-1

I have a complicated schema that requires complicated API calls. For many resource retrievals, the user would want to specify several parameters to filter the results. Including all of these parameters in the URI seems like it would be messy and difficult for front-end developers to craft, so I’ve opted to put the parameters into the request body as JSON. Unfortunately, this doesn’t seem to sit well with the web back-end I’m using (Django-Rest Framework). Is this RESTful, or am I making a mistake?

As a follow-up question, if I should put the parameters in the URI, how would I represent complex pieces of data, like lists of strings, and the relationships between pieces of data?

JGut
  • 522
  • 3
  • 12
  • 3
    Possible duplicate of [HTTP GET with request body](https://stackoverflow.com/questions/978061/http-get-with-request-body) – hoefling Sep 29 '18 at 09:36

2 Answers2

1

Is this RESTful, or am I making a mistake?

It sounds to me as though you are making a mistake. The authority in this case is RFC 7231

A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.

My interpretation is this: caching is an important part of the web; for caching to work as people would expect it requires compliant caches to be able to manage that message body as part of the key.

An HTTP method that may serve your needs better is SEARCH.

The SEARCH method plays the role of transport mechanism for the query and the result set. It does not define the semantics of the query. The type of the query defines the semantics.

SEARCH is a safe method; it does not have any significance other than executing a query and returning a query result.

If that doesn't fit your needs, you could look through the HTTP method registry to see if one of the other standards fits your use case.

how would I represent complex pieces of data, like lists of strings, and the relationships between pieces of data?

The real answer is "any way you want" -- the origin server has control of its URI space, and any information encoded into it is done so at the server's convenience for its own use.

You could, for instance, consider using one of the Base64 encodings defined in RFC 4648

Community
  • 1
  • 1
VoiceOfUnreason
  • 40,245
  • 4
  • 34
  • 73
  • Only the `SEARCH` method is not exactly part of RESTful, which is limited to `GET`, `POST`, `PUT`, `PATCH`, `DELETE`. Now I personally think that using WebDAV and whatever other commands you want to support is just fine as long as you properly document them (which can be very difficult because the HTTP protocol is a really massive number of quirky rules!) – Alexis Wilke Jan 07 '19 at 01:37
0

From what I read about RESTful, you can only use GET, POST, PUT, PATCH, and DELETE.

The GET and DELETE are not expected to include a body. As @VoiceOfUnreason mentioned, this is mainly because caches can have difficulties handling a body along a GET. That being said, if your results are never cached, it should not be a concern at all. (i.e. return Cache: no-cache and other similar HTTP header from your server.)

There is no real convention on the Query String and supporting lists or JSON and such. If you want to keep a GET, you could use an encoded JSON string, though. There is no problem with that, except the length of the URL.

http://www.example.com/?query=<encoded-json>

(encoded just means that you have to properly escape URI special characters, what the JavaScript encodeURICompent() function does.)

The length of the URL should be kept under 1Kb to be 100% safe. You can do some research on it, I think that the browser with the most stringent limit is around 2k.

If you want to use a bigger query, then you should revert your queries to using a POST and not a GET. Then the buffer is normal in that situation and the reply is not expected to be cached.


Real World Use (but Not An Excuse)

If you look into Elasticsearch, you will see that all their queries accept a JSON. You can send a DSL query using a GET or a POST. Either one accept a JSON in their body.

They offer the POST because most browsers will not accept to attach a body to a GET method. So GET queries would not work at all from a browser.


Example of Arrays in Query Strings

There has been various libraries, and at least PHP, that added support for arrays in parameters. In most cases this is done by supporting the array syntax in the parameter name. For example:

path/?var[1]=123&var[2]=456&var[3]=789

In this case, those languages will convert the value in an array. $_GET['var'][1] would then return 123.

This is not a convention, just an extension of that specific environment.

Alexis Wilke
  • 15,168
  • 8
  • 60
  • 116