RESTful URL design for search
Solution 1:
For the searching, use querystrings. This is perfectly RESTful:
/cars?color=blue&type=sedan&doors=4
An advantage to regular querystrings is that they are standard and widely understood and that they can be generated from form-get.
Solution 2:
The RESTful pretty URL design is about displaying a resource based on a structure (directory-like structure, date: articles/2005/5/13, object and it's attributes,..), the slash /
indicates hierarchical structure, use the -id
instead.
#Hierarchical structure# I would personaly prefer:
/garage-id/cars/car-id
/cars/car-id #for cars not in garages
If a user removes the /car-id
part, it brings the cars
preview - intuitive. User exactly knows where in the tree he is, what is he looking at. He knows from the first look, that garages and cars are in relation. /car-id
also denotes that it belongs together unlike /car/id
.
#Searching# The searchquery is OK as it is, there is only your preference, what should be taken into account. The funny part comes when joining searches (see below).
/cars?color=blue;type=sedan #most prefered by me
/cars;color-blue+doors-4+type-sedan #looks good when using car-id
/cars?color=blue&doors=4&type=sedan #I don't recommend using &*
Or basically anything what isn't a slash as explained above.
The formula: /cars[?;]color[=-:]blue[,;+&]
, * though I wouldn't use the &
sign as it is unrecognizable from the text at first glance.
** Did you know that passing JSON object in URI is RESTful? **
Lists of options
/cars?color=black,blue,red;doors=3,5;type=sedan #most prefered by me
/cars?color:black:blue:red;doors:3:5;type:sedan
/cars?color(black,blue,red);doors(3,5);type(sedan) #does not look bad at all
/cars?color:(black,blue,red);doors:(3,5);type:sedan #little difference
##possible features?##
Negate search strings (!)
To search any cars, but not black and red:?color=!black,!red
color:(!black,!red)
Joined searches
Search red or blue or black cars with 3 doors in garages id 1..20 or 101..103 or 999 but not 5
/garage[id=1-20,101-103,999,!5]/cars[color=red,blue,black;doors=3]
You can then construct more complex search queries. (Look at CSS3 attribute matching for the idea of matching substrings. E.g. searching users containing "bar" user*=bar
.)
#Conclusion#
Anyway, this might be the most important part for you, because you can do it however you like after all, just keep in mind that RESTful URI represents a structure which is easily understood e.g. directory-like /directory/file
, /collection/node/item
, dates /articles/{year}/{month}/{day}
.. And when you omit any of last segments, you immediately know what you get.
So.., all these characters are allowed unencoded:
- unreserved:
a-zA-Z0-9_.-~
Typically allowed both encoded and not, both uses are then equivalent. - special characters:
$-_.+!*'(),
- reserved:
;/?:@=&
May be used unencoded for the purpose they represent, otherwise they must be encoded. - unsafe:
<>"#%{}|^~[]`
Why unsafe and why should rather be encoded: RFC 1738 see 2.2
Also see RFC 1738#page-20 for more character classes.
RFC 3986 see 2.2
Despite of what I previously said, here is a common distinction of delimeters, meaning that some "are" more important than others.
- generic delimeters:
:/?#[]@
- sub-delimeters:
!$&'()*+,;=
More reading:
Hierarchy: see 2.3, see 1.2.3
url path parameter syntax
CSS3 attribute matching
IBM: RESTful Web services - The basics
Note: RFC 1738 was updated by RFC 3986