Barra inclinada final en RESTful API

60

He tenido un debate sobre qué hacer con una barra inclinada final en una API RESTful.

Digamos que tengo un recurso llamado perros y recursos subordinados para perros individuales. Por lo tanto, podemos hacer lo siguiente:

GET/PUT/POST/DELETE http://example.com/dogs
GET/PUT/POST/DELETE http://example.com/dogs/{id}

Pero, ¿qué hacemos con el siguiente caso especial:

GET/PUT/POST/DELETE http://example.com/dogs/

Mi opinión personal es que esto dice enviar una solicitud a un recurso de perro individual con id = null. Creo que la API debería devolver un 404 para este caso.

Otros dicen que la solicitud está accediendo al recurso perros, es decir, se ignora la barra diagonal final.

¿Alguien sabe la respuesta definitiva?

Gaz_Edge
fuente
2
Pensé que la forma RESTful era distinguir entre dog / id y dogs (es decir, todos los perros).
pdr
Del libro RESTful Web Services - recursos subordinados: recursos que existen en relación con algún otro recurso "padre", es decir, perros / {id} Una base de datos habilitada para la web puede exponer una tabla como un recurso, y las filas de la base de datos individuales como sus recursos subordinados .
Gaz_Edge
Está accediendo al recurso del perro, la barra diagonal debe ignorarse, lo que significa que debe obtener una respuesta prohibida por intentar eliminar algo a lo que no se debe aplicar la eliminación. Supongo que 404 también es aceptable. Sin embargo, ¿importa?
Benjamin Gruenbaum
No entiendo, ¿quién dijo que no puedes eliminar perros? Si elimina perros, se eliminará a sí mismo y a todos los perros individuales. Es por eso que creo que permitir llamadas a perros / es arriesgado. ¿Qué pasa si el cliente quiso eliminar un perro individual, pero accidentalmente dejó el {id}? El resultado sería que todos los perros serían eliminados. Es mucho más seguro asumir que está pidiendo {id} nulo y devolver 404
Gaz_Edge
Lo trataría dogsy dogs/como equivalente. Para mí está claro que dogs/es un directorio que contiene los perros individuales. No está claro qué dogses, pero lo trataría como equivalente, al igual que la mayoría de los servidores web aceptan accesos a directorios sin el seguimiento /.
CodesInChaos

Respuestas:

50

Nada de esto es autoritario (ya que REST no tiene un significado exacto). Pero del documento original sobre REST, una URL completa (que no termina en /) nombra un recurso, mientras que una que termina en una barra inclinada '/' es un grupo de recursos (probablemente no redactado así).

Se supone que una OBTENCIÓN de una URL con una barra diagonal al final enumera los recursos disponibles.

GET http://example.com/dogs/          /* List all the dogs resources */

Se supone que un PUT en una URL con una barra diagonal reemplaza todos los recursos.

PUT http://example.com/dogs/          /* Replace all the dogs resources */

Se supone que un BORRAR en una URL con una barra diagonal elimina todos los recursos

DELETE http://example.com/dogs/       /* Deletes all the dogs resources */

Se supone que una POST en una URL con una barra diagonal para crear un nuevo recurso se puede acceder posteriormente. Para estar conforme, el nuevo recurso debe estar en este directorio (aunque muchas arquitecturas RESTful engañan aquí).

POST http://example.com/dogs/        /* Creates a new dogs resource (notice singular) */

etc.

La página wiki sobre el tema parece explicarlo bien:

Ver ejemplo https://en.wikipedia.org/wiki/Representational_state_transfer#Applied_to_Web_services .

