resource practices pattern nouns best rest resources naming-conventions uri

pattern - rest routes best practices



REST URI convención: nombre singular o plural del recurso al crearlo (18)

Soy nuevo en REST y he observado que en algunos servicios REST utilizan un URI de recursos diferente para actualizar / obtener / eliminar y crear. Como

  • Crear: usar / resources con el método POST (observar plural) en algunos lugares usando / resource (singular)
  • Actualización - usando / resource / 123 con el método PUT
  • Get - Usando / resource / 123 con el método GET

Estoy un poco confundido acerca de esta convención de nomenclatura URI. ¿Qué deberíamos usar plural o singular para la creación de recursos? ¿Cuáles deberían ser los criterios al decidir eso?


Singular

Conveniencia Las cosas pueden tener nombres plurales irregulares. A veces no tienen uno. Pero los nombres singulares siempre están ahí.

por ejemplo, CustomerAddress sobre CustomerAddresses

Considere este recurso relacionado.

Este /order/12/orderdetail/12 es más legible y lógico que /orders/12/orderdetails/4 .

Tablas de base de datos

Un recurso representa una entidad como una tabla de base de datos. Debe tener un nombre singular lógico. Aquí está la answer sobre los nombres de las tablas.

Mapeo de clases

Las clases son siempre singulares. Las herramientas ORM generan tablas con los mismos nombres que los nombres de clase. A medida que se utilizan más y más herramientas, los nombres singulares se están convirtiendo en un estándar.

Lea más sobre el dilema del desarrollador de A REST API



Ambas representaciones son útiles. Yo había usado el singular por conveniencia durante bastante tiempo, la inflexión puede ser difícil. Según mi experiencia en el desarrollo de API REST estrictamente singulares, los desarrolladores que consumen el punto final carecen de certeza sobre cuál puede ser la forma del resultado. Ahora prefiero usar el término que mejor describe la forma de la respuesta.

Si todos sus recursos son de nivel superior, entonces puede obtener representaciones singulares. Evitar la inflexión es una gran victoria.

Si está realizando algún tipo de enlace profundo para representar consultas sobre relaciones, entonces los desarrolladores que escriben en contra de su API pueden recibir ayuda mediante una convención más estricta.

Mi convención es que cada nivel de profundidad en un URI está describiendo una interacción con el recurso principal, y el URI completo debe describir implícitamente lo que se está recuperando.

Supongamos que tenemos el siguiente modelo.

interface User { <string>id; <Friend[]>friends; <Manager>user; } interface Friend { <string>id; <User>user; ...<<friendship specific props>> }

Si tuviera que proporcionar un recurso que le permita a un cliente obtener el administrador de un amigo en particular de un usuario en particular, podría ser algo como:

GET /users/{id}/friends/{friendId}/manager

Los siguientes son algunos ejemplos más:

  • GET /users : enumera los recursos de usuario en la colección global de usuarios
  • POST /users : crea un nuevo usuario en la colección global de usuarios
  • GET /users/{id} - recupera un usuario específico de la colección global de usuarios
  • GET /users/{id}/manager : obtenga el administrador de un usuario específico
  • GET /users/{id}/friends - obtiene la lista de amigos de un usuario
  • GET /users/{id}/friends/{friendId} - obtener un amigo específico de un usuario
  • LINK /users/{id}/friends - agrega una asociación de amigos a este usuario
  • UNLINK /users/{id}/friends - elimina una asociación de amigos de este usuario

Observe cómo cada nivel se asigna a un padre con el que se puede actuar. Usar diferentes padres para el mismo objeto es contraintuitivo. La recuperación de un recurso en GET /resource/123 no deja ninguna indicación de que la creación de un nuevo recurso se debe realizar en POST /resources


Con las convenciones de nomenclatura, generalmente es seguro decir "solo elige una y apégate a ella", lo que tiene sentido.

Sin embargo, después de tener que explicar REST a muchas personas, representar los puntos finales como rutas en un sistema de archivos es la forma más expresiva de hacerlo.
Es sin estado (los archivos existen o no existen), es jerárquico, simple y familiar: ya sabe cómo acceder a los archivos estáticos, ya sea localmente o a través de http.

