Je cherche un moyen d'enrouler les API autour des fonctions par défaut dans mes applications Web, bases de données et CMS basés sur PHP.
J'ai regardé autour de moi et j'ai trouvé plusieurs frameworks "squelettes". En plus des réponses à ma question, il y a Tonic , un framework REST que j'aime car il est très léger.
J'aime REST le meilleur pour sa simplicité et je voudrais créer une architecture API basée sur elle. J'essaie de comprendre les principes de base et je ne les ai pas encore complètement compris. Par conséquent, un certain nombre de questions.
1. Est-ce que je comprends bien?
Disons que j'ai une ressource "utilisateurs". Je pourrais configurer un certain nombre d'URI comme ceci:
/api/users when called with GET, lists users
/api/users when called with POST, creates user record
/api/users/1 when called with GET, shows user record
when called with PUT, updates user record
when called with DELETE, deletes user record
Est-ce une représentation correcte d'une architecture RESTful jusqu'à présent?
2. J'ai besoin de plus de verbes
Créer, mettre à jour et supprimer peut être suffisant en théorie, mais dans la pratique, j'aurai besoin de beaucoup plus de verbes. Je me rends compte que ce sont des choses qui pourraient être intégrées dans une demande de mise à jour, mais ce sont des actions spécifiques qui peuvent avoir des codes de retour spécifiques et je ne voudrais pas les jeter toutes dans une seule action.
Certains qui me viennent à l'esprit dans l'exemple utilisateur sont:
activate_login
deactivate_login
change_password
add_credit
comment exprimer des actions telles que celles d'une architecture d'URL RESTful?
Mon instinct serait de faire un appel GET à une URL comme
/api/users/1/activate_login
et attendez un code d'état de retour.
Cela s'écarte cependant de l'idée d'utiliser des verbes HTTP. Qu'est-ce que tu penses?
3. Comment renvoyer des messages d'erreur et des codes
Une grande partie de la beauté de REST provient de son utilisation des méthodes HTTP standard. En cas d'erreur, j'émets un en-tête avec un code d'état d'erreur 3xx, 4xx ou 5xx. Pour une description détaillée de l'erreur, je peux utiliser le corps (non?). Jusqu'ici tout va bien. Mais quelle serait la façon de transmettre un code d'erreur propriétaire plus détaillé pour décrire ce qui s'est mal passé (par exemple, "échec de la connexion à la base de données" ou "connexion incorrecte à la base de données")? Si je le mets dans le corps avec le message, je dois l'analyser ensuite. Existe-t-il un en-tête standard pour ce genre de chose?
4. Comment faire l'authentification
- À quoi ressemblerait une authentification basée sur une clé API suivant les principes REST?
- Y a-t-il des points forts contre l'utilisation de sessions lors de l'authentification d'un client REST, à part que c'est une violation flagrante du principe REST? :) (je ne plaisante qu'à moitié ici, l'authentification basée sur la session fonctionnerait bien avec mon infrastructure existante.)
la source
Réponses:
J'ai remarqué cette question avec quelques jours de retard, mais je pense que je peux ajouter quelques informations. J'espère que cela peut être utile pour votre entreprise RESTful.
Point 1: est-ce que je comprends bien?
Tu as bien compris. C'est une représentation correcte d'une architecture RESTful. Vous pouvez trouver la matrice suivante de Wikipedia très utile pour définir vos noms et verbes:
Lorsque vous traitez un URI de collection comme:
http://example.com/resources/
GET : répertorie les membres de la collection, ainsi que leurs URI membres pour une navigation ultérieure. Par exemple, répertoriez toutes les voitures à vendre.
PUT : Signification définie comme "remplacer la collection entière par une autre collection".
POST : créez une nouvelle entrée dans la collection où l'ID est attribué automatiquement par la collection. L'ID créé est généralement inclus dans les données renvoyées par cette opération.
SUPPRIMER : Signification définie comme "supprimer toute la collection".
Lorsque vous traitez avec un URI membre comme:
http://example.com/resources/7HOU57Y
GET : récupère une représentation du membre adressé de la collection exprimée dans un type MIME approprié.
PUT : mettez à jour le membre adressé de la collection ou créez-le avec l'ID spécifié.
POST : traite le membre adressé comme une collection à part entière et en crée un nouveau subordonné.
DELETE : supprime le membre adressé de la collection.
Point 2: j'ai besoin de plus de verbes
En général, lorsque vous pensez avoir besoin de plus de verbes, cela peut en fait signifier que vos ressources doivent être ré-identifiées. N'oubliez pas que dans REST, vous agissez toujours sur une ressource ou sur une collection de ressources. Ce que vous choisissez comme ressource est très important pour votre définition d'API.
Activer / Désactiver la connexion : Si vous créez une nouvelle session, vous souhaiterez peut-être considérer "la session" comme ressource. Pour créer une nouvelle session, utilisez POST to
http://example.com/sessions/
avec les informations d'identification dans le corps. Pour l'exirer, utilisez PUT ou DELETE (peut-être selon que vous avez l'intention de conserver un historique de session)http://example.com/sessions/SESSION_ID
.Changer le mot de passe: Cette fois, la ressource est "l'utilisateur". Vous auriez besoin d'un PUT
http://example.com/users/USER_ID
avec les anciens et nouveaux mots de passe dans le corps. Vous agissez sur la ressource "l'utilisateur" et un changement de mot de passe est simplement une demande de mise à jour. Elle est assez similaire à l'instruction UPDATE dans une base de données relationnelle.Cela va à l'encontre d'un principe REST très fondamental: l'utilisation correcte des verbes HTTP. Toute demande GET ne doit jamais laisser d'effet secondaire.
Par exemple, une demande GET ne doit jamais créer de session sur la base de données, renvoyer un cookie avec un nouvel ID de session ou laisser des résidus sur le serveur. Le verbe GET est comme l'instruction SELECT dans un moteur de base de données. N'oubliez pas que la réponse à toute demande avec le verbe GET doit pouvoir être mise en cache lorsqu'elle est demandée avec les mêmes paramètres, tout comme lorsque vous demandez une page Web statique.
Point 3: comment renvoyer des messages d'erreur et des codes
Considérez les codes d'état HTTP 4xx ou 5xx comme des catégories d'erreur. Vous pouvez élaborer l'erreur dans le corps.
Impossible de se connecter à la base de données: / Connexion à la base de données incorrecte : En général, vous devez utiliser une erreur 500 pour ces types d'erreurs. Il s'agit d'une erreur côté serveur. Le client n'a rien fait de mal. 500 erreurs sont normalement considérées comme "réessayables". c'est-à-dire que le client peut réessayer la même demande exacte et s'attendre à ce qu'elle réussisse une fois les problèmes du serveur résolus. Précisez les détails dans le corps, afin que le client soit en mesure de nous fournir un peu de contexte pour nous les humains.
L'autre catégorie d'erreurs serait la famille 4xx, qui indique généralement que le client a fait quelque chose de mal. En particulier, cette catégorie d'erreurs indique normalement au client qu'il n'est pas nécessaire de réessayer la demande telle qu'elle est, car elle continuera à échouer de manière permanente. c'est-à-dire que le client doit changer quelque chose avant de retenter cette demande. Par exemple, les erreurs «Ressource non trouvée» (HTTP 404) ou «Demande mal formée» (HTTP 400) tomberaient dans cette catégorie.
Point 4: Comment faire l'authentification
Comme indiqué au point 1, au lieu d'authentifier un utilisateur, vous voudrez peut-être penser à créer une session. Vous recevrez un nouvel "ID de session", ainsi que le code d'état HTTP approprié (200: accès accordé ou 403: accès refusé).
Vous demanderez alors à votre serveur RESTful: "Pouvez-vous m'OBTENIR la ressource pour cet ID de session?".
Il n'y a pas de mode authentifié - REST est sans état: vous créez une session, vous demandez au serveur de vous donner des ressources en utilisant cet ID de session comme paramètre, et à la déconnexion vous supprimez ou expirez la session.
la source
PUT
pour changer un mot de passe est probablement incorrecte;PUT
requiert la totalité de la ressource, vous devez donc envoyer tous les attributs utilisateur afin de vous conformer à HTTP (et donc à HATEOAS REST). Au contraire, pour simplement changer le mot de passe, il faut utiliserPATCH
ouPOST
.Autrement dit, vous faites cela complètement à l'envers.
Vous ne devriez pas aborder cela à partir des URL que vous devez utiliser. Les URL viendront effectivement "gratuitement" une fois que vous aurez décidé quelles ressources sont nécessaires pour votre système ET comment vous représenterez ces ressources, et les interactions entre les ressources et l'état de l'application.
Pour citer Roy Fielding
Les gens commencent toujours par les URI et pensent que c'est la solution, puis ils ont tendance à manquer un concept clé dans l'architecture REST, notamment, comme cité ci-dessus, "L'échec ici implique que les informations hors bande entraînent une interaction au lieu d'un hypertexte. "
Pour être honnête, beaucoup voient un tas d'URI et certains GET et PUT et POST et pensent que REST est facile. REST n'est pas facile. RPC sur HTTP est facile, déplacer des objets blob de données dans les deux sens via des charges utiles HTTP est facile. REST, cependant, va au-delà de cela. REST est indépendant du protocole. HTTP est juste très populaire et adapté aux systèmes REST.
REST réside dans les types de médias, leurs définitions et la manière dont l'application pilote les actions disponibles pour ces ressources via l'hypertexte (liens, efficacement).
Il existe différentes vues sur les types de supports dans les systèmes REST. Certains favorisent les charges utiles spécifiques à l'application, tandis que d'autres aiment élever les types de médias existants dans des rôles appropriés pour l'application. Par exemple, d'une part, vous avez des schémas XML spécifiques conçus adaptés à votre application par rapport à l'utilisation de quelque chose comme XHTML comme représentation, peut-être par le biais de microformats et d'autres mécanismes.
Je pense que les deux approches ont leur place, le XHTML fonctionnant très bien dans des scénarios qui chevauchent à la fois le web piloté par l'homme et le web, alors que les premiers types de données plus spécifiques me semblent mieux faciliter les interactions machine à machine. Je trouve que l'élévation des formats de produits peut rendre la négociation de contenu potentiellement difficile. "application / xml + yourresource" est beaucoup plus spécifique en tant que type de support que "application / xhtml + xml", car ce dernier peut s'appliquer à de nombreuses charges utiles qui peuvent ou non être quelque chose qui intéresse réellement un client de machine, et il ne peut pas non plus déterminer sans introspection.
Cependant, XHTML fonctionne très bien (évidemment) sur le Web humain où les navigateurs Web et le rendu sont très importants.
Votre application vous guidera dans ce genre de décisions.
Une partie du processus de conception d'un système REST consiste à découvrir les ressources de première classe de votre système, ainsi que les ressources de support dérivées nécessaires pour prendre en charge les opérations sur les ressources principales. Une fois les ressources découvertes, puis la représentation de ces ressources, ainsi que les diagrammes d'état montrant le flux des ressources via l'hypertexte au sein des représentations car le prochain défi.
Rappelons que chaque représentation d'une ressource, dans un système hypertexte, combine à la fois la représentation réelle de la ressource et les transitions d'état disponibles pour la ressource. Considérez chaque ressource comme un nœud dans un graphique, les liens étant les lignes laissant ce nœud à d'autres états. Ces liens informent les clients non seulement de ce qui peut être fait, mais aussi de ce qui est nécessaire pour cela (comme un bon lien combine l'URI et le type de support requis).
Par exemple, vous pouvez avoir:
Votre documentation parlera du champ rel nommé "utilisateurs" et du type de support "application / xml + youruser".
Ces liens peuvent sembler redondants, ils parlent tous à peu près au même URI. Mais ce n'est pas le cas.
En effet, pour la relation "utilisateurs", ce lien parle de la collection d'utilisateurs, et vous pouvez utiliser l'interface uniforme pour travailler avec la collection (GET pour les récupérer tous, DELETE pour les supprimer tous, etc.)
Si vous POSTEZ à cette URL, vous devrez passer un document "application / xml + usercollection", qui ne contiendra probablement qu'une seule instance d'utilisateur dans le document afin que vous puissiez ajouter l'utilisateur, ou non, peut-être, pour en ajouter plusieurs à une fois que. Peut-être que votre documentation suggérera que vous pouvez simplement passer un seul type d'utilisateur au lieu de la collection.
Vous pouvez voir ce dont l'application a besoin pour effectuer une recherche, comme défini par le lien "recherche" et son type de médiatisation. La documentation pour le type de support de recherche vous dira comment cela se comporte et à quoi s'attendre en tant que résultats.
Le point à retenir ici, cependant, est que les URI eux-mêmes sont fondamentalement sans importance. L'application contrôle les URI, pas les clients. Au-delà de quelques «points d'entrée», vos clients doivent s'appuyer sur les URI fournis par l'application pour son travail.
Le client a besoin de savoir comment manipuler et interpréter les types de médias, mais n'a pas grand-chose à faire où il va.
Ces deux liens sont sémantiquement identiques aux yeux des clients:
Alors, concentrez-vous sur vos ressources. Concentrez-vous sur leurs transitions d'état dans l'application et sur la meilleure façon d'y parvenir.
la source
re 1 : Cela semble bien jusqu'à présent. N'oubliez pas de renvoyer l'URI de l'utilisateur nouvellement créé dans un en-tête "Location:" dans le cadre de la réponse à POST, avec un code d'état "201 Created".
re 2: L'activation via GET est une mauvaise idée, et l'inclusion du verbe dans l'URI est une odeur de conception. Vous voudrez peut-être envisager de retourner un formulaire sur un GET. Dans une application Web, ce serait un formulaire HTML avec un bouton d'envoi; dans le cas d'utilisation de l'API, vous souhaiterez peut-être renvoyer une représentation contenant un URI à PUT pour activer le compte. Bien sûr, vous pouvez également inclure cet URI dans la réponse sur POST à / users. L'utilisation de PUT garantira que votre demande est idempotente, c'est-à-dire qu'elle peut être renvoyée en toute sécurité si le client n'est pas sûr du succès. En général, pensez aux ressources dans lesquelles vous pouvez transformer vos verbes (sorte de "dénonciation des verbes"). Demandez-vous à quelle méthode votre action spécifique est le plus étroitement alignée. Par exemple, change_password -> PUT; désactiver -> probablement SUPPRIMER; add_credit -> éventuellement POST ou PUT.
re 3. N'inventez pas de nouveaux codes de statut, sauf si vous pensez qu'ils sont si génériques qu'ils méritent d'être normalisés à l'échelle mondiale. Essayez d'utiliser le code d'état le plus approprié disponible (lisez-les tous dans la RFC 2616). Inclure des informations supplémentaires dans le corps de réponse. Si vous êtes vraiment, vraiment sûr de vouloir inventer un nouveau code d'état, détrompez-vous; si vous le croyez toujours, assurez-vous au moins de choisir la bonne catégorie (1xx -> OK, 2xx -> informatif, 3xx -> redirection; 4xx-> erreur client, 5xx -> erreur serveur). Ai-je mentionné qu'inventer de nouveaux codes de statut est une mauvaise idée?
re 4. Si possible, utilisez le cadre d'authentification intégré à HTTP. Découvrez comment Google procède à l'authentification dans GData. En général, ne mettez pas de clés API dans vos URI. Essayez d'éviter les sessions pour améliorer l'évolutivité et prendre en charge la mise en cache - si la réponse à une demande diffère en raison de quelque chose qui s'est produit auparavant, vous vous êtes généralement lié à une instance de processus serveur spécifique. Il est préférable de transformer l'état de session en un état client (par exemple, en faire partie des requêtes suivantes) ou de le rendre explicite en le transformant en état de ressource (serveur), c'est-à-dire en lui donnant son propre URI.
la source
1. Vous avez la bonne idée de la façon de concevoir vos ressources, à mon humble avis. Je ne changerais rien.
2. Plutôt que d'essayer d'étendre HTTP avec plus de verbes, pensez à ce que vos verbes proposés peuvent être réduits en termes de méthodes et de ressources HTTP de base. Par exemple, au lieu d'un
activate_login
verbe, vous pouvez configurer des ressources comme:/api/users/1/login/active
qui est un simple booléen. Pour activer une connexion, justePUT
un document qui dit «vrai» ou 1 ou autre chose. Pour désactiver,PUT
un document là-bas est vide ou dit 0 ou faux.De même, pour modifier ou définir des mots de passe, il suffit de faire
PUT
s pour/api/users/1/password
.Chaque fois que vous devez ajouter quelque chose (comme un crédit), pensez à l'
POST
art. Par exemple, vous pourriez faire unePOST
à une ressource comme/api/users/1/credits
avec un corps contenant le nombre de crédits à ajouter. UnPUT
sur la même ressource pourrait être utilisé pour remplacer la valeur plutôt que d'ajouter. UnPOST
avec un nombre négatif dans le corps soustrait, et ainsi de suite.3. Je déconseille fortement d'étendre les codes d'état HTTP de base. Si vous ne trouvez pas celui qui correspond exactement à votre situation, choisissez le plus proche et mettez les détails de l'erreur dans le corps de la réponse. N'oubliez pas non plus que les en-têtes HTTP sont extensibles; votre application peut définir tous les en-têtes personnalisés que vous aimez. Une application sur laquelle j'ai travaillé, par exemple, pourrait renvoyer un
404 Not Found
sous plusieurs circonstances. Plutôt que de demander au client d'analyser le corps de la réponse pour la raison, nous venons d'ajouter un nouvel en-têteX-Status-Extended
, qui contenait nos extensions de code d'état propriétaires. Vous pourriez donc voir une réponse comme:De cette façon, un client HTTP comme un navigateur Web saura toujours quoi faire avec le code 404 normal, et un client HTTP plus sophistiqué peut choisir de regarder l'en-
X-Status-Extended
tête pour des informations plus spécifiques.4. Pour l'authentification, je recommande d'utiliser l'authentification HTTP si vous le pouvez. Mais à mon humble avis, il n'y a rien de mal à utiliser l'authentification basée sur les cookies si c'est plus facile pour vous.
la source
Bases REST
REST a une contrainte d'interface uniforme, qui stipule que le client REST doit s'appuyer sur des normes au lieu des détails spécifiques à l'application du service REST réel, de sorte que le client REST ne se cassera pas par des modifications mineures et qu'il sera probablement réutilisable.
Il existe donc un contrat entre le client REST et le service REST. Si vous utilisez HTTP comme protocole sous-jacent, les normes suivantes font partie du contrat:
REST a une contrainte sans état, qui déclare que la communication entre le service REST et le client doit être sans état. Cela signifie que le service REST ne peut pas conserver les états du client, vous ne pouvez donc pas disposer d'un stockage de session côté serveur. Vous devez authentifier chaque demande. Ainsi, par exemple, l'authentification de base HTTP (faisant partie de la norme HTTP) est correcte, car elle envoie le nom d'utilisateur et le mot de passe à chaque demande.
Pour répondre à vos questions
Oui c'est possible.
Juste pour mentionner, les clients ne se soucient pas de la structure IRI, ils se soucient de la sémantique, car ils suivent des liens ayant des relations de lien ou des attributs de données liées (RDF).
La seule chose importante à propos des IRI, c'est qu'un seul IRI ne doit identifier qu'une seule ressource. Il est permis à une seule ressource, comme un utilisateur, d'avoir de nombreux IRI différents.
C'est assez simple pourquoi nous utilisons de bons IRI comme
/users/123/password
; il est beaucoup plus facile d'écrire la logique de routage sur le serveur lorsque vous comprenez l'IRI simplement en le lisant.Vous avez plus de verbes, comme PUT, PATCH, OPTIONS, et encore plus, mais vous n'en avez pas besoin de plus ... Au lieu d'ajouter de nouveaux verbes, vous devez apprendre à ajouter de nouvelles ressources.
activate_login -> PUT /login/active true deactivate_login -> PUT /login/active false change_password -> PUT /user/xy/password "newpass" add_credit -> POST /credit/raise {details: {}}
(La connexion n'a pas de sens du point de vue REST, en raison de la contrainte sans état.)
Vos utilisateurs ne se soucient pas de la raison du problème. Ils veulent seulement savoir s'il y a du succès ou une erreur, et probablement un message d'erreur qu'ils peuvent comprendre, par exemple: "Désolé, mais nous n'avons pas pu enregistrer votre message.", Etc ...
Les en-têtes d'état HTTP sont vos en-têtes standard. Je pense que tout le reste devrait être dans le corps. Un seul en-tête ne suffit pas pour décrire par exemple des messages d'erreur multilingues détaillés.
La contrainte sans état (ainsi que les contraintes de cache et de système en couches) garantit une bonne évolutivité du service. Vous ne voulez sûrement pas maintenir des millions de sessions sur le serveur, alors que vous pouvez faire de même sur les clients ...
Le client tiers obtient un jeton d'accès si l'utilisateur lui accorde l'accès à l'aide du client principal. Après cela, le client tiers envoie le jeton d'accès à chaque demande. Il existe des solutions plus compliquées, par exemple, vous pouvez signer chaque demande, etc. Pour plus de détails, consultez le manuel OAuth.
Littérature liée
Mémoire de Roy Thomas Fielding (auteur de REST)
2000, University of California, Irvine
dissertation de données liées de Markus Lanthaler (co-auteur de JSON-LD et auteur de Hydra)
2014, Graz University of Technology, Autriche
la source
Pour les exemples que vous avez indiqués, j'utiliserais ce qui suit:
activate_login
POST /users/1/activation
deactivate_login
DELETE /users/1/activation
changer le mot de passe
PUT /passwords
(cela suppose que l'utilisateur est authentifié)ajouter un crédit
POST /credits
(cela suppose que l'utilisateur est authentifié)Pour les erreurs, vous renverriez l'erreur dans le corps au format dans lequel vous avez reçu la demande, donc si vous recevez:
DELETE /users/1.xml
Vous renverriez la réponse en XML, la même chose serait vraie pour JSON etc ...
Pour l'authentification, vous devez utiliser l'authentification http.
la source
create
dans le cadre de l'URI (rappelez-vous que les URI devraient être des noms et que les méthodes HTTP devraient être des verbes qui fonctionnent sur ces noms.) Au lieu de cela, j'aurais une ressource comme celle/users/1/active
qui peut être un simple booléen, et elle peut être défini en mettant un 1 ou 0 à cette ressource.activation
sur l'URI, sauf si vous manipulez et gérez explicitement une ressource par le nom de/users/1/activation
. Que fait un GET à ce sujet? Que fait un PUT? J'ai l'impression que vous verbalisez l'URI. En outre, comme pour la négociation de type de contenu, il est souvent préférable de l'ignorer et de l'insérer dans les en-têtes, commeAccept
.la source
Je suggérerais (comme première passe) qui
PUT
ne devrait être utilisé que pour la mise à jour des entités existantes.POST
devrait être utilisé pour en créer de nouveaux. c'est à direne me semble pas juste. Cependant, le reste de votre première section (utilisation du verbe) semble logique.
la source
Verbose, mais copié à partir de la spécification de la méthode HTTP 1.1 à http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
9.3 OBTENIR
La méthode GET signifie récupérer toutes les informations (sous la forme d'une entité) identifiées par l'URI de demande. Si l'URI de demande fait référence à un processus de production de données, ce sont les données produites qui doivent être renvoyées en tant qu'entité dans la réponse et non le texte source du processus, sauf si ce texte se trouve être la sortie du processus.
La sémantique de la méthode GET devient un "GET conditionnel" si le message de demande comprend un champ d'en-tête If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match ou If-Range. Une méthode GET conditionnelle demande que l'entité soit transférée uniquement dans les circonstances décrites par le ou les champs d'en-tête conditionnels. La méthode GET conditionnelle est destinée à réduire l'utilisation inutile du réseau en permettant aux entités mises en cache d'être actualisées sans nécessiter plusieurs demandes ou transférer des données déjà détenues par le client.
La sémantique de la méthode GET passe à un "GET partiel" si le message de demande comprend un champ d'en-tête Range. Un GET partiel demande que seule une partie de l'entité soit transférée, comme décrit dans la section 14.35. La méthode GET partielle est destinée à réduire l'utilisation inutile du réseau en permettant aux entités partiellement récupérées de se terminer sans transférer les données déjà détenues par le client.
La réponse à une demande GET peut être mise en cache si et seulement si elle répond aux exigences de mise en cache HTTP décrites dans la section 13.
Voir la section 15.1.3 pour les considérations de sécurité lors de l'utilisation pour les formulaires.
9.5 POST
La méthode POST est utilisée pour demander au serveur d'origine d'accepter l'entité incluse dans la demande en tant que nouveau subordonné de la ressource identifiée par l'URI de demande dans la ligne de demande. POST est conçu pour permettre à une méthode uniforme de couvrir les fonctions suivantes:
La fonction réelle exécutée par la méthode POST est déterminée par le serveur et dépend généralement de l'URI de demande. L'entité publiée est subordonnée à cet URI de la même manière qu'un fichier est subordonné à un répertoire qui le contient, un article de presse est subordonné à un groupe de discussion auquel il est publié ou un enregistrement est subordonné à une base de données.
L'action effectuée par la méthode POST peut ne pas aboutir à une ressource qui peut être identifiée par un URI. Dans ce cas, 200 (OK) ou 204 (Pas de contenu) est le statut de réponse approprié, selon que la réponse inclut ou non une entité qui décrit le résultat.
Si une ressource a été créée sur le serveur d'origine, la réponse DEVRAIT être 201 (créée) et contenir une entité qui décrit le statut de la demande et fait référence à la nouvelle ressource, et un en-tête Location (voir section 14.30).
Les réponses à cette méthode ne peuvent pas être mises en cache, sauf si la réponse inclut des champs d'en-tête Cache-Control ou Expires appropriés. Cependant, la réponse 303 (Voir Autre) peut être utilisée pour demander à l'agent utilisateur de récupérer une ressource pouvant être mise en cache.
Les demandes POST DOIVENT respecter les exigences de transmission des messages énoncées au paragraphe 8.2.
Voir la section 15.1.3 pour des considérations de sécurité.
9.6 PUT
La méthode PUT demande que l'entité incluse soit stockée sous l'URI de demande fourni. Si l'URI de demande fait référence à une ressource déjà existante, l'entité incluse DEVRAIT être considérée comme une version modifiée de celle résidant sur le serveur d'origine. Si l'URI de demande ne pointe pas vers une ressource existante et que cet URI peut être défini comme nouvelle ressource par l'agent utilisateur demandeur, le serveur d'origine peut créer la ressource avec cet URI. Si une nouvelle ressource est créée, le serveur d'origine DOIT en informer l'agent utilisateur via la réponse 201 (créée). Si une ressource existante est modifiée, les codes de réponse 200 (OK) ou 204 (sans contenu) DEVRAIENT être envoyés pour indiquer la réussite de la demande. Si la ressource n'a pas pu être créée ou modifiée avec l'URI de demande, Une réponse d'erreur DEVRAIT être donnée qui reflète la nature du problème. Le destinataire de l'entité NE DOIT PAS ignorer les en-têtes Content- * (par exemple Content-Range) qu'il ne comprend pas ou n'implémente pas et DOIT retourner une réponse 501 (non implémentée) dans de tels cas.
Si la demande passe par un cache et que l'URI de demande identifie une ou plusieurs entités actuellement mises en cache, ces entrées DEVRAIENT être traitées comme périmées. Les réponses à cette méthode ne peuvent pas être mises en cache.
La différence fondamentale entre les requêtes POST et PUT se reflète dans la signification différente de l'URI de demande. L'URI dans une demande POST identifie la ressource qui gérera l'entité incluse. Cette ressource peut être un processus d'acceptation de données, une passerelle vers un autre protocole ou une entité distincte qui accepte les annotations. En revanche, l'URI dans une demande PUT identifie l'entité jointe à la demande - l'agent utilisateur sait quel URI est prévu et le serveur NE DOIT PAS tenter d'appliquer la demande à une autre ressource. Si le serveur souhaite que la demande soit appliquée à un URI différent,
il DOIT envoyer une réponse 301 (déplacée en permanence); l'agent utilisateur PEUT alors prendre sa propre décision concernant la redirection ou non de la demande.
Une seule ressource PEUT être identifiée par de nombreux URI différents. Par exemple, un article peut avoir un URI pour identifier "la version actuelle" qui est distincte de l'URI identifiant chaque version particulière. Dans ce cas, une demande PUT sur un URI général peut entraîner la définition de plusieurs autres URI par le serveur d'origine.
HTTP / 1.1 ne définit pas comment une méthode PUT affecte l'état d'un serveur d'origine.
Les demandes PUT DOIVENT respecter les exigences de transmission des messages énoncées au paragraphe 8.2.
Sauf indication contraire pour un en-tête d'entité particulier, les en-têtes d'entité dans la demande PUT DEVRAIENT être appliqués à la ressource créée ou modifiée par le PUT.
9.7 SUPPRIMER
La méthode DELETE demande au serveur d'origine de supprimer la ressource identifiée par l'URI de demande. Cette méthode PEUT être remplacée par une intervention humaine (ou tout autre moyen) sur le serveur d'origine. Le client ne peut pas garantir que l'opération a été effectuée, même si le code d'état renvoyé par le serveur d'origine indique que l'action s'est terminée avec succès. Cependant, le serveur NE DEVRAIT PAS indiquer de succès sauf si, au moment où la réponse est donnée, il a l'intention de supprimer la ressource ou de la déplacer vers un emplacement inaccessible.
Une réponse réussie DEVRAIT être 200 (OK) si la réponse comprend une entité décrivant l'état, 202 (Accepté) si l'action n'a pas encore été exécutée, ou 204 (Pas de contenu) si l'action a été exécutée mais la réponse ne comprend pas une entité.
Si la demande passe par un cache et que l'URI de demande identifie une ou plusieurs entités actuellement mises en cache, ces entrées DEVRAIENT être traitées comme périmées. Les réponses à cette méthode ne peuvent pas être mises en cache.
la source
À propos des codes de retour REST: il est incorrect de mélanger les codes de protocole HTTP et les résultats REST.
Cependant, j'ai vu de nombreuses implémentations les mélanger, et de nombreux développeurs peuvent ne pas être d'accord avec moi.
Les codes de retour HTTP sont liés à
HTTP Request
lui - même. Un appel REST est effectué à l'aide d'une demande de protocole de transfert hypertexte et il fonctionne à un niveau inférieur à la méthode REST invoquée elle-même. REST est un concept / une approche, et sa sortie est un résultat métier / logique , tandis que le code de résultat HTTP est un transport .Par exemple, renvoyer "404 Not found" lorsque vous appelez / users / est confus, car cela peut signifier:
"403 Interdit / Accès refusé" peut signifier:
Et la liste peut continuer avec '500 Server error "(une erreur HTTP Apache / Nginx lancée ou une erreur de contrainte métier dans REST) ou d'autres erreurs HTTP, etc.
À partir du code, il est difficile de comprendre quelle était la raison de l'échec, un échec HTTP (transport) ou un échec REST (logique).
Si la requête HTTP a été exécutée physiquement avec succès, elle doit toujours renvoyer 200 codes, quel que soit le ou les enregistrements trouvés ou non. Parce que la ressource URI est trouvée et a été gérée par le serveur http. Oui, il peut renvoyer un ensemble vide. Est-il possible de recevoir une page Web vide avec 200 comme résultat http, non?
Au lieu de cela, vous pouvez renvoyer 200 codes HTTP et simplement un JSON avec un tableau / objet vide, ou utiliser un indicateur de résultat / succès booléen pour informer sur le statut de l'opération effectuée.
De plus, certains fournisseurs d'accès Internet peuvent intercepter vos demandes et vous renvoyer un code http 404. Cela ne signifie pas que vos données ne sont pas trouvées, mais que quelque chose ne va pas au niveau du transport.
De Wiki :
la source