web-dev-qa-db-fra.com

REST API - pourquoi utiliser PUT DELETE POST GET?

Je parcourais donc des articles sur la création d'API REST. Certains suggèrent d'utiliser tous les types de requêtes HTTP: comme PUTDELETEPOSTGET. Nous créerions par exemple index.php et écririons l'API de cette manière:

$method = $_SERVER['REQUEST_METHOD'];
$request = split("/", substr(@$_SERVER['PATH_INFO'], 1));

switch ($method) {
  case 'PUT':
    ....some put action.... 
    break;
  case 'POST':
    ....some post action.... 
    break;
  case 'GET':
    ....some get action.... 
    break;
  case 'DELETE':
    ....some delete action.... 
    break;
}

OK, d'accord - je ne connais pas (encore) beaucoup de services Web. Mais, ne serait-il pas plus facile d’accepter simplement [~ # ~] json [~ # ~] objet par le biais de POST ou GET (ce qui contient le nom de la méthode et tous les paramètres), puis répond également en JSON. Nous pouvons facilement sérialiser/désérialiser via les fonctions json_encode() et json_decode() de PHP et faire ce que nous voulons avec ces données sans avoir à traiter avec différentes méthodes de requête HTTP.

Est-ce que je manque quelque chose?

UPDATE 1:

Ok - après avoir exploré diverses API et appris beaucoup de choses sur XML-RPC, JSON-RPC, [~ # ~] soap [~ # ~], [~ # ~] reste [~ # ~] J'ai conclu que ce type d'API est valable. En fait, stack exchange utilise à peu près cette approche sur leurs sites et je pense que ces personnes savent ce qu’elles font API Stack Exchange .

148
Stann

L'idée de présentation State Tle transfert ne consiste pas à accéder aux données de la manière la plus simple possible.

Vous avez suggéré d'utiliser des demandes de publication pour accéder à JSON, ce qui est un moyen parfaitement valide d'accéder/de manipuler des données.

REST est une méthodologie pour un accès significatif aux données. Lorsque vous voyez une demande dans REST, vous devez immédiatement savoir ce qui se passe avec les données.

Par exemple:

GET: /cars/make/chevrolet

est susceptible de renvoyer une liste de voitures chevy. Une bonne REST api pourrait même incorporer des options de sortie dans la chaîne de requête comme ?output=json ou ?output=html qui permettrait à l’accesseur de choisir le format dans lequel l’information devrait être codée.

Après avoir réfléchi à la manière d’incorporer raisonnablement le typage de données dans une API REST), j’ai conclu que le meilleur moyen de spécifier explicitement le type de données serait via l’extension de fichier déjà existante telle que comme .js, .json, .html, ou .xml. Une extension de fichier manquante serait définie par défaut sur le format par défaut (JSON, par exemple); une extension de fichier non prise en charge peut renvoyer un 501 Not Implemented code d'état .

Un autre exemple:

POST: /cars/
{ make:chevrolet, model:malibu, colors:[red, green, blue, grey] }

est susceptible de créer un nouveau malibu Chevy dans la base de données avec les couleurs associées. Je dis probablement car REST api n'a pas besoin d'être directement lié à la structure de la base de données. Il s'agit simplement d'un interface de masquage pour que les vraies données soient protégées (pensez-y comme des accesseurs et des mutateurs pour une structure de base de données).

Nous devons maintenant passer à la question de idempotence . Généralement REST implémente CRUD sur HTTP. HTTP utilise GET, PUT, POST et DELETE pour les requêtes.

Une implémentation très simpliste de REST pourrait utiliser le mappage CRUD suivant:

Create -> Post
Read   -> Get
Update -> Put
Delete -> Delete

Il existe un problème avec cette implémentation: Post est définie comme une méthode non idempotente. Cela signifie que les appels ultérieurs de la même méthode Post entraîneront des états de serveur différents . Get, Put et Delete sont idempotents; ce qui signifie que les appeler plusieurs fois devrait aboutir à un état de serveur identique.

Cela signifie qu'une demande telle que:

Delete: /cars/oldest

pourrait effectivement être implémenté comme:

Post: /cars/oldest?action=delete

Tandis que

Delete: /cars/id/123456

entraînera le même état de serveur si vous l’appelez une fois, ou si vous l’appelez 1000 fois.

Une meilleure façon de gérer la suppression de l'élément oldest serait de demander:

Get: /cars/oldest

et utilisez le ID parmi les données résultantes pour faire une requête delete:

Delete: /cars/id/[oldest id]

Un problème avec cette méthode serait si un autre /cars l'article a été ajouté entre le moment où /oldest a été demandé et quand le delete a été émis.

195
zzzzBov

C'est une question de sécurité et de maintenabilité.

méthodes sûres

Dans la mesure du possible, vous devez utiliser des méthodes "sûres" (unidirectionnelles) telles que GET et HEAD) afin de limiter la vulnérabilité potentielle.

