Quiero hacer que mi API RESTful sea muy predecible. ¿Cuál es la mejor práctica para decidir cuándo hacer una segmentación de datos utilizando el URI en lugar de utilizar parámetros de consulta?
Para mí tiene sentido que los parámetros del sistema que admiten la paginación, la clasificación y la agrupación estén después del '?' Pero, ¿qué pasa con los campos como 'estado' y 'región' u otros atributos que segmentan su colección? Si también van a ser parámetros de consulta, ¿cuál es la regla general para saber cuándo usar parámetros de ruta?
Respuestas:
La mejor práctica para el diseño de RESTful API es que los parámetros de ruta se usan para identificar un recurso o recursos específicos, mientras que los parámetros de consulta se usan para ordenar / filtrar esos recursos.
Aquí hay un ejemplo. Suponga que está implementando puntos finales API RESTful para una entidad llamada Car. Estructurarías tus puntos finales de esta manera:
GET
/cars
GET
/cars/:id
la POST
/cars
PUT
/cars/:id
DELETE
/cars/:id
De esta forma, solo está utilizando parámetros de ruta cuando especifica qué recurso buscar, pero esto no clasifica / filtra los recursos de ninguna manera.
Ahora suponga que desea agregar la capacidad de filtrar los automóviles por color en sus solicitudes GET. Como el color no es un recurso (es una propiedad de un recurso), puede agregar un parámetro de consulta que lo haga. Agregaría ese parámetro de consulta a su solicitud GET de
/cars
esta manera:OBTENER
/cars?color=blue
Este punto final se implementaría para que solo se devolvieran los automóviles azules.
En lo que respecta a la sintaxis, sus nombres de URL deben estar en minúsculas. Si tiene un nombre de entidad que generalmente tiene dos palabras en inglés, usaría un guión para separar las palabras, no el caso de camello.
Ex.
/two-words
fuente
La forma fundamental de pensar sobre este tema es la siguiente:
Un URI es un identificador de recurso que identifica de forma exclusiva una instancia específica de un TIPO de recurso. Como todo lo demás en la vida, cada objeto (que es una instancia de algún tipo), tiene un conjunto de atributos que son temporales o temporales.
En el ejemplo anterior, un automóvil es un objeto muy tangible que tiene atributos como marca, modelo y VIN, que nunca cambia, y color, suspensión, etc. que pueden cambiar con el tiempo. Entonces, si codificamos el URI con atributos que pueden cambiar con el tiempo (temporal), podemos terminar con múltiples URI para el mismo objeto:
Y años después, si el color de este mismo automóvil cambia a negro:
Tenga en cuenta que la instancia del automóvil en sí (el objeto) no ha cambiado, solo cambió el color. Tener múltiples URI apuntando a la misma instancia de objeto lo obligará a crear múltiples manejadores de URI; este no es un diseño eficiente y, por supuesto, no es intuitivo.
Por lo tanto, el URI solo debe constar de partes que nunca cambiarán y continuarán identificando de manera única ese recurso durante toda su vida útil. Todo lo que pueda cambiar debe reservarse para los parámetros de consulta, como tal:
En pocas palabras: piense en el polimorfismo.
fuente
En una API REST, no debe preocuparse demasiado por los URI predecibles. La sugerencia misma de la previsibilidad de URI alude a un malentendido de la arquitectura RESTful. Se supone que un cliente debería estar construyendo URI por sí mismo, algo que realmente no debería ser necesario.
Sin embargo, supongo que no está creando una verdadera API REST, sino una API 'inspirada en REST' (como la de Google Drive). En estos casos, la regla general es 'parámetros de ruta = identificación de recursos' y 'parámetros de consulta = clasificación de recursos'. Entonces, la pregunta es, ¿puede identificar de manera única su recurso SIN estado / región? Si es así, entonces quizás sea un parámetro de consulta. Si no, entonces es un camino param.
HTH
fuente
Una vez que diseñé una API, que recurso principal era
people
. Por lo general, los usuarios solicitarían un filtro filtradopeople
, para evitar que los usuarios llamaran algo así/people?settlement=urban
cada vez que lo implementaba, lo/people/urban
que luego me permitió agregar fácilmente/people/rural
. Además, esto permite acceder a la/people
lista completa si sería de alguna utilidad más adelante. En resumen, mi razonamiento fue agregar una ruta a subconjuntos comunesDesde aquí :
fuente
En términos generales, tiendo a usar parámetros de ruta cuando hay una 'jerarquía' obvia en el recurso, como:
Si ese único recurso tiene un estado, uno podría:
Sin embargo, si 'región' no es realmente parte del recurso expuesto, probablemente pertenece como uno de los parámetros de consulta, similar a la paginación (como mencionó).
fuente
La segmentación es más jerárquica y "bonita" pero puede ser limitante.
Por ejemplo, si tiene una url con tres segmentos, cada uno pasa parámetros diferentes para buscar un automóvil por marca, modelo y color:
Esta es una url muy bonita y más fácil de recordar por el usuario final, pero ahora te quedas con esta estructura. Digamos que quiere hacerlo para que en la búsqueda el usuario pueda buscar TODOS los autos azules o TODOS los Honda Civics. Un parámetro de consulta resuelve esto porque da un par de valores clave. Para que puedas pasar:
Ahora tiene una manera de hacer referencia al valor a través de su clave: "color" o "make" en su código de consulta.
Podría solucionar esto posiblemente utilizando más segmentos para crear una especie de estructura de valores clave como:
Espero que tenga sentido ...
fuente
URL de ejemplo:
/rest/{keyword}
Esta URL es un ejemplo de parámetros de ruta. Podemos obtener estos datos de URL usando
@PathParam
.URL de ejemplo:
/rest?keyword=java&limit=10
Esta URL es un ejemplo para los parámetros de consulta. Podemos obtener estos datos de URL usando
@Queryparam
.fuente