Y dentro de ese contexto, las reglas lingüísticas solo pueden llevarlo a lo siguiente:

Un directorio puede contener varios archivos y / o subdirectorios, y por lo tanto su nombre debe estar en forma plural.

Y me gusta eso.
Aunque, por otro lado, es su directorio, puede llamarlo "un recurso o recursos múltiples" si eso es lo que quiere. Eso no es realmente lo importante.

Lo importante es que si coloca un archivo llamado "123" en un directorio llamado "resourceS" (que resulta en /resourceS/123 ), no puede esperar que sea accesible a través de /resource/123 .

No intente hacerlo más inteligente de lo que debe ser: cambiar de plural a singular dependiendo del número de recursos a los que está accediendo actualmente puede ser estético para algunos, pero no es efectivo y no tiene sentido en una Sistema jerárquico .

Nota: Técnicamente, puede hacer "enlaces simbólicos", de modo que también se puede acceder a /resource/123 a través de /resource/123 , ¡pero el primero aún debe existir!


Desde la perspectiva del consumidor de API, los puntos finales deben ser predecibles para

Idealmente...

  1. GET /resources debe devolver una lista de recursos.
  2. GET /resource debe devolver un código de estado de nivel 400.
  3. GET /resources/id/{resourceId} debe devolver una colección con un recurso.
  4. GET /resource/id/{resourceId} debe devolver un objeto de recurso.
  5. POST /resources debe crear recursos por lotes.
  6. POST /resource debe crear un recurso.
  7. PUT /resource debe actualizar un objeto de recurso.
  8. PATCH /resource debe actualizar un recurso publicando solo los atributos modificados.
  9. PATCH /resources debería actualizar por lotes los recursos que solo publican los atributos modificados.
  10. DELETE /resources debería eliminar todos los recursos; Es broma: código de estado 400
  11. DELETE /resource/id/{resourceId}

Este enfoque es el más flexible y rico en funciones, pero también el más lento de desarrollar. Por lo tanto, si tiene prisa (como siempre ocurre con el desarrollo de software) simplemente nombre su resource punto final o los resources forma plural. Prefiero la forma singular porque le da la opción de realizar una introspección y evaluación programáticamente, ya que no todas las formas plurales terminan en ''s''.

Dicho todo esto, por cualquier razón, el desarrollador de práctica más comúnmente utilizado ha optado por utilizar la forma plural. Esta es, en última instancia, la ruta que he elegido y si nos fijamos en apis populares como github y twitter , esto es lo que hacen.

Algunos criterios para decidir podrían ser:

  1. ¿Cuáles son mis limitaciones de tiempo?
  2. ¿Qué operaciones permitiré a mis consumidores hacer?
  3. ¿Cómo es la carga útil de solicitud y resultado?
  4. ¿Quiero poder usar la reflexión y analizar el URI en mi código?

Eso depende de ti. Lo que sea que hagas sea consistente.


Me sorprende ver que tanta gente se suba al carro del sustantivo plural. Cuando implementas conversiones de singular a plural, ¿estás cuidando los sustantivos irregulares de plural? ¿Te gusta el dolor?

Consulte http://web2.uvcs.uvic.ca/elc/studyzone/330/grammar/irrplu.htm

Hay muchos tipos de plural irregular, pero estos son los más comunes:

Tipo de sustantivo Formando el plural Ejemplo

Termina con -fe Cambie de f a v, luego Agregue cuchillos, vidas, esposas, esposas Termine con -f Cambie de f a v, luego Agregue medias Mitades, lobo, pan, hogazas Termine con -o Agregue papas, papa, tomate, tomate, volcán, volcanes, extremos con -us Cambio -us a -i cactus cactus núcleos núcleos focales termina con -is Cambio -is a -es análisis analiza crisis tesis tesis termina con -on Cambio -en -un fenómeno de fenómenos criterio criterios TODO CLASE Cambie la vocal o Cambie la palabra o Agregue un final diferente hombre hombre pie pie niño niños persona personas diente dientes ratón ratones Sin cambio Singular y plural son las mismas ovejas venado peces (a veces)


