Intermédiaire4 min de lecture

DynamoDB ReturnValues : récupérer l'ancien ou le nouvel item depuis une écriture

Par défaut, une écriture DynamoDB ne renvoie rien d'autre que le succès. Mais tu as souvent besoin des données autour de l'écriture — la valeur avant ta modification, ou la valeur fraîche après. Le réflexe naïf, c'est un second GetItem, qui est un aller-retour supplémentaire et une course : quelqu'un d'autre peut écrire entre les deux. DynamoDB évite les deux avec le paramètre ReturnValues, qui te renvoie l'ancien ou le nouvel item de façon atomique dans l'écriture elle-même.

Que fait ReturnValues dans DynamoDB ?

ReturnValues indique à une opération d'écriture DynamoDB de renvoyer l'item dans le même appel, ce qui évite un second GetItem et la course aux données qu'il crée. PutItem et DeleteItem acceptent NONE ou ALL_OLD ; UpdateItem accepte les cinq options (NONE, ALL_OLD, UPDATED_OLD, ALL_NEW, UPDATED_NEW), renvoyant les valeurs anciennes ou nouvelles de façon atomique.

  • ReturnValues renvoie l'item dans le cadre de l'écriture — pas de seconde lecture, pas de course.
  • NONE (par défaut) — ne renvoie rien.
  • ALL_OLD — l'item entier tel qu'il était avant l'écriture.
  • UPDATED_OLD — uniquement les attributs que la mise à jour a changés, valeurs d'avant.
  • ALL_NEW — l'item entier après l'écriture.
  • UPDATED_NEW — uniquement les attributs changés, valeurs d'après.
  • PutItem/DeleteItem n'acceptent que NONE ou ALL_OLD ; UpdateItem accepte les cinq.

Le problème : tu as besoin de la valeur que tu viens d'écraser

Disons que tu gères un service de support et qu'un agent fait passer le statut d'un ticket de open à pending. Ton journal d'audit doit consigner ce qu'était le statut avant le changement. Sans ReturnValues, tu ferais :

  1. GetItem pour lire le statut actuel,
  2. UpdateItem pour fixer le nouveau.

Entre les étapes 1 et 2, un autre agent pourrait changer le statut — et maintenant ton journal d'audit consigne une valeur « avant » périmée. Pire, ce sont deux appels pour une seule opération logique. ReturnValues réduit ça à un unique UpdateItem atomique qui renvoie l'ancien statut tel qu'il était réellement au moment de l'écriture.

Les cinq options, et quand utiliser chacune

UpdateItem prend en charge tout l'éventail ; le choix porte sur quelle tranche de l'item et quel côté de l'écriture tu veux :

ReturnValuesRenvoieÀ utiliser quand
NONErientu n'as pas besoin de récupérer l'item (par défaut)
ALL_OLDitem entier, avant écritureaudit / « qu'est-ce que je viens de remplacer ? »
UPDATED_OLDattrs changés, avant écritureseuls comptent les champs que tu as touchés
ALL_NEWitem entier, après écrituretu dois renvoyer l'item complet et frais à un appelant
UPDATED_NEWattrs changés, après écriturerelire un compteur/une valeur que tu viens d'incrémenter

UPDATED_NEW est le héros du quotidien : incrémente un compteur avec une expression de mise à jour et relis le nouveau total dans le même appel, sans course. Pour l'audit du ticket de support, ALL_OLD (ou UPDATED_OLD si tu ne consignes que le champ statut) capture l'état d'avant changement de façon atomique.

Note l'asymétrie : PutItem et DeleteItem ne prennent en charge que NONE et ALL_OLD — il n'y a pas de « nouvelle » valeur à renvoyer pour un delete, et la nouvelle valeur d'un put est simplement ce que tu as envoyé. Seul UpdateItem, qui modifie sur place, offre les cinq. AWS documente la matrice exacte.

Écrire la mise à jour dans DynoTable

Assemble l'UpdateItem et son expression de mise à jour visuellement avec le constructeur d'expressions DynamoDB — il émet la clause SET/ADD plus les maps de noms et de valeurs d'attributs. Dans l'application, DynoTable montre l'item résultant après la validation d'une écriture en attente, donc tu vois le nouvel état directement.

Revue d'un changement préparé sur un item dans DynoTable — les anciennes et nouvelles valeurs avant que la mise à jour ne soit validée.
Revue d'un changement préparé sur un item dans DynoTable — les anciennes et nouvelles valeurs avant que la mise à jour ne soit validée.

Pièges et étapes suivantes

  • Ne fais pas GetItem-puis-écriture pour lire autour d'un changement — c'est un aller-retour et une course ; utilise ReturnValues.
  • UPDATED_* ne renvoie que les attributs touchés — s'il te faut l'item entier, utilise ALL_*.
  • PutItem/DeleteItem ne peuvent pas renvoyer de nouvelles valeurs — seulement NONE/ALL_OLD.
  • ReturnValues n'est pas un substitut à une condition — pour protéger une écriture, ajoute une expression de condition ; pour en relire l'effet, utilise ReturnValues. Elles se composent.
  • À voir aussi : expressions de mise à jour, compteurs atomiques.

Envie de faire des modifications et de voir l'avant/après sans scripter deux appels ? Télécharge DynoTable et édite tes items directement.

Mis à jour