Trait de barre oblique dans l'API RESTful

60

J'ai eu un débat sur ce qu'il faut faire avec une barre oblique de fin dans une API RESTful.

Disons que j'ai une ressource appelée chiens et ressources subordonnées pour des chiens individuels. Nous pouvons donc faire ce qui suit:

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

Mais que faisons-nous avec le cas particulier suivant:

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

Mon opinion personnelle est que cela signifie envoyer une demande à une ressource de chien individuelle avec id = null. Je pense que l'API devrait renvoyer un 404 pour ce cas.

D'autres disent que la demande accède à la ressource chiens, c'est-à-dire que la barre oblique finale est ignorée.

Est-ce que quelqu'un connaît la réponse définitive?

Gaz_Edge
la source
2
Je pensais que la méthode RESTful consistait à faire la distinction entre chien / identifiant et chiens (signifiant tous les chiens).
pdr
Extrait du livre Services Web RESTful - Ressources subordonnées: ressources associées à une autre ressource «mère», par exemple dogs / {id} Une base de données Web peut exposer une table en tant que ressource et les lignes de la base individuelle en tant que ses ressources subordonnées. .
Gaz_Edge
Pour accéder à la ressource chien, la barre oblique finale doit être ignorée, ce qui signifie qu’elle doit obtenir une réponse interdite si vous essayez de supprimer quelque chose que cette suppression ne doit pas être appliquée. Je suppose que 404 est également acceptable. Est-ce important?
Benjamin Gruenbaum
Je ne vous suis pas - qui a dit que vous ne pouviez pas effacer les chiens? Si vous supprimez des chiens, tous les chiens sont supprimés. C'est pourquoi je pense que permettre des appels à des chiens / est risqué. Que se passe-t-il si le client voulait supprimer un chien individuel, mais a accidentellement omis de {id}? Le résultat serait que tous les chiens seraient supprimés. Il est beaucoup plus
prudent
Je traiterais dogset dogs/comme équivalent. Pour moi, il est clair que dogs/c'est un répertoire contenant les chiens individuels. Ce qui dogsest moins clair , mais je considérerais cela comme équivalent, tout comme la plupart des serveurs Web acceptent les accès aux répertoires sans suivi /.
CodesInChaos

Réponses:

50

Rien de tout cela ne fait autorité (car REST n'a pas de signification exacte). Mais dans le document original sur REST, une URL complète (ne se terminant pas par /) nomme une ressource, tandis que celle se terminant par une barre oblique '/' correspond à un groupe de ressources (probablement pas rédigé de la sorte).

Un GET d'une URL avec une barre oblique à la fin est censé répertorier les ressources disponibles.

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

Un PUT sur une URL avec une barre oblique est supposé remplacer toutes les ressources.

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

Un DELETE sur une URL avec une barre oblique est supposé supprimer toutes les ressources

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

Un POST sur une URL avec une barre oblique est censé créer une nouvelle ressource peut ensuite être consulté. Pour être conforme, la nouvelle ressource doit se trouver dans ce répertoire (bien que de nombreuses architectures RESTful trichent ici).

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

etc.

La page wiki sur le sujet semble bien l'expliquer:

Voir les exemples https://en.wikipedia.org/wiki/Representational_state_transfer#Applied_to_Web_services .

Martin York
la source
Il correspond également au modèle de chemin / url normal, où les répertoires sont souvent écrits avec une fin/
CodesInChaos
4
Alors, que devrait-il se passer si vous accédez à un groupe de ressources sans la fin /?
oberlies
1
@oberlies: Cela dépend du contexte. Il n'y a pas de règles strictes ni de règles optimales Il y a toujours des attentes à la règle et cela devrait vouloir dire ce que vous attendez d'elle. Dans l'exemple ci-dessus: GET http://example.com/dogspeut renvoyer des méta-informations sur les chiens (pas la liste elle-même, mais des méta-informations sur la liste des chiens). Peut-être ou peut-être que c'est une erreur.
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.Ce n'est pas le seul endroit qui suggère de ne pas utiliser l'entraînement slash
Laiv
@ Laiv Je ne suis pas en désaccord avec le sentiment. Mais veuillez lier une référence plus fiable (c'est un maillon faible).
Martin York
17
Does anyone know the definitive answer?

Il n'y en a pas car il n'y a pas de document officiel sur ce qui est requis pour qu'un service soit considéré comme RESTful.

Cela dit, j'autoriserais le slash final simplement pour la facilité d'utilisation. Techniquement, cela pourrait être perçu comme une tentative d'accès à un chien avec un identifiant nul; Je ne vois pas un utilisateur faire ce saut à moins de l'avoir lu dans votre documentation. Je peux voir un utilisateur qui tente d'écrire du code par rapport à votre API et inclut la barre oblique finale simplement par habitude et se demande pourquoi il obtient une réponse 404 lorsqu'il veut une liste de chiens.

Mike
la source
Qu'en est-il de DELETE example.com/dogs ?
Benjamin Gruenbaum
Puisque le chien est le parent de tous les chiens individuels, la suppression de chiens supprimera tous les chiens individuels et eux-mêmes. Si vous ne le faites pas, votre hypermédia tombera en panne
Gaz_Edge
@Gaz_Edge: In REST example.com/dogsest une ressource totalement indépendante de toute ressource example.com/dogs/X. Ainsi, un DELETE sur example.com/dogsne doit pas supprimer tous les chiens / * (bien que cela puisse être le cas si c'est la sémantique). Mais DELETE example.com/dogs/devrait supprimer tous les chiens / *.
Martin York
3
Je dirais encore une fois que puisqu'il n'y a pas de règles définitives sur ce qui est RESTful, ce qui se passe lorsque vous supprimez / chiens ou / chiens / est basé sur ce que vous attendez des utilisateurs de votre API. Est-il probable qu'ils souhaitent réellement supprimer tous les chiens avec une seule demande? Si c'est le cas, implémentez-le comme cela, sinon donnez une réponse 405 Method Not Allowed.
Mike
1
Je sais que c'est un vieux fil, mais je me suis récemment posé cette question moi-même. Pour ce que ça vaut la peine, l'OS X shell Bash traite foo, foo/, et de manière foo////identique. Il semble fondamentalement dépouiller les segments de chemin vides. Donc, si vous suivez la même approche avec votre service REST, dogset dogs/se réfère à la même chose.
Greg Brown
2

Deux façons.

Méthode 1

Utilisez toujours des barres obliques de fin pour toute ressource pouvant contenir des enfants.

Considérez simplement "GET" sur un répertoire public_html avec des fichiers.

Pas possible quand hello.html est un fichier:

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

Mais possible quand hello.html est un répertoire:

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

Donc, si "hello.html" peut avoir des enfants, il est toujours et toujours "/hello.html/" et "/hello.html/index.html" (ou simplement /hello.html/) est une liste de ces enfants .

Méthode 2

Soyez "intelligent".

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

La commande find ne se soucie pas du type de hello.html. Répertoire ou fichier, peu importe, c'est le nom d'un objet. Lorsque nous écrivons "cp youagain.html hello.html", cp peut comprendre comment gérer hello.html. cp est intelligent. Votre serveur Web est intelligent aussi. Il a une bibliothèque de gestion de chemin. Il a routage. Il peut stat et vous dire si un nom est un objet ou un répertoire. Il peut rediriger bla à bla / ou même simplement donner la même réponse pour les deux. C'est le génial !!! façon. Tant de technologie. Qui voudrait jamais simplement concaténer des chaînes de chemin quand on pourrait faire tout ça ???

Samuel Danielson
la source