Mientras que la práctica más frecuente son las apis REST cuando se usan plurales, por ejemplo, /api/resources/123 , hay un caso especial en el que encuentro que el uso de un nombre en singular es más apropiado / expresivo que los nombres en plural. Es el caso de las relaciones uno a uno. Específicamente si el elemento de destino es un objeto de valor (en el paradigma de diseño impulsado por dominio).

Asumamos que cada recurso tiene un accessLog uno a uno que podría modelarse como un objeto de valor, es decir, no una entidad, por lo tanto, no tiene ID. Podría expresarse como /api/resources/123/accessLog . Los verbos habituales (POST, PUT, DELETE, GET) expresarán adecuadamente la intención y también el hecho de que la relación es de hecho uno a uno.


Mis dos centavos: los métodos que pasan su tiempo cambiando de plural a singular o viceversa son una pérdida de ciclos de CPU. Puede que sea de la vieja escuela, pero en mi época las cosas se llamaban igual. ¿Cómo busco métodos relativos a las personas? Ninguna expresión regular cubrirá tanto a personas como a personas sin efectos secundarios indeseables.

Los plurales ingleses pueden ser muy arbitrarios y gravan el código innecesariamente. Se adhieren a una convención de nomenclatura. Se suponía que los lenguajes informáticos eran sobre la claridad matemática, no sobre la imitación del lenguaje natural.


Para mí es mejor tener un esquema que pueda asignar directamente al código (fácil de automatizar), principalmente porque el código es lo que va a ser en ambos extremos.

GET /orders <---> orders POST /orders <---> orders.push(data) GET /orders/1 <---> orders[1] PUT /orders/1 <---> orders[1] = data GET /orders/1/lines <---> orders[1].lines POST /orders/1/lines <---> orders[1].lines.push(data)


Para mí, los plurales manipulan la colección , mientras que los singulares manipulan el elemento dentro de esa colección.

La colección permite los métodos GET / POST / DELETE.

El ítem permite los métodos GET / PUT / DELETE.

Por ejemplo

POST en / los estudiantes agregarán un nuevo estudiante en la escuela.

ELIMINAR el / los estudiantes eliminarán a todos los estudiantes en la escuela.

ELIMINAR en / alumno / 123 eliminará al alumno 123 de la escuela.

Puede parecer que no es importante, pero algunos ingenieros a veces olvidan la identificación. Si la ruta siempre fue plural y realizó un BORRADO, puede borrar accidentalmente sus datos. Mientras que faltar el id en el singular devolverá una ruta 404 no encontrada.

Para ampliar aún más el ejemplo, si se suponía que la API expondría varias escuelas, entonces algo como

ELIMINAR en / escuela / abc / estudiantes eliminará a todos los estudiantes en la escuela abc .

Elegir la palabra correcta a veces es un desafío por sí solo, pero me gusta mantener la pluralidad de la colección. Por ejemplo, cart_items o cart/items siente bien. En contraste, al eliminar el cart , se elimina el objeto del carrito y no los elementos del carrito;).


Prefiero usar la forma singular por simplicidad y consistencia.

Por ejemplo, considerando la siguiente url:

/ cliente / 1

Trataré al cliente como una colección de clientes, pero por simplicidad, la parte de la colección se elimina.

Otro ejemplo:

/ equipo / 1

En este caso, los equipos no son la forma plural correcta. Por lo tanto, tratarlo como una colección de equipos y eliminar la colección por simplicidad lo hace consistente con el caso del cliente.


Prefiero usar tanto plural ( /resources ) como singular ( /resource/{id} ) porque creo que separa más claramente la lógica entre trabajar en la recopilación de recursos y trabajar en un solo recurso.

Como un efecto secundario importante de esto, también puede ayudar a evitar que alguien utilice la API de forma incorrecta. Por ejemplo, considere el caso en el que un usuario intenta obtener un recurso de manera incorrecta al especificar el ID como un parámetro como este:

