significado siglas restful protocol entre ejemplo diferencia cliente rest

siglas - Diseño de URL RESTful para búsqueda



rest vs soap (12)

Además también sugeriría:

/cars/search/all{?color,model,year} /cars/search/by-parameters{?color,model,year} /cars/search/by-vendor{?vendor}

Aquí, la Search se considera como un recurso secundario del recurso Cars .

Estoy buscando una forma razonable de representar las búsquedas como una URL RESTful.

La configuración: Tengo dos modelos, Cars y Garages, donde los Cars pueden estar en Garages. Así que mis urls se parecen a

/car/xxxx xxx == car id returns car with given id /garage/yyy yyy = garage id returns garage with given id

Un automóvil puede existir por sí solo (de ahí el / automóvil), o puede existir en un garaje. ¿Cuál es la forma correcta de representar, digamos, todos los autos en un garaje determinado? Algo como:

/garage/yyy/cars ?

¿Qué hay de la unión de los coches en el garaje yyy y zzz?

¿Cuál es la forma correcta de representar una búsqueda de automóviles con ciertos atributos? Diga: muéstrame todos los sedanes azules con 4 puertas:

/car/search?color=blue&type=sedan&doors=4

¿O debería ser / coches en su lugar?

El uso de "búsqueda" parece inapropiado allí, ¿cuál es una mejor forma / término? Debería ser:

/cars/?color=blue&type=sedan&doors=4

¿Deben los parámetros de búsqueda ser parte de PATHINFO o QUERYSTRING?

En resumen, estoy buscando orientación para el diseño de url REST de modelos cruzados y para búsqueda.

[Actualización] Me gusta la respuesta de Justin, pero él no cubre el caso de búsqueda en varios campos:

/cars/color:blue/type:sedan/doors:4

o algo así. Como vamos de

/cars/color/blue

al caso de campos múltiples?


Aunque me gusta la respuesta de Justin, siento que representa con más precisión un filtro en lugar de una búsqueda. ¿Qué pasa si quiero saber acerca de los coches con nombres que comienzan con cam?

De la forma en que lo veo, podría incorporarlo a la forma en que maneja recursos específicos:
/ coches / cam *

O, simplemente puede agregarlo en el filtro:
/ coches / puertas / 4 / nombre / cámara * / colores / rojo, azul, verde

Personalmente, prefiero este último, sin embargo, de ninguna manera soy un experto en REST (habiendo oído hablar de él hace apenas unas 2 semanas ...)


Aunque tener los parámetros en la ruta tiene algunas ventajas, existen, IMO, algunos factores de peso.

  • No todos los caracteres necesarios para una consulta de búsqueda están permitidos en una URL. La mayoría de los caracteres de puntuación y Unicode tendrían que estar codificados en la URL como un parámetro de cadena de consulta. Estoy luchando con el mismo problema. Me gustaría usar XPath en la URL, pero no toda la sintaxis de XPath es compatible con una ruta URI. Por lo tanto, para rutas simples, /cars/doors/driver/lock/combination sería apropiado para ubicar el elemento " combination " en el documento XML de la puerta del conductor. Pero /car/doors[id=''driver'' and lock/combination=''1234''] no es tan amigable.

  • Hay una diferencia entre filtrar un recurso en función de uno de sus atributos y especificar un recurso.

    Por ejemplo, desde

    /cars/colors devuelve una lista de todos los colores para todos los autos (el recurso devuelto es una colección de objetos de color)

    /cars/colors/red,blue,green devolvería una lista de objetos de color que son rojos, azules o verdes, no una colección de autos.

    Para devolver los coches, el camino sería

    /cars?color=red,blue,green o /cars/search?color=red,blue,green

  • Los parámetros en la ruta son más difíciles de leer porque los pares nombre / valor no están aislados del resto de la ruta, que no son pares nombre / valor.