méthodes idempotentes

Dans la mesure du possible, vous devez utiliser des méthodes "idempotentes" telles que GET, HEAD, PUT et DELETE, qui ne peuvent pas avoir d’effets secondaires et sont donc moins sujettes aux erreurs/plus faciles à contrôler.

Source

38
markus

En bref, REST met l'accent sur les noms plutôt que sur les verbes. Au fur et à mesure que votre API devient plus complexe, vous ajoutez plus d'éléments, plutôt que davantage de commandes.

24
Neil

Vous avez demandé:

ne serait-il pas plus facile d'accepter simplement un objet JSON via $ _POST normal, puis de répondre en JSON aussi

Un article de Wikipédia sur RESTE :

Les applications RESTful optimisent l'utilisation de l'interface prédéfinie bien définie et des autres fonctionnalités intégrées fournies par le protocole réseau choisi, tout en minimisant l'ajout de nouvelles fonctionnalités spécifiques à l'application.

D'après ce (peu) que j'ai vu, je pense que cela est généralement accompli en maximisant l'utilisation des verbes HTTP existants et en concevant un schéma d'URL pour votre service qui soit aussi puissant et évident que possible.

Les protocoles de données personnalisés (même s’ils reposent sur des protocoles standard, tels que SOAP ou JSON) sont déconseillés et doivent être réduits au minimum pour une meilleure conformité à l’idéologie REST.

SOAP RPC sur HTTP, d’autre part, encourage chaque concepteur d’application à définir un nouveau vocabulaire arbitraire composé de noms et de verbes (par exemple, getUsers (), savePurchaseOrder (...)), généralement superposés au verbe HTTP 'POST'. Cela néglige de nombreuses fonctionnalités HTTP existantes, telles que l'authentification, la mise en cache et la négociation du type de contenu, et peut laisser le concepteur de l'application réinventer nombre de ces fonctionnalités dans le nouveau vocabulaire.

Les objets avec lesquels vous travaillez peuvent être dans n'importe quel format. L'idée est de réutiliser le plus possible le protocole HTTP pour exposer les opérations que l'utilisateur souhaite effectuer sur ces ressources (requêtes, gestion d'état/mutation, suppression).

Vous avez demandé:

Est-ce que je manque quelque chose?

Il y a encore beaucoup à apprendre sur REST et sur la syntaxe URI/les verbes HTTP eux-mêmes. Par exemple, certains verbes sont idempotents, d'autres non. Je n'ai rien vu à ce sujet dans votre question, donc je ne me suis pas donné la peine d'essayer de plonger dedans. Les autres réponses et Wikipedia contiennent beaucoup d'informations intéressantes.

En outre, il vous reste beaucoup à apprendre sur les différentes technologies réseau construites sur HTTP que vous pouvez exploiter si vous utilisez une API réellement reposante. Je commencerais par l'authentification.

9

En ce qui concerne l'utilisation de l'extension pour définir le type de données. J'ai remarqué que l'API MailChimp le fait, mais je ne pense pas que ce soit une bonne idée.

GET /zzz/cars.json/1

GET /zzz/cars.xml/1

Mon son semble être une bonne idée, mais j'estime qu'une approche "plus ancienne" est préférable: utiliser des en-têtes HTTP.

GET /xxx/cars/1
Accept: application/json

De plus, les en-têtes HTTP sont bien meilleurs pour la communication entre types de données (si jamais quelqu'un en avait besoin)

POST /zzz/cars
Content-Type: application/xml     <--- indicates we sent XML to server
Accept: application/json          <--- indicates we want get data back in JSON format  
8
Pawel Cioch

Est-ce que je manque quelque chose?

Oui. ;-)

Ce phénomène existe à cause de = contrainte d'interface uniforme . REST aime utiliser des normes existantes au lieu de réinventer la roue. La norme HTTP s'est déjà avérée très évolutive (le Web fonctionne depuis un moment). Pourquoi devrions-nous réparer quelque chose qui n'est pas endommagé? ?!

Remarque: La contrainte d'interface uniforme est importante si vous souhaitez découpler les clients du service. Cela revient à définir des interfaces pour les classes afin de les découpler les unes des autres. Ofc. ici l'interface uniforme est constituée de normes telles que HTTP , types MIME , URI , RDF , vocabs de données liées , hydra vocab , etc. .

4
inf3rno

Une bonne sémantique est importante dans la programmation.

Utiliser plus de méthodes que GET/POST sera utile car cela augmentera la lisibilité de votre code et facilitera sa maintenance.

Pourquoi?

Parce que vous savez que GET va récupérer les données de votre API. Vous savez que POST ajoutera de nouvelles données à votre système. Vous savez que PUT effectuera des mises à jour. DELETE supprimera des lignes, etc., etc.

Normalement, je structure mes services Web RESTFUL de manière à avoir une fonction de rappel nommée de la même manière que la méthode.

