respuestas - ¿Usar un verbo en URL es fundamentalmente incompatible con REST?
rest para dummies (4)
El método HTTP es el verbo: GET, PUT, POST, etcétera, mientras que la URL siempre debe referirse al sustantivo (receptor de la acción). Piénselo de esta manera: ¿Tendrían sentido dos verbos en una oración? "GET calcular" es una tontería, donde "GET state" es bueno y "GET process" es mejor ("state" es metadata para un proceso).
Entonces, digamos que tenemos algo que no parece estar mejor representado como un recurso (el estado del proceso que queremos pausar, el cálculo sin estado que queremos realizar en el servidor, etc.).
Si en el diseño de API usamos el process/123/pause
o calculations/fibonacci
, ¿eso es fundamentalmente incompatible con REST? Tan lejos de lo que leo, parece que no, siempre y cuando estas URL sean reconocibles usando HATEOAS y los tipos de medios estén estandarizados.
¿O debería preferir poner acción en el mensaje tal como se responde here ?
Nota 1:
Entiendo que es posible reformular algunos de mis ejemplos en términos de sustantivos. Sin embargo, creo que para casos específicos los sustantivos no funcionan tan bien como los verbos. Así que estoy tratando de entender si tener esos verbos sería inmediatamente inseguro. Y si lo es, entonces por qué la recomendación es tan estricta y qué beneficios puedo perder al no seguirla en esos casos.
Nota 2:
Responder "REST no tiene ninguna restricción sobre eso" sería una respuesta válida (lo que significaría que este enfoque es RESTful). Las respuestas "depende de a quién le preguntes" o "es una mejor práctica" no responden realmente a la pregunta. La pregunta supone que el concepto de REST existe como un término común bien definido que dos personas pueden usar para referirse al mismo conjunto de restricciones. Si la suposición en sí misma es incorrecta y la discusión formal de REST no tiene sentido, por favor dígalo.
Este artículo tiene algunos buenos consejos: http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
Citando del artículo:
¿Qué pasa con las acciones que no encajan en el mundo de las operaciones de CRUD?
Aquí es donde las cosas pueden ser borrosas. Hay una serie de enfoques:
Reestructurar la acción para que aparezca como un campo de un recurso. Esto funciona si la acción no toma parámetros. Por ejemplo, una acción de activación podría asignarse a un campo booleano activado y actualizarse mediante un PATCH al recurso.
Trátelo como un sub recurso con los principios RESTful. Por ejemplo, la API de GitHub te permite protagonizar una esencia con PUT / gists /: id / star y unstar con DELETE / gists /: id / star.
A veces, realmente no tiene forma de asignar la acción a una estructura RESTful razonable. Por ejemplo, una búsqueda de múltiples recursos realmente no tiene sentido para aplicarse al punto final de un recurso específico. En este caso, / search tendría más sentido aunque no sea un sustantivo. Esto está bien: simplemente haga lo correcto desde la perspectiva del consumidor API y asegúrese de que esté documentado claramente para evitar confusiones.
Personalmente me gusta la sugerencia n. ° 2. Si necesitas pausar algo, ¿qué estás pausando? Si es un proceso con un nombre, intente esto:
/process/{processName}/pause
No se trata estrictamente de sustantivos vs. verbos; se trata de si usted es:
- identificando recursos
- manipular recursos a través de representaciones
¿Qué es un recurso? Fielding lo define así:
La abstracción clave de la información en REST es un recurso. Cualquier información que pueda nombrarse puede ser un recurso: un documento o imagen, un servicio temporal (por ejemplo, "el clima actual en Los Ángeles"), una colección de otros recursos, un objeto no virtual (por ejemplo, una persona), etc. . En otras palabras, cualquier concepto que pueda ser el objetivo de la referencia de hipertexto de un autor debe ajustarse a la definición de un recurso. Un recurso es un mapeo conceptual para un conjunto de entidades, no la entidad que corresponde al mapeo en un punto particular en el tiempo ".
Ahora, a tu pregunta. No puede simplemente mirar una URL y decir: "¿Es tal una URL fundamentalmente incompatible con REST?" porque las URL en un sistema REST no son realmente las más importantes. Es más importante que las URLs process/123/pause
y calculations/fibonacci
identifiquen los recursos según la definición anterior. Si lo hacen, no hay una violación de restricción REST. Si no lo hacen, estás violando la restricción de interfaz uniforme de REST. Su ejemplo me lleva a creer que no se ajusta a la definición del recurso y, por lo tanto , violaría esta restricción.
Para ilustrar qué podría ser un recurso en este sistema, podría cambiar el estado de un proceso al POST ponerlo en la colección de recursos de paused-processes
. Aunque esa es quizás una forma inusual de trabajar con procesos, no es fundamentalmente incompatible con el estilo de arquitectura REST.
En el caso de los cálculos, los cálculos mismos podrían ser el recurso y ese recurso podría verse así:
Request:
GET /calculations/5
Response:
{
fibonacci: 5,
prime-number: true,
square-root: 2.23607
}
Aunque de nuevo, ese es un concepto algo inusual de un recurso. Supongo que un uso un poco más típico podría verse así:
Request:
GET /stored-calculations/12381728 (note that URL is a random identifier)
Response:
{
number: 5,
fibonacci: 5,
prime-number: true,
square-root: 2.23607
}
aunque presumiblemente querría almacenar información adicional sobre ese recurso que no sea un cálculo puro que cualquiera puede hacer con una calculadora ...
Response:
{
number: 5,
fibonacci: 5,
prime-number: true,
square-root: 2.23607,
last-accessed-date: 2013-10-28T00:00:00Z,
number-of-retrievals-of-this-resource: 183
}
Se considera una mala práctica usar verbos en su API REST.
Hay algún material sobre SO y en otros lugares sobre por qué y cómo evitar el uso de verbos. Dicho esto, hay muchas API "REST" que usan verbos.
Para su API de process
, haría que el recurso Process tenga un campo de state
, que se puede modificar con un PUT
.
Supongamos que GET /process/$id
actualmente devuelve:
{
state: "PAUSED"
}
Luego PUT
esto a /process/$id
:
{
state: "RUNNING"
}
que hace que el proceso cambie de estado.
En el caso de Fibonacci, solo tiene un recurso llamado fibonacci
, y use POST
con parámetros (digamos n para los primeros n números de fibonacci) en el cuerpo, o quizás incluso GET
con una consulta en la URL.