1

Consider a use case where I have a URL like

/api/v1?credentials="test"&age=20&gender=male

Now how can I have 2 different type of cases

USE CASE-1

How can I accept the above query parameters in the form a class from swagger, I know we can define this in swagger as different individual parameters something like this

     parameters:
        - in: query
          name: credentials
          schema:
            type: string
        - in: query
          name: age
          schema:
            type: integer
        - in: query
          name: gender
          schema:
            type: string

but with this swagger creates a rest method with string or integer parameters, and having so many multiple parameters might not be a good idea so what I strongly expect is that it creates a class something like shown below, and my rest methods are generated with this class object. And how can I leverage this class into my controller layer?

class Query{
  String name;
  Integer age;
  String gender;
}

USE CASE-2

Is there some way I can accept all these query params into the form of a hashMap or multiValueMap I know there is another integer in the above url query params, but for now, lets consider I will accept all these params into the form of a string and will later typecast them as per my requirement.

NOTE - that I don't want the same name parameter with multiple values, I am expecting all the query parameters with or without the same names to be mapped into one string-to-string key-value pair. So let's say when I had to access them I will directly use something like map.get("age")

Vaibhav Jain
  • 61
  • 1
  • 6
  • For use case -1 Is there even someway I can create a custom class myself and in my controller layer I leverage it to be accepted as a query parameter? Basic aim is to convert all these params into one model – Vaibhav Jain Nov 05 '22 at 15:19

1 Answers1

1

To have these parameters as query parameters is just fine according to REST. Your controller method to handle the request will be good accepting 3 values as int or Strings. For logging in, a better choice would be to use POST method, depending on what you wish to achieve.

From your example, you really should check state-of-the-art authentication. You could consider JWT, it can wrap all these values securely and is actually designed for doing this. After you log-in a user with credentials, the JWT will be created and can then be used by the client for succeeding interactions as long as it is valid.

Edit:

The Swagger notation also supports a deepObject notation as suggested in https://swagger.io/docs/specification/describing-parameters/, which indeed is not exactly what you are looking for. Still, it would allow to send query accordingly: /api/v1?query[credentials]="test"&query[age]=20&query[gender]=male

In Swagger codegen, you could still consider your own code-generator that extends the basic capabilities.

MJG
  • 355
  • 1
  • 9
  • Thanks for the reply @MJG, I also agree POST can be a better solution here or passing them in the body can be a good solution. But just from an implementation point of view I only want to understand how can we implement those mentioned above, and also I have a strong use case where I want to implement them as mentioned in Usecase-1 and Usecase-2, so please if you are aware of how can we implement above model that will be very helpful. I am in a very tightly coupled architecture where implementing a new type of request will not be very helpful for me – Vaibhav Jain Nov 05 '22 at 16:35
  • In query, no complex object can be used. Your endpoint is the only responsible to create the Query object itself from the simple parameters. By the way, to send 'sensitive' information like credentials in query just a no-go, not sure if you intend to. – MJG Nov 05 '22 at 16:47
  • 1
    Yes @MJG, the credentials was just a dummy name I used to explain my problem, but I am still not very sure because in my org internally I have seen a sample implementation where they probably are doing the same thing(wrapping up multiple query params into one class object) but I am not exactly able to adapt into my workflow and neither able to understand how they have implemented but if I have to gist of it what they are doing in their controller layer is that they have a method like below – Vaibhav Jain Nov 05 '22 at 16:58
  • 1
    `public ResponseEntity getTask(@Parameter(hidden = true) Query query)` but one tricky part is they have created a custom annotation like `@ParameterForSelfTasks implemented like @Parameter(in = ParameterIn.QUERY, name = "credential", content = @Content(schema = @Schema(type = "string"))) ` – Vaibhav Jain Nov 05 '22 at 17:01
  • Like it is explained here? https://stackoverflow.com/questions/16942193/spring-mvc-complex-object-as-get-requestparam – MJG Nov 05 '22 at 17:13
  • 1
    Oh ok thanks a lot @MJG I was kinda stuck finding something like But I am still unclear on the following things < 1. If I have to specify these class objects as a header or query param specifically then how can I do it because I am not specifying anything just directly passing it to my controller method and it is accepting input as a query params 2. If I have a param like `createdAt` and I expect the user to pass it as `created_at` then how can I achieve that? I have tried using `@JsonProperty(created_at)` but that is not helping out atleast – Vaibhav Jain Nov 06 '22 at 08:00
  • @VaibhavJain Well that seems to be a different question to me. But this also depends a lot on the technology of the framework that is used to implement the backend. But usually try to annotate the Query object and read the documentation of your framework if it #. supports that use-case #. how that can be done. – MJG Nov 06 '22 at 11:29