GET /resources?Id=123

En este caso, donde usamos la versión plural, el servidor probablemente ignorará el parámetro Id y devolverá la lista de todos los recursos. Si el usuario no tiene cuidado, pensará que la llamada fue exitosa y usará el primer recurso en la lista.

Por otro lado, al utilizar la forma singular:

GET /resource?Id=123

lo más probable es que el servidor devuelva un error porque la identificación no está especificada de la manera correcta, y el usuario tendrá que darse cuenta de que algo está mal.


Qué tal si:

/resource/ (no /resource )

/resource/ significa que es una carpeta que contiene algo llamado "resource", es una carpeta de "resouce".

Y también creo que la convención de nomenclatura de las tablas de la base de datos es la misma, por ejemplo, una tabla llamada "usuario" es una "tabla de usuario", contiene algo llamado "usuario".


Sé que la mayoría de las personas están entre decidir si usar plural o singular. El problema que no se ha abordado aquí es que el cliente necesitará saber cuál está utilizando, y es probable que siempre cometan un error. Aquí es de donde viene mi sugerencia.

¿Qué tal ambos? Y con eso, me refiero a usar singular para toda su API y luego crear rutas para reenviar solicitudes hechas en forma plural a la forma singular. Por ejemplo:

GET /resources = GET /resource GET /resources/1 = GET /resource/1 POST /resources/1 = POST /resource/1 ...

Te dan la imagen. Nadie se equivoca, requiere un esfuerzo mínimo y el cliente siempre lo hará bien.


Tampoco veo el punto de hacer esto y creo que no es el mejor diseño de URI. Como usuario de un servicio REST, espero que el recurso de la lista tenga el mismo nombre, sin importar si accedo a la lista o al recurso específico "en" la lista. Debe usar los mismos identificadores sin importar si desea usar el recurso de la lista o un recurso específico.


Usar el plural para todos los métodos es más práctico al menos en un aspecto: si está desarrollando y probando una API de recursos utilizando Postman (o una herramienta similar), no necesita editar el URI al cambiar de GET a PUT a POST, etc. .


Plural

  • Simple - todas las direcciones URL comienzan con el mismo prefijo
  • Lógica - orders/ obtiene una lista de índice de pedidos.
  • Estándar : el estándar más adoptado, seguido por la gran mayoría de las API públicas y privadas.

Por ejemplo:

GET /resources - devuelve una lista de elementos de recursos

POST /resources - crea uno o varios elementos de recursos

PUT /resources - actualiza uno o varios elementos de recursos

PATCH /resources : actualiza parcialmente uno o varios elementos de recursos

DELETE /resources : elimina todos los elementos de recursos

Y para elementos de recursos individuales:

GET /resources/:id : devuelve un elemento de recurso específico basado en el parámetro :id

POST /resources/:id : crea un elemento de recurso con la identificación especificada (requiere validación)

PUT /resources/:id - actualiza un elemento de recurso específico

PATCH /resources/:id - actualiza parcialmente un elemento de recurso específico

DELETE /resources/:id - elimina un elemento de recurso específico

Para los defensores del singular, piénselo de esta manera: ¿Le pediría un pedido a alguien y esperaría una cosa o una lista de cosas? Entonces, ¿por qué esperaría que un servicio devolviera una lista de cosas cuando escribe /order ?


La premisa de usar /resources es que representa "todos" los recursos. Si realiza un GET /resources , es probable que devuelva la colección completa. Al realizar POST en /resources , está agregando a la colección.

Sin embargo, los recursos individuales están disponibles en / recurso. Si realiza un GET /resource , es probable que se produzca un error, ya que esta solicitud no tiene ningún sentido, mientras que /resource/123 tiene mucho sentido.

Usar /resource lugar de /resources es similar a cómo lo haría si estuviera trabajando con, por ejemplo, un sistema de archivos y una colección de archivos y /resource es el "directorio" con los 123 , 456 archivos individuales que 123 .

De ninguna manera es correcto o incorrecto, ve con lo que más te guste.