11

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

Felipe Oriani
  • 37,948
  • 19
  • 131
  • 194
Miguel Moura
  • 36,732
  • 85
  • 259
  • 481
  • 2
    http://stackoverflow.com/questions/195212/what-are-the-advantages-of-using-a-get-request-over-a-post-request – Kamlesh Dec 12 '13 at 17:47

4 Answers4

19

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.

bvdb
  • 22,839
  • 10
  • 110
  • 123
  • There are problems with using POST as a catch-all solution for searches, such as needing to maintain models and being unable to bookmark search urls. Imo it is better to use query string with GET for simple searches and refactor into a POST only when you actually need to. – Peter David Carter Jul 15 '22 at 05:46
  • Another workaround, similar to your 2021 update, is simply adding each vendor to the URL as a vendor= name/value pair. Many web frameworks will turn repeated URL parameters into a list, making parsing such values trivial. – Tom Lint Aug 23 '22 at 13:31
  • Another issue with get is you have to encode and possibly escape the values so it creates a valid URL, especially for user-generated parameters. I had to change a GET method to POST after we discovered user search terms could contain ampersand which caused the URL to think it was a separate parameters in the query string and the backend controller didn't match the call with extra parameters. – SleekPanther Jun 06 '23 at 17:27
10

With GET verb, the arguments will be on the URL, there is not http request body for GET. Using POST may not be the appropriated solution for this, which in case we also have the arguments on the URL but we can send more data into the request body in a specific format (json, xml, text, etc). Using GET as the verb name said, is the best solution for it and you also get the benefit of copy/paste this url and share anywhere. There is no limit for arguments on the URL of http.

The HTTP protocol does not place any a priori limit on the length of a URI. Servers MUST be able to handle the URI of any resource they serve, and SHOULD be able to handle URIs of unbounded length if they provide GET-based forms that could generate such URIs. A server SHOULD return 414 (Request-URI Too Long) status if a URI is longer than the server can handle (see section 10.4.15).

but as the Jasen comment, browsers can have limit.

Anyway, remember to use method do avoid sql injection. If you are going with ado.net, use Parameters. If you are using and ORM it will care for you.

Community
  • 1
  • 1
Felipe Oriani
  • 37,948
  • 19
  • 131
  • 194
  • I am not modifying any data so that is why I thought to use GET. And do I need any protection against what is inserted on the input? Basically I am parsing the string by getting a max of 4 distinct words with length higher then 4 characters. Then I search a database for posts that contains that words in the title. – Miguel Moura Dec 12 '13 at 17:50
  • I am using Entity Framework for it ... And before that I split all the words and get a few that satisfies my criteria so even if there was some kind of script it will be destroyed on that phase ... I think – Miguel Moura Dec 12 '13 at 17:55
  • Browsers have a query string limit. http://stackoverflow.com/questions/812925/what-is-the-maximum-possible-length-of-a-query-string – Jasen Dec 12 '13 at 17:59
  • Thank you for tip Jasen, I added on my anwser. – Felipe Oriani Dec 12 '13 at 18:04
  • Huge middle finger to anyone implementing search results with POST. Going back to search results is a thing and POST breaks the smooth back behavior. I see absolutely no reason to use POST for search results. – Robo Robok Jul 27 '21 at 10:03
1

Unless you are modifying data, I would go with a GET. I see no drawbacks if you are always getting data and not manipulating data.

Maess
  • 4,118
  • 20
  • 29
1

Search is not necessarily a Post, you're trying to get some data, not modify or insert.

AD.Net
  • 13,352
  • 2
  • 28
  • 47
  • I am not modifying any data so that is why I thought to use GET. And do I need any protection against what is inserted on the input? Basically I am parsing the string by getting a max of 4 distinct words with length higher then 4 characters. Then I search a database for posts that contains that words in the title. – Miguel Moura Dec 12 '13 at 17:50
  • You can use other techniques to handle that, like using parameters in sql or stored proc, using something like linq, etc. – AD.Net Dec 12 '13 at 17:56