Martin York
fuente
También se ajusta al modelo de ruta / url normal, donde los directorios a menudo se escriben con un final/
CodesInChaos
44
Entonces, ¿qué debería suceder si accede a un grupo de recursos sin el seguimiento /?
Oberlies
1
@oberlies: depende del contexto. No hay reglas estrictas y rápidas, solo las mejores prácticas. Siempre hay excepciones a la regla y debe significar lo que espera que signifique. En el ejemplo anterior: GET http://example.com/dogspuede devolver metainformación sobre los perros (no la lista en sí, sino metainformación sobre la lista de perros). Tal vez o tal vez sea un error.
Martin York
1
As the last character within a URI’s path, a forward slash (/) adds no semantic value and may cause confusion. It’s better to drop them completely.Este no es el único lugar que sugiere no usar la barra de entrenamiento
Laiv
@Laiv No estoy en desacuerdo con el sentimiento. Pero por favor vincule una referencia más autorizada (ese es un eslabón débil).
Martin York
17
Does anyone know the definitive answer?

No hay uno, ya que no hay un documento oficial sobre lo que se requiere para que un servicio se considere RESTful.

Dicho esto, permitiría la barra diagonal simplemente por facilidad de uso. Aunque técnicamente hablando, esto podría verse como un intento de acceder a un perro con una identificación nula; No veo a un usuario haciendo este salto a menos que lo hayan leído en su documentación. Puedo ver a un usuario que intenta escribir código en su API e incluye la barra diagonal simplemente por hábito y me pregunto por qué obtienen una respuesta 404 cuando quieren una lista de perros.

Miguel
fuente
¿Qué pasa con DELETE example.com/dogs ?
Benjamin Gruenbaum
Como dogs es el padre de todos los perros individuales, al eliminar perros se eliminarán todos los perros individuales y a sí mismo. Si no haces eso, tu hipermedia se romperá
Gaz_Edge
@Gaz_Edge: en REST example.com/dogses un recurso completamente independiente de cualquier recurso example.com/dogs/X. Por lo tanto, un DELETE on example.com/dogsno tiene que eliminar todos los perros / * (aunque puede hacerlo si esa es la semántica). Pero DELETE example.com/dogs/debería eliminar todos los perros / *.
Martin York
3
Una vez más, diría que, dado que no hay un conjunto definitivo de reglas sobre lo que es RESTful, lo que sucede cuando BORRAS / dogs o / dogs / se basaría en lo que esperas que los consumidores de tu API esperen. ¿Es probable que realmente quieran eliminar todos los perros con una sola solicitud? Si es así, impleméntelo así, de lo contrario, dé una respuesta 405 Método no permitido.
Mike
1
Sé que este es un hilo viejo, pero recientemente me he estado preguntando sobre esto. Por lo que vale la pena, los OS X shell trata Bash foo, foo/y foo////de forma idéntica. Básicamente parece eliminar segmentos de ruta vacíos. Entonces, si sigue el mismo enfoque con su servicio REST, dogsy dogs/se referiría a lo mismo.
Greg Brown
2

Dos caminos.

Método 1

Utilice siempre barras diagonales finales para cualquier recurso que pueda contener elementos secundarios.

Simplemente considere "OBTENER" en un directorio public_html con archivos.

No es posible cuando hello.html es un archivo:

/hello.html
/hello.html/youagain.html

Pero es posible cuando hello.html es un directorio:

/hello.html/     (actually /hello.html/index.html)
/hello.html/youagain.html

Entonces, si "hello.html" alguna vez puede tener hijos, entonces es siempre y para siempre "/hello.html/" y "/hello.html/index.html" (o simplemente /hello.html/) es una lista de estos niños .

Método 2

Se inteligente".

$ find
.
./hello.html
./hello.html/index.html

El comando find no se preocupa por el tipo de hello.html. Directorio o archivo, a quién le importa, es el nombre de un objeto. Cuando escribimos "cp youagain.html hello.html", cp puede descubrir cómo manejar hello.html. CP es inteligente. Tu servidor web también es inteligente. Tiene una biblioteca de manejo de ruta. Tiene enrutamiento. Puede generar estadísticas y decirte si un nombre es un objeto o un directorio. Puede redirigir bla a bla / o incluso simplemente ofrecer la misma respuesta para ambos. ¡Esto es increíble! camino. Tanta tecnología. ¿Quién querría simplemente concatenar cadenas de ruta cuando podríamos hacer todo eso?

Samuel Danielson
fuente