Un último comentario. Prefiero /garages/yyy/cars (siempre plural) a /garage/yyy/cars (quizás fue un error tipográfico en la respuesta original) porque evita cambiar el camino entre singular y plural. Para palabras con una ''s'' agregada, el cambio no es tan malo, pero cambiar /person/yyy/friends a /people/yyy parece incómodo.


El diseño bonito de RESTful URL se trata de mostrar un recurso basado en una estructura (estructura similar a un directorio, fecha: artículos / -id , objeto y sus atributos, ..), la barra / indica la estructura jerárquica, use el -id en lugar.

Estructura jerarquica

Personalmente preferiría:

/garage-id/cars/car-id /cars/car-id #for cars not in garages

Si un usuario elimina la parte /car-id , trae la vista previa de los cars intuitiva. El usuario sabe exactamente dónde está en el árbol, qué está mirando. Él sabe desde el primer vistazo, que los garajes y los coches están en relación. /car-id también denota que pertenece a diferencia de /car/id .

buscando

La consulta está bien tal como está , solo tiene su preferencia, lo que debe tenerse en cuenta. La parte divertida viene cuando se unen búsquedas (ver más abajo).

/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 &*

O básicamente cualquier cosa que no sea una barra como se explicó anteriormente.
La fórmula: /cars[?;]color[=-:]blue[,;+&] , * aunque no usaría el signo & ya que es irreconocible desde el texto a primera vista.

** ¿Sabía que pasar el objeto JSON en URI es RESTful? **

Listas de opciones

/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

posibles características?

Negar las cadenas de búsqueda (!)
Para buscar cualquier coche, pero no negro y rojo :
?color=!black,!red
color:(!black,!red)

Búsquedas unidas
Busque autos rojos o azules o negros con 3 puertas en garajes id 1..20 o 101..103 o 999 pero no 5 /garage[id=1-20,101-103,999,!5]/cars[color=red,blue,black;doors=3]
A continuación, puede construir consultas de búsqueda más complejas. (Observe la coincidencia de atributos de CSS3 para la idea de hacer coincidir subcadenas. Por ejemplo, buscar usuarios que contengan "bar" user*=bar )

Conclusión

De todos modos, esta podría ser la parte más importante para usted, ya que puede hacerlo como quiera después de todo, solo tenga en cuenta que el URI RESTful representa una estructura que se entiende fácilmente, por ejemplo, directorio- /directory/file , /collection/node/item , dates /articles/{year}/{month}/{day} .. Y cuando omite cualquiera de los últimos segmentos, inmediatamente sabrá lo que obtiene.

Entonces ..., todos estos personajes son permitidos sin codificar :

  • sin reservas: a-zA-Z0-9_.-~
  • reservado ;/?:@=&$-_.+!*''(),
  • inseguro *: <>"#%{}|/^~[]`

* Por qué no es seguro y por qué debería estar codificado: RFC 1738 ver 2.2

RFC 3986 ver 2.2
A pesar de lo que dije anteriormente, aquí hay una distinción común de delimitadores, lo que significa que algunos "son" más importantes que otros.

  • delimitadores genéricos:: :/?#[]@
  • sub-delimitadores:! !$&''()*+,;=

Más lectura:
Jerarquía: ver 2.3 , ver 1.2.3
doriantaylor.com/policy/http-url-path-parameter-syntax
Asignación de atributos CSS3
IBM: servicios web RESTful - Lo básico
Nota: RFC 1738 fue actualizado por RFC 3986


Esto no es REST. No puede definir URI para recursos dentro de su API. La navegación de recursos debe ser impulsada por hipertexto. Está bien si desea URI bonitas y grandes cantidades de acoplamiento, pero simplemente no lo llame REST, porque viola directamente las restricciones de la arquitectura RESTful.

Ver este article del inventor de REST.


Hay muchas buenas opciones para su caso aquí. Aún así debería considerar el uso del cuerpo POST.

