DynamoDB ReturnValues : ancien ou nouvel item
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.
ReturnValuesrenvoie 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/DeleteItemn'acceptent queNONEouALL_OLD;UpdateItemaccepte 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 :
GetItempour lire le statut actuel,UpdateItempour 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 :
ReturnValues | Renvoie | À utiliser quand |
|---|---|---|
NONE | rien | tu n'as pas besoin de récupérer l'item (par défaut) |
ALL_OLD | item entier, avant écriture | audit / « qu'est-ce que je viens de remplacer ? » |
UPDATED_OLD | attrs changés, avant écriture | seuls comptent les champs que tu as touchés |
ALL_NEW | item entier, après écriture | tu dois renvoyer l'item complet et frais à un appelant |
UPDATED_NEW | attrs changés, après écriture | relire 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.

Pièges + étapes suivantes
- Ne fais pas
GetItem-puis-écriture pour lire autour d'un changement — c'est un aller-retour et une course ; utiliseReturnValues. UPDATED_*ne renvoie que les attributs touchés — s'il te faut l'item entier, utiliseALL_*.PutItem/DeleteItemne peuvent pas renvoyer de nouvelles valeurs — seulementNONE/ALL_OLD.ReturnValuesn'est pas un substitut à une condition — pour protéger une écriture, ajoute une expression de condition ; pour en relire l'effet, utiliseReturnValues. 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.
Compteur atomique avec UPDATED_NEW
Les systèmes d'inventaire incrémentent un champ version ou stock à chaque écriture. Le motif est un UpdateItem avec ADD stock :inc et ReturnValues: UPDATED_NEW :
UpdateItem PK=SKU#8842
UpdateExpression: ADD stock :one
ExpressionAttributeValues: {":one": {"N": "1"}}
ReturnValues: UPDATED_NEW
→ Attributes.stock.N == "41" (was 40)Tu reçois seulement la map d'attributs changés, pas l'item entier — idéal quand l'item est gros mais que l'appelant a besoin du nouveau compteur. Pour des pistes d'audit qui doivent capturer chaque champ avant le changement, passe à ALL_OLD.
L'écriture se facture toujours comme un UpdateItem sur la taille de l'item ; ReturnValues n'ajoute pas de charge de lecture séparée — DynamoDB a déjà chargé l'item pour appliquer la mise à jour.
Note sur la capacité
Renvoyer des attributs ne double pas le coût WCU de l'écriture elle-même. Tu paies pour l'écriture selon la taille de l'item avant et après la mise à jour d'après les règles AWS, indépendamment du nombre d'attributs qui apparaissent dans le payload de réponse.
Si tu étais tenté de faire GetItem puis UpdateItem pour journaliser l'ancienne valeur, tu as payé une lecture plus une écriture. ReturnValues: ALL_OLD sur l'update retire complètement la lecture — sur un item de 2 Ko à 500 updates par seconde, ça économise environ 250 RCU/s à cohérence à terme.
Composer avec les expressions de condition
ReturnValues et les
expressions de condition se composent sur le même appel. Exemple : incrémenter retryCount seulement tant qu'il est sous un plafond, et renvoyer le nouveau compte :
ConditionExpression: retryCount < :max
UpdateExpression: ADD retryCount :one
ReturnValues: UPDATED_NEWSi la condition échoue, DynamoDB renvoie ConditionalCheckFailedException et aucun payload d'attribut — distinct d'un update réussi avec un UPDATED_NEW vide quand rien n'a changé.
Utilise l'expression builder pour générer ensemble l'UpdateExpression, la condition et les maps de valeurs marshallées.
Guide de décision
| Tu as besoin de… | Réglage | Marche sur |
|---|---|---|
| Rien en retour | NONE | Put, Update, Delete |
| Item entier avant overwrite/delete | ALL_OLD | Put, Update, Delete |
| Seulement les champs changés, avant | UPDATED_OLD | Update |
| Item entier après patch | ALL_NEW | Update |
| Seulement les champs changés, après | UPDATED_NEW | Update |
Deletes et puts
DeleteItem avec ReturnValues: ALL_OLD est comment tu implémentes une sémantique « pop et retourne » sur un item de file — la ligne supprimée revient dans Attributes. Il n'y a pas de ALL_NEW sur delete parce que l'item n'existe plus.
PutItem avec ALL_OLD renvoie l'item précédent quand tu écrases une clé existante — utile pour les workflows de swap. Quand la clé n'existait pas, la réponse omet Attributes.
Vérifier dans DynoTable
Prépare un changement d'attribut dans l'éditeur d'item : le panneau de revue montre les anciennes et nouvelles valeurs côte à côte avant le commit — la même information que UPDATED_OLD et UPDATED_NEW renverraient, sans écrire un script. Après commit, copie la ligne en JSON pour des fixtures de test via les actions d'export de la grille.


