0

I have the GET method in my Spring REST controller. This method returns the list of users by the filter. I have a few ways to implement it:

  1. Add @PathVariable like - /users/{type}/{age}/{name}/...(bad approach in this case)
  2. Add @RequestParam like - /users?type=type,age=age,name=name...(usual approach in this case)
  3. Use RequestDto (the best approach) like
     public class UsersRequestDto {
        private String type;
        private int age;
        private String name;
        ...
        }

But I can not use GET method for this. I must use POST method with @RequestBody

And it breaks the rules. My method doesn't change state and doesn't create any entities. It workes as the GET method but in reality, it is POST.

And I have 2 ways:

  1. Use the GET method with many parameters
  2. Use the POST method with DTO which works as the GET method and confuses users.

Which way is better?

Pavel Petrashov
  • 495
  • 1
  • 2
  • 11

3 Answers3

0

How many different parameters are you including in your query?

Personally, I prefer the option of a GET method with many different parameters. It has other benefits such as being cacheable as well. Also, compare it to something like a the URL that a Google search generates - lots of query string parameters.

The POST option feels dirty - it's a violation of what a POST should actually do (creating or updating a resource).

See these discussions: https://softwareengineering.stackexchange.com/questions/233164/how-do-searches-fit-into-a-restful-interface and REST API Best practices: Where to put parameters?

Riaan Nel
  • 2,099
  • 7
  • 15
  • Yes, I understand that `The POST option feels dirty - it's a violation of what a POST should actually do (creating or updating a resource).` It motivated me to create this question. But using DTO looks grate- you can change DTO and don't change the API method signature – Pavel Petrashov Nov 24 '20 at 09:50
  • I remembered one more option - in the POSTrequest you can hide parameters and don'ts show it in the search bar (internal ids, some details) – Pavel Petrashov Nov 24 '20 at 10:06
0

1st of all when you are using RequestParam then key will be added with & symbol not with comma(,) .

when you want to filter ( as you have mentioned) something then best approach would be to use RequestParam.

To minimize the code you can opt to "MultiValueMap" or "HttpservletRequest" .

1)HttpServletRequest

@GetMapping("/user")
    public List<User> getFilteredUser(HttpServletRequest httpservlet)
    httpservlet.getQuesryString()   //will return all request param.

2)MultiValueMap

@RequestParam MultiValueMap<String,String> params

NOTE:- Generally POST is for create/update record.

priyranjan
  • 552
  • 3
  • 14
0

Short version: you might be looking for How to bind @RequestParam to object in Spring. (See also: https://stackoverflow.com/a/16942352/54734 )

On the web, we would have an html form with a GET action. When the form is submitted, the browser would process the input controls and create the application/x-www-form-urlencoded representation of the form data. For a GET action, that representation is used as the query string.

Using GET, and encoding all of the information into the query string, allows us to take advantage of general purpose caching of the results.

But the query parameters aren't accessible by themselves - they are actually embedded within the larger context of the HTTP request. We don't usually see that because, once again, general purpose components can do a lot of the heavy lifting.

So we don't see the parser that extracts the target-uri from the request, or the parser that splits the target URI into its separate components, or the parser that splits the query part into a sequence of key value pairs....

In general, what we do is ride the "general purpose" implementation as far as we can, then get off and do the rest of the work ourselves. If the framework offered no better support for object mapping, that could mean implementing that mapping ourselves.

So if our framework lacked the capability to map the query string directly to an object representation, we would hand roll that part of the implementation ourselves (either by copying each parameter "by hand", or writing our own reflection code to do the mapping automagically).

But it seems that Spring has that capability already built into it; and that it is the default option (no annotation required); you just have to be sure that the object implementation provides the interface that Spring needs to execute the mapping.

VoiceOfUnreason
  • 40,245
  • 4
  • 34
  • 73