Estoy buscando una forma razonable de representar las búsquedas como URL RESTful.
La configuración: Tengo dos modelos, Coches y Garajes, donde Coches puede estar en Garajes. Así que mis urls parecen:
/car/xxxx
xxx == car id
returns car with given id
/garage/yyy
yyy = garage id
returns garage with given id
Un coche puede existir por sí mismo (de ahí el /car), o puede existir en un garaje. ¿Cuál es la forma correcta de representar, digamos, todos los coches en un garaje determinado? Algo así como
/garage/yyy/cars ?
¿Qué tal la unión de los coches del garaje yyy y zzz?
¿Cuál es la forma correcta de representar una búsqueda de coches con determinados atributos? Digamos: muéstrame todos los sedanes azules de 4 puertas:
/car/search?color=blue&type=sedan&doors=4
¿o debería ser /coches en su lugar?
El uso de "search" parece inapropiado allí - ¿cuál es una mejor manera / término? ¿Debería ser simplemente:
/cars/?color=blue&type=sedan&doors=4
¿Deberían los parámetros de búsqueda formar parte del PATHINFO o del QUERYSTRING?
En resumen, estoy buscando orientación para el diseño de url REST entre modelos, y para la búsqueda.
[Actualización] Me gusta la respuesta de Justin, pero no cubre el caso de búsqueda multi-campo:
/cars/color:blue/type:sedan/doors:4
o algo así. ¿Cómo pasamos de
/cars/color/blue
al caso de campos múltiples?
Justin's respuesta es probablemente el camino a seguir, aunque en algunas aplicaciones puede tener sentido considerar una búsqueda en particular como un recurso en su propio derecho, como si desea apoyar búsquedas guardadas con nombre:
/search/{searchQuery}
o
/search/{savedSearchName}
Aunque me gusta la respuesta de Justin, creo que representa mejor un filtro que una búsqueda. ¿Qué pasa si quiero saber sobre coches cuyos nombres empiezan por cam?
Tal y como yo lo veo, podrías incorporarlo a la forma de gestionar recursos específicos:
/coches/cam
O, simplemente podrías añadirlo en el filtro:
/coches/puertas/4/nombre/cam/colores/rojo,azul,verde
Personalmente, prefiero esta última opción, aunque no soy en absoluto un experto en REST (oí hablar de él por primera vez hace sólo 2 semanas o así...)
Mi consejo sería el siguiente:
/garages
Returns list of garages (think JSON array here)
/garages/yyy
Returns specific garage
/garage/yyy/cars
Returns list of cars in garage
/garages/cars
Returns list of all cars in all garages (may not be practical of course)
/cars
Returns list of all cars
/cars/xxx
Returns specific car
/cars/colors
Returns lists of all posible colors for cars
/cars/colors/red,blue,green
Returns list of cars of the specific colors (yes commas are allowed :) )
Editar:
/cars/colors/red,blue,green/doors/2
Returns list of all red,blue, and green cars with 2 doors.
/cars/type/hatchback,coupe/colors/red,blue,green/
Same idea as the above but a lil more intuitive.
/cars/colors/red,blue,green/doors/two-door,four-door
All cars that are red, blue, green and have either two or four doors.
Espero que esto te dé una idea. Esencialmente, su API Rest debe ser fácilmente detectable y debe permitirle navegar a través de sus datos. Otra ventaja de usar URLs y no cadenas de consulta es que puedes aprovechar los mecanismos nativos de caché que existen en el servidor web para el tráfico HTTP.
Aquí'hay un enlace a una página que describe los males de las cadenas de consulta en REST: http://web.archive.org/web/20070815111413/http://rest.blueoxen.net/cgi-bin/wiki.pl?QueryStringsConsideredHarmful
He utilizado la caché de Google porque la página normal no me funcionaba: http://rest.blueoxen.net/cgi-bin/wiki.pl?QueryStringsConsideredHarmful