POST or GET in a search form?

Viewed 15946

I created a Search form to find posts on a MVC site.

Should the form type be POST or GET?

I know that being get is possible to bookmark the search and so on.

Any disadvantage of using GET?

Thank You, Miguel

4 Answers

Even though GET is the more conventional solution for querying data, there are plenty of cases where a GET is too limited to perform a /search.

The essence of the problem, is that a GET has no request body, and for that reason it cannot handle more complex request. In essence a GET can only send data using the URL. A URL can contain path parameters and query parameters, which are just a set of key-value pairs where both key and value are of a string type.

By contrast, a POST can in addition also carry an entire JSON document in its body. By restricting ourselves to a GET, we cannot use any of those JSON features, and as a result we cannot send proper objects or arrays to our back-end.

How valuable are semantics, really ? Should we follow a workaround, which could result in technical debt, just to honor a naming convention?

An example of a problem case

As mentioned above, one of the possible problems, is that it cannot deal with arrays.

For instance, in a webshop, you want users to present with a catalog of products presented in a list. You want to offer your users the ability to select a number of vendors using checkboxes to filter the list. It would result in an array such as selectedVendors = ["vendorA", "vendorB"].

If we want to respect the convention of using a GET, then we have to find an acceptable workaround which allows us to send a list of vendors to the back-end without using a request body.

Workaround 1

With only query parameters at your disposal, it is possible to model it as a bunch of booleans: includeVendorA, includeVendorB, ...

Unfortunately, that's hard to maintain and difficult to document.

Workaround 2

The front-end could actually perform multiple queries. i.e.

  • Get the ones for vendorA first (/search?vendor=VendorA),
  • then the ones for vendorB (/search?vendor=VendorB)
  • then finally merge all results back together to a single list.

First of all, it has a performance penalty, because it needs multiple round-trips. But secondly, it also breaks the ability to support paging.

Workaround 3

Add incremental indexes to your query parameter names. (e.g. /search?vendor1=VendorA&vendor2=VendorB)

Again, hard to document, and not supported by OpenAPI neither.

Finally

If we can just accept that a POST is more suitable for a /search, then we don't need any of those workarounds.

Update 2021

Specifically for sending arrays over GET, there still isn't a standard yet. However, slowly frameworks and languages are shifting towards a de facto standard: /search?vendor[]=VendorA&vendor[]=VendorB.

One more specific shortcoming of the GET, would be the ability to model conditional filters: (e.g. in a ticket system: "give me all tickets which person X created and all tickets which person X closed", or in a webstore: "give me all products that are in discount and all products with free shipping"). They translate to database queries with a mix of AND and OR statements.

Related