Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to design RESTful search/filtering? [closed]

Tags:

rest

search

I'm currently designing and implementing a RESTful API in PHP. However, I have been unsuccessful implementing my initial design.

GET /users # list of users GET /user/1 # get user with id 1 POST /user # create new user PUT /user/1 # modify user with id 1 DELETE /user/1 # delete user with id 1 

So far pretty standard, right?

My problem is with the first one GET /users. I was considering sending parameters in the request body to filter the list. This is because I want to be able to specify complex filters without getting a super long url, like:

GET /users?parameter1=value1&parameter2=value2&parameter3=value3&parameter4=value4 

Instead I wanted to have something like:

GET /users # Request body: {     "parameter1": "value1",     "parameter2": "value2",     "parameter3": "value3",     "parameter4": "value4" } 

which is much more readable and gives you great possibilities to set complex filters.

Anyway, file_get_contents('php://input') didn't return the request body for GET requests. I also tried http_get_request_body(), but the shared hosting that I'm using doesn't have pecl_http. Not sure it would have helped anyway.

I found this question and realized that GET probably isn't supposed to have a request body. It was a bit inconclusive, but they advised against it.

So now I'm not sure what to do. How do you design a RESTful search/filtering function?

I suppose I could use POST, but that doesn't seem very RESTful.

like image 763
Erik B Avatar asked Feb 16 '11 18:02

Erik B


People also ask

Should a search API be get or post?

GET requests should be used to retrieve data when designing REST APIs; POST requests should be used to create data when designing REST APIs. Creating something is a side effect — if not the point. The HTTP GET method isn't supposed to have side effects. It's considered read-only for retrieving data.


2 Answers

The best way to implement a RESTful search is to consider the search itself to be a resource. Then you can use the POST verb because you are creating a search. You do not have to literally create something in a database in order to use a POST.

For example:

Accept: application/json Content-Type: application/json POST http://example.com/people/searches {   "terms": {     "ssn": "123456789"   },   "order": { ... },   ... } 

You are creating a search from the user's standpoint. The implementation details of this are irrelevant. Some RESTful APIs may not even need persistence. That is an implementation detail.

like image 154
Jason Harrelson Avatar answered Dec 02 '22 05:12

Jason Harrelson


If you use the request body in a GET request, you're breaking the REST principle, because your GET request won't be able to be cached, because cache system uses only the URL.

What's worse, your URL can't be bookmarked, because the URL doesn't contain all the information needed to redirect the user to this page.

Use URL or Query parameters instead of request body parameters, e.g.:

/myapp?var1=xxxx&var2=xxxx /myapp;var1=xxxx/resource;var2=xxxx  

In fact, the HTTP RFC 7231 says that:

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.

For more information take a look here.

like image 45
jfcorugedo Avatar answered Dec 02 '22 05:12

jfcorugedo