Don't use GET for APIs
I have an Web API developed using the http methods as they were intended[0] by the authors. Now I need to enhance the GET based API calls with support for batch requests. It turns out that there is no standard method to encode more than name -> value pairs in the query string. Everything is framework, language specific. So if you need more(e.g. an array or a nested data structure) than name value pairs you better avoid GET. I hope this helps anyone who starts a new Web API project.
[0] https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
12 comments
[ 3.0 ms ] story [ 30.3 ms ] threadNamely, if this were an Ask HN, I'd tell you to use the new HTTP RFCs [1] instead of the old ones.
I'm assuming that 'batch requests' means that your HTTP API is a thin proxy that surfaces data from some underlying database, and you want to enhance to be able to operate on more than one underlying resource. In the case of GET, you're retrieving data, so I'm guessing you want to surface more than one resource. I would call that a 'search', while modifying more than one resource with the same request I'd call a 'batch'; please correct me if you feel I'm wrong.
With that in mind, I suggest two approaches to have 'search requests':
[A.] try to express your search filters with key-value pairs, as fundamentally that's what should be going on behind the scenes.
[B.] design a 'Search Manager' endpoint where you can POST a search-request in a complex datatype of your design. This endpoint returns a 201 Created with a Location URI that allows you to retrieve the results.
The suggestion in this programmers exchange post is essentially the same, stated slightly differently [2].
[1] https://tools.ietf.org/html/rfc7231#section-4.1
[2] http://programmers.stackexchange.com/questions/233164/how-do...
- OR -
You can design a structured format that communicates the information you want. For example, a format based on JSON with an array of objects, or a format based on JSON with an key-value map of objects (ie. object of objects).
There are others. This blog post [2] from 2014 lists some from a hypermedia perspective, although you may find some of these formats excessive for what you're trying to accomplish.
Before JSON became a favorite for HTTP APIs, there used to be XML-based ones as well. AtomPub is a very good protocol, which defines an 'application/atomcoll+xml' mediatype for collections [3]
[1] http://amundsen.com/media-types/collection/
[2] http://sookocheff.com/post/api/on-choosing-a-hypermedia-form...
[3] http://bitworking.org/projects/atom/draft-ietf-atompub-proto...
Why can't use just encode a complex type and parse it at the receiving end? The url may look like garbage, but you could theoretically pass anything you want (within length bounds) as a parameter.
[0] https://developer.paypal.com/docs/classic/api/NVPAPIOverview...
Even without that, passing a parameter as url-encoded json isn't that awful.
They have, back in the "XML is the king of data formats, and WebDAV is the way to build web applications" days. (It sounds something like either the SEARCH or REPORT HTTP method defined for WebDAV.)
Someone proposed a generified version of SEARCH but it didn't go anywhere, that and a few other bits of WebDAV really could use being detached and made useful separately for generic web content.
Even ElasticSearch acknowledges this and allows you to POST the body instead. That's not very 'RESTful' either, but at least it's to spec. But since you haven't mentioned REST at all, POSTing to a controller resource to perform what would amount to be a retrieval is certainly a common practice in other HTTP APIs.
[1] https://www.elastic.co/guide/en/elasticsearch/reference/curr...
[2] http://stackoverflow.com/questions/978061/http-get-with-requ...