91 votes

Dans REST, est-ce que POST ou PUT est le mieux adapté pour l'opération upsert ?

Je garde un stockage clé-valeur dans le serveur pour le client. Si l'utilisateur envoie la clé "k1", je l'insère dans la base de données. Est-ce que cela est considéré comme POST o PUT ?

J'ai également une autre opération qui supprime toutes les clés existantes et ajoute la nouvelle clé. Est-ce que cette opération POST o PUT parce qu'il efface des enregistrements et en ajoute un nouveau.

105voto

Polly Shaw Points 2504

Si l'utilisateur envoie la clé "k1", je l'insère dans la base de données. Est-ce que cela est considéré comme POST ou PUT ?

Selon le Spécification HTTP :

La méthode PUT demande que l'entité jointe soit stockée sous l'URL de la demande fournie. Si la Request-URI fait référence à une ressource déjà existante, l'entité jointe devrait être considérée comme une version modifiée de celle qui réside sur le serveur d'origine. Si la Request-URI ne renvoie pas à une ressource existante, et que cette URI peut être définie comme une nouvelle ressource par l'agent utilisateur demandeur, le serveur d'origine peut créer la ressource avec cette URI.

Je pense donc que l'utilisation de PUT pour une insertion ou une mise à jour est parfaitement légitime, à condition que dans les deux cas l'URI soit connu à l'avance. Si vous utilisez la clé comme partie de l'URI (comme k1 dans le cas de http://www.somewhere.com/resources/k1 ), cela devrait être le cas. Cependant, pour être idéalement RESTful, un GET vers la même URL devrait également vous permettre de télécharger la ressource.

J'ai également une autre opération qui supprime toutes les clés existantes et ajoute la nouvelle clé, est-ce POST ou PUT parce qu'il efface les enregistrements et en ajoute un nouveau.

Je ne pense pas que cette opération puisse être considérée comme RESTful car elle fait deux choses. Elle semble fournir une macro pour satisfaire les besoins d'un client particulier, plutôt qu'un simple accès aux données. Une conception RESTful standard serait la suivante

  1. Obtenir une liste de clés en envoyant un GET à l'URL parent. Dans l'exemple ci-dessus, ce serait http://www.somewhere.com/resources ;
  2. Suppression de chacune de ces clés en envoyant un DELETE à http://www.somewhere.com/resources/k1 ;
  3. Ajouter le remplacement en envoyant un PUT à http://www.somewhere.com/resources/k2 .

C'est moins évident, mais je pense qu'il serait également légitime de supprimer toutes les ressources en envoyant une seule requête DELETE à l'adresse suivante http://www.somewhere.com/resources .

2voto

ecoologic Points 2748

La réponse de Polly Shaw est correcte, mais je voudrais mentionner que, étant donné que le message pourrait très probablement être incomplet (il manque l'ID lorsque la ressource n'est pas encore créée), un PATCH Le verbe serait légèrement plus correct.

https://www.rfc-editor.org/rfc/rfc5789

Il s'agit d'un réglage extrêmement fin.

2voto

Rob Henry Points 37

Si la définition d'une upsert est un mélange de nouveaux enregistrements avec des enregistrements existants (à mettre à jour).

Se référant à : https://restfulapi.net/rest-put-vs-post/

PUT doit être idempotent. Cela signifie que si vous envoyez la même charge utile une deuxième fois, l'état du système ne doit pas être modifié.

Si la charge utile prévue est un mélange de nouveaux et d'anciens enregistrements et que le comportement attendu est de créer plus de nouveaux enregistrements la deuxième fois, il semblerait que "upsert" soit plus proche de POST.

Nous nous efforçons de créer des API tolérantes aux erreurs. Si vous ne pouvez pas rendre le PUT idempotent et qu'ils doivent l'utiliser, ils pourraient corrompre le système. D'autre part, POST n'est pas censé être idempotent, donc si vous envoyez des données de mise à jour uniquement (encore et encore) dans les données utiles (même si cela viole techniquement la règle d'idempotence pour POST parce que cela ne change pas l'état du système en ajoutant des enregistrements lors des appels suivants), le système ne serait (probablement) pas corrompu.

  • La spécification indique que PUT "peut" ajouter de nouveaux éléments et "doit" être idempotent.
  • Il dit que POST "doit" ajouter de nouveaux éléments et n'est pas idempotent.

Si vous voulez vraiment mettre en œuvre un upsert, aucun des deux n'est parfait, mais si des erreurs provoquent une corruption sur PUT, l'API est à blâmer (elle est censée être idempotente) alors que la corruption sur POST est "je vous l'avais dit".

J'aime aussi penser à ce que le consommateur d'API recherchera. En général, un développeur d'interface utilisateur travaillant sur un nouvel écran cherchera à ajouter les enregistrements que l'utilisateur a ajoutés dans l'interface utilisateur. Il cherchera d'abord un POST, puis découvrira que l'API gère également le côté PUT de l'équation.

Donc, ni l'un ni l'autre, mais si vous devez choisir, choisissez POST.

2voto

Yahyaa Points 99

Selon Docs Web du MDN :

PUT

La méthode de demande HTTP PUT crée une nouvelle ressource ou remplace une représentation de la ressource cible avec les données utiles de la demande.

La différence entre PUT y POST c'est que PUT est idempotent : appeler une fois ou plusieurs fois successivement a le même effet (c'est-à-dire pas de effet secondaire), alors que des appels successifs identiques POST les demandes peuvent avoir des effets supplémentaires, comme si l'on passait une commande plusieurs fois.

