0

I am designing a rest API, to get a resource based on some parameters but in some cases these parameters are between 15-20 in number.

I am thinking of using a POST request to get the resource based on these 15 parameters. I know that POST request should not be used in case of getting the resource.

I want to know if there is a better option to handle this then sending POST request?

  • 2
    seems similar to this https://stackoverflow.com/questions/14202257/design-restful-query-api-with-a-long-list-of-query-parameters – Cyril Cherian Mar 20 '19 at 06:51

4 Answers4

1

You can use Get service by using Map. It will accept all param.

/test?A=ABC&B=123

@RequestMapping(value="/test",method = RequestMethod.GET)
public String testUrl(@RequestParam Map<String, String> parameters) 
{   
println(parameters.get("A"));
println(parameters.get("B"));

return parameters.get("A");
}

Out Put Will Be ABC 123

Muhammad Waqas
  • 367
  • 3
  • 13
  • Thanks for the answer, i am also concerned about the url length, it should not exceed the limit. –  Mar 20 '19 at 06:47
  • You can use URL shorter api's for that. And if you don't want to get in that mess you simply use `POST` service. – Muhammad Waqas Mar 20 '19 at 06:51
1

GET doesn't restrict the number of parameters the only restriction is the length of the URL (which contains these parameters) So if you're expecting that the parameters and values would cause a long URL, you can use POST instead

Standard says that URL length should be not more than 2,083 characters even if some browsers/servers allow more, it's better to stick on this value for a wide-range support for all browsers/servers/gateways

hanyahmed
  • 71
  • 2
1

In order to make your @Controller code more concise (e.g. get rid of 15x @RequestParam) you can use @ModelAttribute annotation.

@GetMapping(value="/things")
public List<Thing> findAllThings(@ModelAttribute ThingDTO thing) { 
// logic
}

and your ThingDTO class like that:

public class ThingDTO {
    private String name;
    private ThingType type;
    [...] //getters, setters etc.
}

This is going to map your class attributes to the @RequestParams. The code looks a bit cleaner imho.

When it comes to the URL length you should check the topic here: What is the maximum length of a URL in different browsers? and decide if there's possibility of exceeding the limit.

What should you use? For data retrieval I'd in 99% cases go with GET so if the above is not a blocker for you, go with GET. If there's a chance of exceeding the limit, go with POST.

Pijotrek
  • 2,821
  • 1
  • 18
  • 32
  • I think `@ModelAttribute` should be the first option when dealing with input parameters of any kind. Binding those variables into a POJO helps with validation, readability and maintainability. – noiaverbale Mar 20 '19 at 08:55
0

The parameter length shouldn't be a problem to handle for the server.

You should read about how to design a rest api. I would recommend you to build it like this:

/api/{version}/{entity}/{id}

If you are using Spring Boot this is very simple to build.

Just write a Controller like this

@RestController
@RequestMapping("/api/users")
public class UsersService {
    @Autowired
    UsersRepository userRepo;

    @RequestMapping(value="/find-all", method=RequestMethod.GET)
    public Page<User> getAllUsers(@RequestParam(value="page", defaultValue = "0", required=false)Integer page, 
                                  @RequestParam(value="size", defaultValue= "20", required=false)Integer size){
        ...
    }

    @RequestMapping(value="/find/{id}")
    public ResponseEntity<User> getUserById(@PathVariable(name="id")Long id){
        ...
    }

    @RequestMapping(value="/save", method=RequestMethod.POST)
    public ResponseEntity<User> createUser(@RequestBody User user){
        ...
    }

    @RequestMapping(value="/delete/{id}", method = RequestMethod.GET)
    public ResponseEntity<Void> deleteUser(@PathVariable(name="id")Long id){
        ...
    }

}

Hope this sample code helps you to build your api. Just pass your ID as a PathVariable like shown in deleteUser() or findUser().

If you need more Parameters, you can extend the list or use RequestParam like used in getAllUsers().

The parameters are optional but need a default value.

Gulliva
  • 488
  • 2
  • 10