Reputation: 29046
I'm looking for a good way to form a URI for a resource that filters on a collection of values contained within records. For example, say you have a recipe database and you want to search for recipes that contain "cherry" (obviously most recipes would contain multiple ingredients).
If I just want to filter on single values, I could do something similar to the following:
/recipe/search/?name=Spaghetti
But what about filtering on multiple values? I was considering something like the following:
/recipe/search/?ingredients=contains=cherry
Any thoughts on this? Is there a "standard" for a filter of this kind?
Update: One problem I have with my idea is the way it gets handled on the backend (in my case Rails). When querying the server with this particular format, Rails generates a Ruby hash that could get ugly like the following:
{"ingredients"=>"contains=cherry",
"action"=>"search",
"controller"=>"recipe"}
Upvotes: 3
Views: 5148
Reputation: 3611
First of all, in contrast to other answers I'll start from a REST
perspective and then find appropriate additions to it. I am not strong in Ruby so bear with no-code on the backend.
/recipies
/recipies/?sortby=date&sort=asc
/recipies/?ingredients=cherry
So that's the REST way of structuring your basic URL.
For multiple matches there is no official way to do it, but i'd follow user1758003. This is an intuitive construction of the url and easily to parse on the backend, so we have /recipies/?ingredients=cherry,chocolate
Don't forget /recipies/search
is not restful because it mirrors recipies
and does not represent an independent entity. However it is a great place to host a searchform for visitors to your site.
Now there are some additional questions packed into the first, let me address them one by one:
Give your visitors a /recipie/search
page or a quick filtering possibility on /recipies
.
Just set the <form action="/recipies" type="GET">
. The browser will add all parameters as an Query string after /recipies
.
A request to /recipies
should list all. If you add a query every parameter of the query must be respected. so /recipies/?ingredients=cheese
MUST only return cheesy recipies.
For multiply query parameter values there is no fixed standard but I'd like a service to be intuitive.
I read GET /recipies/?ingredients=cherry,chocolate
as Get me the recipies which have ingredients of cherry and chocolate
. To get a list of recipies containing either cherry or chocolate I'd want to write the URI like /recipies/?ingredients=cherry|chocolate
which makes it visually very different from a comma and has a predefined meaning (OR) in programming contexts.
Upvotes: 3
Reputation: 162
I'm not familiar with the specifics of ruby hashes but I'm guessing the hash is created to uniquely identified the query both at the http and data access levels?
Regardless, you want to be careful about URL encoding if you wish to use json in a query parameter. Another thing to keep in mind is the term "search" could be considered repetitive. If your server is being accessed using a GET method and you have criteria then hopefully you're not modifying any state in the back end. Not your question but just thought I'd mention it.
So...
https://yourserver.com/approot/recipe/search?ingredients=cherry,cheese&type=cake
HTTP doesn't define commas as a query string separator so your framework should be able to parse 2 query string parameters:
ingredients: "cherry,cheese"
which you should be able to easily covert to an an array using split or whichever equivalent function ruby provides.
and
type: "cake" (extra query term added to illustrate a point and because cherry cheese cake is awesome and cake is not an ingredient)
If I understand your example correctly you would end up with:
{
"ingredients"=>"cherry,cheese",
"type"=>"cake",
"action"=>"search",
"controller"=>"recipe"
}
Is this what you where looking for?
Upvotes: 2
Reputation: 913
Most of the REST webservice using JSON data only.So use JSON format which will return single string value only. From this JSON format you can send the array value also.
For array value means you to convert that array into the JSON format like this
from php:
$ingredients = array('contains'=>array('fruits'=>'cherry,apple','vitamins'=>'a,d,e,k'));
$ingredients_json = json_encode($ingredients);
echo $ingredients_json;
it will return json format like this:
{"contains":{"fruits":"cherry,apple","vitamins":"a,d,e,k"}}
and you can use this JSON string in the url
/recipe/search/?ingredients={"contains":{"fruits":"cherry,apple","vitamins":"a,d,e,k"}}
in the server side we have the option to decode this JSON format value to the array.
{"ingredients"=>"{\"contains\":{\"fruits\":\"cherry,apple\",\"vitamins\":\"a,d,e,k\"}}",
"action"=>"search",
"controller"=>"recipe"}
Upvotes: 1