Syntaxe

PUT /new.html HTTP/1.1

Exemple

Demande

PUT /new.html HTTP/1.1
Host: example.com
Content-type: text/html
Content-length: 16

<p>New File</p>

Réponses

Si la ressource cible n'a pas de représentation courante et que l'option PUT en crée une avec succès, le serveur d'origine doit alors informer l'agent utilisateur en envoyant un 201 ( Created ).

HTTP/1.1 201 Created 
Content-Location: /new.html

Si la ressource cible a bien une représentation courante et que représentation est modifiée avec succès conformément à l'état de la représentation jointe, le serveur d'origine doit envoyer soit un 200 ( OK ) ou un 204 ( No Content ) pour indiquer la réussite de la demande.

HTTP/1.1 204 No Content 
Content-Location: /existing.html

1voto

Tahsin Turkoz Points 1803

L'idée derrière l'opération upsert est que les clients disposent d'informations sur la structure des données et qu'ils décident d'envoyer des données avec une valeur clé. Le modèle de demande pour l'opération upsert est donc très similaire à l'opération update avec la clé incluse, comme dans l'exemple ci-dessous :

/customers/jimmy

La méthode attendue pour mettre à jour un enregistrement existant est PUT. Votre choix devrait donc être PUT.

POST est généralement utilisé pour insérer un nouvel enregistrement avec un tout nouveau contenu comme dans l'exemple ci-dessous :

POST /customers HTTP/1.1
Content-Type: ...
Content-Length: ...
Host: server.yourdomain.com
Accept: ...
User-Agent: ...

id      jimmy
name    jimmy
Occupation   Stackoverflower

Ainsi, dans votre cas, vous n'avez pas besoin d'une opération POST car l'opération PUT pour l'upsert couvre également cette opération.

Ici, la question cruciale concernant l'upsert est de savoir si vous pouvez faire confiance à votre client concernant l'opération upsert. Si un client souhaite insérer un nouvel enregistrement avec une clé existante, que se passe-t-il ? Dans votre cas, vous devriez traiter cette demande comme une mise à jour, car les demandes d'insertion et de mise à jour arrivent à la même API et vous avez un enregistrement existant. C'est la question à laquelle il faut répondre de votre côté concernant la conception.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X