La cadena de consulta es perfecta para su ejemplo, pero si tiene algo más complicado, por ejemplo, una larga lista arbitraria de elementos o condicionales booleanos, es posible que desee definir la publicación como un documento, que el cliente envía por POST.

Esto permite una descripción más flexible de la búsqueda, así como evita el límite de longitud de la URL del servidor.


La respuesta de Justin es probablemente el camino a seguir, aunque en algunas aplicaciones podría tener sentido considerar una búsqueda en particular como un recurso por derecho propio, por ejemplo, si desea admitir búsquedas guardadas con nombre:

/search/{searchQuery}

o

/search/{savedSearchName}


Mi consejo sería este:

/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.

Esperemos que eso te dé la idea. Esencialmente, su API Rest debe ser fácilmente detectable y debe permitirle navegar por sus datos. Otra ventaja de usar URL y no cadenas de consulta es que puede aprovechar los mecanismos de almacenamiento en caché nativos 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

Usé el caché de Google porque la página normal no funcionaba para mí aquí también está ese enlace: http://rest.blueoxen.net/cgi-bin/wiki.pl?QueryStringsConsideredHarmful


Para ampliar la respuesta de Peter, podría hacer de Search un recurso de primera clase:

POST /searches # create a new search GET /searches # list all searches (admin) GET /searches/{id} # show the results of a previously-run search DELETE /searches/{id} # delete a search (admin)

El recurso de búsqueda tendría campos para el color, modelo, estado empaquetado, etc. y podría especificarse en XML, JSON o cualquier otro formato. Al igual que el recurso de Automóviles y Garajes, podría restringir el acceso a las búsquedas en función de la autenticación. Los usuarios que ejecutan con frecuencia las mismas búsquedas pueden almacenarlos en sus perfiles para que no tengan que volver a crearlos. Las URL serán lo suficientemente cortas para que, en muchos casos, puedan intercambiarse fácilmente por correo electrónico. Estas búsquedas almacenadas pueden ser la base de fuentes RSS personalizadas, y así sucesivamente.

Hay muchas posibilidades para usar Búsquedas cuando las consideras como recursos.

La idea se explica con más detalle en este Railscast .


Para la búsqueda, utilice cadenas de consulta. Esto es perfectamente REST.

/cars?color=blue&type=sedan&doors=4

Una ventaja de las cadenas de consulta regulares es que son estándar y ampliamente entendidas y que pueden generarse a partir de la obtención de formularios.


RESTful no recomienda el uso de verbos en URL / cars / search no es reparador. La forma correcta de filtrar / buscar / paginar su API es a través de los Parámetros de Consulta. Sin embargo, puede haber casos en los que hay que romper la norma. Por ejemplo, si está buscando en múltiples recursos, entonces tiene que usar algo como / search? Q = query

Puede visitar http://saipraveenblog.wordpress.com/2014/09/29/rest-api-best-practices/ para comprender las mejores prácticas para diseñar APIs RESTful


Yo uso dos enfoques para implementar búsquedas.

1) El caso más simple, para consultar elementos asociados, y para la navegación.

/cars?q.garage.id.eq=1

Esto significa, consultar los coches que tienen ID de garaje igual a 1.

También es posible crear búsquedas más complejas:

/cars?q.garage.street.eq=FirstStreet&q.color.ne=red&offset=300&max=100

Autos en todos los garajes en FirstStreet que no son rojos (3ra página, 100 elementos por página).

2) Las consultas complejas se consideran recursos regulares que se crean y se pueden recuperar.

POST /searches => Create GET /searches/1 => Recover search GET /searches/1?offset=300&max=100 => pagination in search

El cuerpo POST para la creación de búsquedas es el siguiente:

{ "$class":"test.Car", "$q":{ "$eq" : { "color" : "red" }, "garage" : { "$ne" : { "street" : "FirstStreet" } } } }

Se basa en Grails (criterios DSL): http://grails.org/doc/2.4.3/ref/Domain%20Classes/createCriteria.html