J'utilise PHP, donc j'utilise function_exists (je pense que c'est appelé). Si la fonction n'existe pas, je lance un 405 (METHODE NON AUTORISE).

1
HumbleWebDev

Bill Venners: Dans votre billet de blog intitulé "Pourquoi REST a échoué", vous avez dit que nous avions besoin des quatre verbes HTTP —GET, POST, PUT et DELETE— et a déploré que les constructeurs de navigateurs seulement GET et POST. "Pourquoi avons-nous besoin des quatre verbes? Pourquoi GET et POST ne suffisent-ils pas?)

Elliotte Rusty Harold: Il existe quatre méthodes de base dans HTTP: GET, POST, PUT et DELETE. GET est utilisé la plupart du temps. Il est utilisé pour tout ce qui est en sécurité, qui ne provoque aucun effet secondaire. GET peut être mis en signet, mis en cache, lié à, transmis via un serveur proxy. C'est une opération très puissante, très utile.

POST en revanche est peut-être l'opération la plus puissante. Il peut faire n'importe quoi. Il n'y a pas de limites à ce qui peut arriver et, en conséquence, il faut être très prudent avec cela. Vous ne le marquez pas. Vous ne le cachez pas. Vous ne le pré-récupérez pas. Vous ne faites rien avec un POST sans demander à l'utilisateur. Voulez-vous le faire? Si l'utilisateur appuie sur le bouton, vous pouvez POST certains contenu, mais vous n’allez pas regarder tous les boutons d’une page et commencer à les presser de manière aléatoire. En revanche, les navigateurs peuvent regarder tous les liens de la page et les pré-extraire, ou pré-extraire ceux qu’ils pensent. En fait, certains navigateurs et extensions Firefox ainsi que divers autres outils ont essayé de le faire à un moment ou à un autre.

PUT et DELETE sont au milieu entre GET et POST. La différence entre PUT ou DELETE et POST est que PUT et DELETE sont * idempotent, alors que POST n'est pas. PUT et DELETE peuvent être répétés si nécessaire. Disons vous essayez de créer une nouvelle page sur http://www.example.com/foo.html , vous devez donc taper votre contenu et vous le mettez à cette URL. Le serveur crée cette page à cette URL que vous fournissez. Supposons maintenant que, pour une raison quelconque, votre connexion réseau est défaillante. Vous n'êtes pas sûr si la demande a été acheminée ou non? Il y avait peut-être un problème avec le serveur proxy. Il est donc parfaitement correct de l'essayer à nouveau, autant de fois que vous le souhaitez, car placer le même document à la même adresse URL dix fois ne sera pas différent de le placer une fois. Il en va de même pour DELETE: vous pouvez supprimer quelque chose dix fois, ce qui revient à le supprimer une fois.

En revanche, POST peut provoquer à chaque fois quelque chose de différent. Imaginez que vous visitez une boutique en ligne en appuyant sur le bouton d'achat. Si vous envoyez à nouveau cette demande POST, vous risquez d'acheter tout ce qui se trouve dans votre panier une seconde fois. Si vous l'envoyez à nouveau, vous l'achetez une troisième fois. C'est pourquoi les navigateurs doivent faites très attention à ne pas répéter les opérations POST sans le consentement explicite de l'utilisateur, car POST peut entraîner deux événements si vous le faites deux fois, trois si vous le faites Avec PUT et DELETE, il y a une grande différence entre zéro demande et une demande, mais il n'y a pas de différence entre une demande et dix.

Veuillez visiter l'URL pour plus de détails. http://www.artima.com/lejava/articles/why_put_and_delete.html

Mise à jour:

Méthodes idempotentes Une méthode HTTP idempotente est une méthode HTTP qui peut être appelée plusieurs fois sans résultat différent. Peu importe que la méthode soit appelée une fois ou dix fois. Le résultat devrait être le même. Encore une fois, cela ne s'applique qu'au résultat, pas à la ressource elle-même. Cela peut toujours être manipulé (comme un horodatage de mise à jour, à condition que ces informations ne soient pas partagées dans la représentation des ressources (actuelle).

Considérez les exemples suivants:

a = 4;

a ++;

Le premier exemple est idempotent: peu importe le nombre de fois que nous exécuterons cette instruction, a sera toujours égal à 4. Le deuxième exemple n'est pas idempotent. L'exécution de ces 10 fois donnera un résultat différent de celui de 5 fois. Puisque les deux exemples changent la valeur de a, les deux méthodes ne sont pas sûres.

1
Bimal Das

Fondamentalement REST est ( wiki ):

  1. Architecture client-serveur
  2. Apatridie
  3. Cachéabilité
  4. Système en couches
  5. Code sur demande (optionnel)
  6. Interface uniforme

REST n'est pas un protocole, ce sont des principes. Différentes méthodes et méthodes - quelqu'un de ce qu'on appelle les meilleures pratiques.

0
M-A-X