13

What is best practice for search in API?

  • GET + query parameters, example: GET /search?q=phone
  • GET + parameters in body, example: GET /search {"query": "phone"}
  • POST + parameters in body, example: POST /search {"query": "phone"}
Romper
  • 2,009
  • 3
  • 24
  • 43

3 Answers3

4

Don't include a body with a GET request. That's against the spec:

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.

There are tradeoffs between the other two options. GET requests are cacheable, safe, and idempotent. They're also limited in size.

POST requests are not reliably cacheable, safe, or idempotent, and have no size limit. There's also more flexibility baked in - you can later create a filter resource on the server side in addition to returning the search result, and later searches can use that filter, possibly with a GET, although be careful if you allow caching and changes to the filter definition after it's created.

Looking at your specific example, supporting a single "search" endpoint can get messy pretty fast. If you haven't already, I would encourage you to consider other options.

Community
  • 1
  • 1
Eric Stein
  • 13,209
  • 3
  • 37
  • 52
  • 3
    Elasticsearch uses GET with body for search requests. – Romper May 11 '17 at 14:26
  • 1
    @Romper Sure does. They've throw away idempotence and cacheability because they think that "GET" should mean go get something and "POST" should mean go change something. I disagree with their decision, and they are clearly in violation of the spec as written and as intended. The spec authors made it clear that it was their intent that GET bodies be semantically meaningless. – Eric Stein May 11 '17 at 14:39
  • @Romper With explicit freshness information, yes, the response may be cached. However, some user agents and intermediate servers don't do so, even when allowed by the spec. "Responses to POST requests are only cacheable when they include explicit freshness information (see Section 4.2.1 of [RFC7234]) However, POST caching is not widely implemented." [RFC7231 4.3.3]. So even though you'd like to cache, you're dependent on something from the client up to your service boundary supporting POST caching. – Eric Stein May 11 '17 at 15:14
  • 1
    The spec doesn't say don't use a body in a GET. It's very specifically written to NOT say that. It says, to summarize, "We're not defining a standard for a GET body, and servers don't have to support it, so use with caution." Most major servers (IIS, Apache, etc.) support GET bodies at a protocol level, and leave it up to the code to decide what to do with it if it receives it. There are many GET API implementations out there that don't break idempotency or cacheability even though they use a body. – Thought Feb 07 '23 at 01:54
0

POST requests are considered to change or create data on the server. GET is considered as a "Safe Method" which have no effect on the server database.

Since search requests do normally not change any data you should use a GET request. The limit is at least 2000 symbols (IE) so most of the times you are pretty safe.

Tobias
  • 4,523
  • 2
  • 20
  • 40
  • 1
    As the semantics of a `POST` payload is up to the implementor, `POST` requests are the swiss-army knife of HTTP operations which should be taken if none of the other, more specific operations are suitable. `POST` is not only a create resource operation ... – Roman Vottner May 11 '17 at 13:57
0

Definitely do 1, GET using query parameters. It is much more likely to be cached.

If nothing in the data model changes on the server, your request should be GET. Server ops like logging is OK, but creation of a filter (as another answer suggested), as distinct from a query cache, say, is not.

Nicholas Shanks
  • 10,623
  • 4
  • 56
  • 80