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