Si hay mejores prácticas documentadas, aún no las he encontrado. Sin embargo, aquí hay algunas pautas que uso al determinar dónde colocar parámetros en una url:
Los parámetros opcionales tienden a ser más fáciles de colocar en la cadena de consulta.
Si desea devolver un error 404 cuando el valor del parámetro no corresponde a un recurso existente, entonces tendería hacia un parámetro de segmento de ruta. por ejemplo, /customer/232
donde 232 no es una identificación de cliente válida.
Sin embargo, si desea devolver una lista vacía, cuando no se encuentre el parámetro, sugiero usar parámetros de cadena de consulta. p.ej/contacts?name=dave
Si un parámetro afecta a un subárbol completo de su espacio URI, use un segmento de ruta. por ejemplo, un parámetro de idioma /en/document/foo.txt
versus/document/foo.txt?language=en
Prefiero identificadores únicos para estar en un segmento de ruta en lugar de un parámetro de consulta.
Las reglas oficiales para URI se encuentran en esta especificación RFC aquí . También hay otra especificación RFC muy útil aquí que define reglas para parametrizar URI.
Respuesta tardía, pero agregaré información adicional a lo que se ha compartido, a saber, que hay varios tipos de "parámetros" para una solicitud, y debe tener esto en cuenta.
Ahora veamos los diferentes lugares donde podrían ir estos parámetros.
En general, desea que el estado se configure en encabezados o cookies, según el tipo de información de estado que sea. Creo que todos podemos estar de acuerdo en esto. Utilice encabezados http personalizados (X-My-Header) si es necesario.
Del mismo modo, el Contenido solo tiene un lugar para pertenecer, que está en el cuerpo de la solicitud, ya sea como cadenas de consulta o como contenido http multipart y / o JSON. Esto es consistente con lo que recibe del servidor cuando le envía contenido. Así que no debes ser grosero y hacerlo de manera diferente.
Los localizadores como "id = 5" o "action = refresh" o "page = 2" tendrían sentido tener como una ruta URL, como
mysite.com/article/5/page=2
donde en parte sabes lo que se supone que significa cada parte (los conceptos básicos como el artículo y 5 obviamente significa obtener los datos del tipo de artículo con id 5) y los parámetros adicionales se especifican como parte del URI. Pueden tener la forma depage=2
, opage/2
si sabe que después de cierto punto en el URI, las "carpetas" son pares de valores clave.Los filtros siempre van en la cadena de consulta, porque si bien son parte de la búsqueda de los datos correctos, solo están allí para devolver un subconjunto o modificación de lo que los localizadores devuelven solos. La búsqueda en
mysite.com/article/?query=Obama
(subconjunto) es un filtro, y también lo es/article/5?order=backwards
(modificación). ¡Piensa en lo que hace, no solo en cómo se llama!Si "ver" determina el formato de salida, entonces es un filtro (
mysite.com/article/5?view=pdf
) porque devuelve una modificación del recurso encontrado en lugar de buscar en qué recurso queremos. Si en cambio decide qué parte específica del artículo podemos ver (mysite.com/article/5/view=summary
), entonces es un localizador.Recuerde, reducir un conjunto de recursos es filtrar. Localizar algo específico dentro de un recurso es ubicar ... duh. El filtrado de subconjuntos puede devolver cualquier número de resultados (incluso 0). La localización siempre encontrará esa instancia específica de algo (si existe). El filtrado de modificaciones devolverá los mismos datos que el localizador, excepto los modificados (si se permite dicha modificación).
¡Espero que esto haya ayudado a las personas a tener momentos eureka si se han perdido sobre dónde poner las cosas!
fuente
id
un filtro entonces? Devuelve un subconjunto del recurso(page-1)*perpage
y mostrarperpage
elementos". Usarlo como filtro es correcto entonces, pero por diferentes razones. Llamarlo "página" es técnicamente incorrecto. Más semánticamente correcto sería llamarlo "desde" o "startAt"perpage
a 50 en lugar de 20.Depende de un diseño. No hay reglas para los URI en REST a través de HTTP (lo principal es que son únicos). A menudo se trata del gusto y la intuición ...
Tomo el siguiente enfoque:
fuente
OMI, los parámetros deberían ser mejores como argumentos de consulta. La url se usa para identificar el recurso, mientras que los parámetros de consulta agregados para especificar qué parte del recurso desea, cualquier estado que el recurso debería tener, etc.
fuente
http://labs.apache.org/webarch/uri/rfc/rfc3986.html#query
Según la implementación de REST,
1) Las variables de ruta se utilizan para la acción directa sobre los recursos, como un contacto o una canción, por ejemplo.
GET etc / api / resource / {songid} o
GET etc / api / resource / {contactid} devolverán los datos respectivos.
2) Los permisos / argumentos de consulta se utilizan para los recursos directos como los metadatos de una canción, por ejemplo, GET / api / resource / {songid}? Metadata = generes; devolverá los datos de los géneros para esa canción en particular.
fuente
"Empaque" y PUBLICE sus datos en el "contexto" que proporciona el localizador de recursos del universo, lo que significa # 1 por el bien del localizador.
Tenga en cuenta las limitaciones con el n. ° 2. Prefiero POSTs a # 1.
nota: las limitaciones se discuten para
POST in ¿Hay un tamaño máximo para el contenido del parámetro POST?
GET in ¿Hay un límite en la duración de una solicitud GET? y tamaño máximo de los parámetros de URL en _GET
ps estos límites se basan en las capacidades del cliente (navegador) y el servidor (configuración).
fuente
Según el estándar URI, la ruta es para parámetros jerárquicos y la consulta es para parámetros no jerárquicos. De c. puede ser muy subjetivo lo que es jerárquico para ti.
En situaciones en las que se asignan múltiples URI al mismo recurso, me gusta poner los parámetros, necesarios para la identificación, en la ruta y los parámetros, necesarios para construir la representación, en la consulta. (Para mí de esta manera es más fácil de enrutar).
Por ejemplo:
/users/123
y/users/123?fields="name, age"
/users
y/users?name="John"&age=30
Para reducir mapa me gusta usar los siguientes enfoques:
/users?name="John"&age=30
/users/name:John/age:30
Por lo tanto, depende de usted (y del enrutador del lado del servidor) cómo construye sus URI.
nota: Solo por mencionar que estos parámetros son parámetros de consulta. Entonces, lo que realmente está haciendo es definir un lenguaje de consulta simple. Mediante consultas complejas (que contienen operadores como y, o, mayor que, etc.) le sugiero que utilice un lenguaje de consulta ya existente. Las capacidades de las plantillas URI son muy limitadas ...
fuente
Como programador a menudo en el extremo del cliente, prefiero el argumento de consulta. Además, para mí, separa la ruta URL de los parámetros, agrega claridad y ofrece más extensibilidad. También me permite tener una lógica separada entre la construcción de URL / URI y el generador de parámetros.
Me gusta lo que dijo manuel aldana sobre la otra opción si hay algún tipo de árbol involucrado. Puedo ver que las partes específicas del usuario se cortan así.
fuente
No hay reglas duras y rápidas, pero la regla general desde un punto de vista puramente conceptual que me gusta usar se puede resumir brevemente de esta manera: una ruta URI (por definición) representa un recurso y los parámetros de consulta son esencialmente modificadores en ese recurso . Hasta el momento, que probablemente no ayuda ... Con una API REST que tiene los principales métodos de actuar sobre el uso de un único recurso
GET
,PUT
yDELETE
. Por lo tanto, si algo debe representarse en la ruta o como parámetro puede reducirse a si esos métodos tienen sentido para la representación en cuestión. ¿Podría razonablemente hacerPUT
algo en ese camino y sería semánticamente correcto hacerlo? Por supuesto, podría hacerPUT
algo en cualquier lugar y doblar el back-end para manejarlo, pero debería serPUT
Esto equivale a una representación del recurso real y no a una versión innecesariamente contextualizada del mismo. Para colecciones, se puede hacer lo mismoPOST
. Si desea agregar a una colección en particular, cuál sería una URL que tenga sentidoPOST
.Esto todavía deja algunas áreas grises, ya que algunos caminos podrían apuntar a la cantidad de recursos de los padres que es algo discrecional y dependiente de su uso. La única línea difícil que esto dibuja es que cualquier tipo de representación transitiva debe hacerse utilizando un parámetro de consulta, ya que no tendría un recurso subyacente.
En respuesta al ejemplo del mundo real dado en la pregunta original (API de Twitter), los parámetros representan una consulta transitiva que filtra el estado de los recursos (en lugar de una jerarquía). En ese ejemplo en particular, sería completamente irrazonable agregar a la colección representada por esas restricciones, y además esa consulta no podría representarse como una ruta que tendría sentido en los términos de un gráfico de objeto.
La adopción de este tipo de perspectiva orientada a los recursos puede mapearse fácilmente directamente al gráfico de objetos de su modelo de dominio y conducir la lógica de su API al punto en que todo funciona de manera muy limpia y de manera bastante autodocumentada una vez que se aclara. El concepto también se puede aclarar alejándose de los sistemas que utilizan el enrutamiento de URL tradicional asignado a un modelo de datos que normalmente no encaja (es decir, un RDBMS). Apache Sling ciertamente sería un buen lugar para comenzar. El concepto de despacho transversal de objetos en un sistema como Zope también proporciona un análogo más claro.
fuente
Aquí está mi opinión.
Los parámetros de consulta se utilizan como metadatos para una solicitud. Actúan como filtro o modificador para una llamada de recurso existente.
Ejemplo:
/calendar/2014-08-08/events
debería dar eventos de calendario para ese día.
Si quieres eventos para una categoría específica
/calendar/2014-08-08/events?category=appointments
o si necesita eventos de más de 30 minutos
/calendar/2014-08-08/events?duration=30
Una prueba de fuego sería verificar si la solicitud aún se puede servir sin parámetros de consulta.
fuente
Por lo general, tiendo a # 2, como argumento de consulta (es decir, / api / resource? Parameter = value).
Una tercera opción es publicar el parámetro = valor en el cuerpo.
Esto se debe a que funciona mejor para recursos de múltiples parámetros y es más extensible para uso futuro.
No importa cuál elija, asegúrese de elegir solo uno, no mezcle y combine. Eso lleva a una API confusa.
fuente
Se ha dejado de lado una "dimensión" de este tema, pero es muy importante: hay momentos en que las "mejores prácticas" tienen que ponerse de acuerdo con la plataforma que estamos implementando o aumentando con las capacidades REST.
Ejemplo práctico:
En la actualidad, muchas aplicaciones web implementan la arquitectura MVC (Modelo, Vista, Controlador). Asumen que se proporciona una ruta estándar determinada, aún más cuando esas aplicaciones web vienen con la opción "Habilitar URL de SEO".
Solo por mencionar una aplicación web bastante famosa: una tienda de comercio electrónico OpenCart. Cuando el administrador habilita las "URL de SEO", espera que dichas URL vengan en un formato MVC bastante estándar como:
Dónde
special-offers
es el controlador MVC que procesará la URL (que muestra la página de ofertas especiales)list-all
es la acción del controlador o el nombre de la función a llamar. (*)limit = 25 es una opción, indicando que se mostrarán 25 elementos por página.
(*)
list-all
es un nombre de función ficticio que utilicé para mayor claridad. En realidad, OpenCart y la mayoría de los marcos MVC tienen una función predeterminada, implícita (y generalmente omitida en la URL)index
que se llama cuando el usuario desea que se realice una acción predeterminada. Entonces la URL del mundo real sería:Con una aplicación ahora bastante estándar o una estructura framework similar a la anterior, a menudo obtendrá un servidor web que está optimizado para ello, que reescribe las URL para él (la verdadera "URL no SEOed" sería:)
http://www.domain.tld/index.php?route=special-offers/list-all&limit=25
.Por lo tanto, usted, como desarrollador, debe enfrentarse a la infraestructura existente y adaptar sus "mejores prácticas", a menos que sea el administrador del sistema, sepa exactamente cómo modificar una configuración de reescritura de Apache / NGinx (¡esto último puede ser desagradable!) Y así en.
Por lo tanto, su API REST a menudo sería mucho mejor siguiendo los estándares de la aplicación web de referencia, tanto por su coherencia como por su facilidad / velocidad (y, por lo tanto, el ahorro de presupuesto).
Para volver al ejemplo práctico anterior, una API REST consistente sería algo con URL como:
o (URL no SEO)
con una mezcla de argumentos de "caminos formados" y argumentos de "consulta formada".
fuente
Veo muchas API REST que no manejan bien los parámetros. Un ejemplo que surge a menudo es cuando el URI incluye información de identificación personal.
http://software.danielwatrous.com/design-principles-for-rest-apis/
Creo que una pregunta del corolario es cuando un parámetro no debería ser un parámetro, sino que debería moverse al HEADER o BODY de la solicitud.
fuente
Es una pregunta muy interesante.
Puede usar ambos, no hay ninguna regla estricta sobre este tema, pero el uso de variables de ruta URI tiene algunas ventajas:
Pero si usa variables de ruta, todos estos servicios pueden almacenar en caché sus solicitudes GET.
Le da al usuario más información sobre la estructura de los datos.
Pero si sus datos no tienen ninguna relación de jerarquía, aún puede usar las variables de ruta, usando una coma o punto y coma:
/ Ciudad / longitud, latitud
Como regla general, use una coma cuando el orden de los parámetros sea importante, use punto y coma cuando el orden no sea importante:
/ IconGenerator / rojo; azul; verde
Además de esas razones, hay algunos casos en los que es muy común usar variables de cadena de consulta:
http: // www.google.com/search?q=rest
En resumen, no hay ninguna razón sólida para usar uno de estos métodos, pero siempre que pueda, use variables URI.
fuente