3

I've set up an API in Spring where the client can specify the ids of the objects they want to receive. It returns a JSON list (using the @ResponseBody annotation) of the objects.

But, since the request can be a long list, I've set it up as a POST, where it's received as an object named ProductRequest (using the @RequestBody annotation). This seemingly isn't conformant to the official REST API standard, since posts are official to create new objects, but it seems better to implement it this way since you're not cluttering up the URL with a bunch of ids. Also, I can specify additional parameters customizing the output.

So my question is, can this be considered a valid RESTful design? Post isn't being used to create an object, so it's not strictly conformant to restful. Thoughts?

Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
Jack BeNimble
  • 35,733
  • 41
  • 130
  • 213
  • What 'official REST API standard' do you mean? – jschnasse Nov 21 '17 at 13:17
  • If possible, you could specify your own HTTP Verb, e.g. LIST. But this is not always the best choice. Found a short discussion [here](https://www.safaribooksonline.com/library/view/restful-web-services/9780596809140/ch01s12.html) – jschnasse Nov 21 '17 at 13:24

3 Answers3

1

It is a simple GET request.

@GetMapping(path = "/your-url")
public List<Object> method(@RequestParam(name="ids") List<Long> objectIds) {
}

You can receive your list just as a simple java list.

/api?ids=1,2,3

Bogdan Oros
  • 1,249
  • 9
  • 13
  • Question: What if your list of ids consists of hundreds or thousands of 12-digit identifiers? Couldn't that overflow the max allowable for the URL string? I have run into this before. Also, why is it a bad thing to make it a post? Ultimately, that's just how the API works in this case. – Jack BeNimble Nov 20 '17 at 20:11
  • 1
    I think such kind of requests need to be paginated also on client side and do not request more than a "fixed" amount of objects in one request. But if it is not possible, you can't use HTTP method GET I think. – Bogdan Oros Nov 20 '17 at 21:01
1

You can very well do an http POST to "get" the resource(s). There are some very valid examples of doing so,

  1. GraphQL -- All we are doing is sending (POSTing) some Queries in requestbody to "GET" some data in the format that we prefer

  2. Assume that you have to authenticate with a username and password to get a specific data, you will either send it in Header in GET request or you will do a POST to 'GET' a data.

so-random-dude
  • 15,277
  • 10
  • 68
  • 113
  • as I know, we should use the `GET` method to get data in the format we prefer by specifying the `query` parameter. POST is preferable if we need to set an operation that will be performed over resources – Andrew Tobilko Nov 21 '17 at 14:01
  • @AndrewTobilko Thanks for the comment... when multiple resources involved, it is still "GET" operation, there is no "side-effects", even though the http method is a POST – so-random-dude Nov 21 '17 at 15:27
1

Couldn't that overflow the max allowable for the URL string?

Actually, there is no limitation on the length of a URI. However, practically, you can encounter some.

According to RFC7230 (emphasis mine),

HTTP does not place a predefined limit on the length of a request-line, as described in Section 2.5. A server that receives a method longer than any that it implements SHOULD respond with a 501 (Not Implemented) status code. A server that receives a request-target longer than any URI it wishes to parse MUST respond with a 414 (URI Too Long) status code.

Various ad-hoc limitations on request-line length are found in practice. It is RECOMMENDED that all HTTP senders and recipients support, at a minimum, request-line lengths of 8000 octets.

It clearly suggests that we can't rely on a request-line while we are dealing with your issue.

Can this be considered a valid RESTful design?

Due to the limitation mentioned above, using POST is a valid workaround.

As stated by this Wikipedia article,

The common workaround for these problems is to use POST instead of GET and store the parameters in the request body. The length limits on request bodies are typically much higher than those on URL length.

To completely free you from hesitation, there is a common non-standard header X-Http-Method-Override. It requests a web application to override the method specified in the request with the method given in the header:

X-Http-Method-Override: GET

I am not sure whether Spring handles the header. Though, it has the HiddenHttpMethodFilter filter which seems to do similar work.

Community
  • 1
  • 1
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142