DynamoDB BatchGetItem en Node.js (AWS SDK v3)

BatchGetItem récupère jusqu'à 100 éléments par clé primaire en une seule requête. Dans AWS SDK v3, l'appel doit être une boucle, parce que UnprocessedKeys arrive sur une réponse réussie plutôt que sur une erreur. Ce qui le remplit, et pourquoi 16 Mo et 1 Mo par partition sont les chiffres qui comptent, est couvert dans les opérations par lot dans DynamoDB. Cette page porte sur l'appel v3 et sur ce qu'il te rend.

Code

import {BatchGetItemCommand, DynamoDBClient} from '@aws-sdk/client-dynamodb';

const client = new DynamoDBClient({region: 'us-east-1'});

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

let requestItems = {
  Music: {
    Keys: [
      {Artist: {S: 'Arturo Sandoval'}, SongTitle: {S: 'Cubano Chant'}},
      {Artist: {S: 'Arturo Sandoval'}, SongTitle: {S: 'A Mis Abuelos'}},
      {Artist: {S: 'Ella Fitzgerald'}, SongTitle: {S: 'Misty'}}
    ]
  }
};

const items = [];
let attempt = 0;

do {
  const response = await client.send(new BatchGetItemCommand({RequestItems: requestItems}));
  items.push(...(response.Responses?.Music ?? []));

  // A partial result is NOT an error: throttling, a >16 MB response, or an
  // internal failure returns the leftovers in UnprocessedKeys. Retry them
  // with exponential backoff.
  requestItems = response.UnprocessedKeys;
  if (requestItems && Object.keys(requestItems).length > 0) {
    attempt += 1;
    await sleep(Math.min(100 * 2 ** attempt, 5000));
  }
} while (requestItems && Object.keys(requestItems).length > 0);

console.log(`Fetched ${items.length} items`);

Explication

  • Le chaînage optionnel n'est pas du bruit défensif. Responses et UnprocessedKeys sont tous deux optionnels dans les types v3, donc response.Responses?.Music ?? [] et la garde Object.keys() sont ce que le compilateur réclame. En JavaScript pur, ce sont eux qui empêchent la première réponse vide de lever une exception.
  • Branche sur err.name. v3 y place le code d'erreur du service, et les deux échecs que cette commande lève réellement ne sont pas réessayables : ils ne doivent donc jamais tomber dans la boucle de backoff. Plus de 100 clés donne ValidationException / Too many items requested for the BatchGetItem call ; deux fois la même clé donne Provided list of item keys contains duplicates. Les deux sont reproduits mot pour mot sur la page Python.
  • UnprocessedKeys arrive déjà à la forme de RequestItems, ce qui est la seule raison pour laquelle la boucle peut le réaffecter directement. Ce n'est pas un curseur de pagination et ça ne veut pas dire que l'appel a échoué.
  • Le backoff est une consigne d'AWS, pas une politesse. La référence de l'API te dit d'utiliser "an exponential backoff algorithm" parce qu'une reprise immédiate retombe sur la même partition throttlée.
  • ConsistentRead et ProjectionExpression se règlent par table, à l'intérieur de chaque entrée de RequestItems et non au niveau supérieur. C'est facile à manquer quand la map n'a qu'une clé et ressemble à une requête plate.

Ce que la réponse renvoie vraiment

Exécute le bloc ci-dessus contre DynamoDB Local 3.3.0 avec les trois morceaux présents, ajoute ReturnConsumedCapacity: 'TOTAL', et journalise les titres au lieu du compte :

order:            [ 'A Mis Abuelos', 'Misty', 'Cubano Chant' ]
UnprocessedKeys:  {}
ConsumedCapacity: [ { TableName: 'Music', CapacityUnits: 1.5 } ]

La requête listait Cubano Chant, A Mis Abuelos, Misty. La réponse n'est dans aucune de ces positions, et c'est pour ça que la boucle empile dans un tableau plat au lieu d'indexer par décalage. Fais correspondre les éléments aux requêtes sur leurs attributs de clé, et inclus ces clés dans toute ProjectionExpression pour qu'il te reste de quoi les rapprocher.

Mets ConsistentRead: true sur cette même entrée Music et les trois mêmes clés coûtent 3 unités au lieu de 1,5. Trois éléments de moins de 4 Ko chacun sont facturés comme trois lectures GetItem distinctes, à une demi-unité en cohérence à terme et une unité pleine en lecture fortement cohérente. Le calculateur de tarifs traduit cette arithmétique par élément en montant mensuel avant que tu ne t'engages sur un modèle de lecture.

Supprime maintenant Misty et relance : deux éléments, un UnprocessedKeys vide, et 1,0 unité. La clé manquante n'a rien été facturée. C'est un artefact de DynamoDB Local et non le contrat ; la référence BatchGetItem (récupérée le 2026-07-28) indique que les requêtes portant sur des éléments inexistants consomment la capacité de lecture minimale correspondant au type de lecture. Ne dimensionne pas un lot de cache misses à partir d'une exécution locale.

Pour récupérer un jeu de clés et regarder ce qui est réellement revenu, sans écrire la boucle d'abord, télécharge DynoTable.

Exemples liés

Références

Dernière vérification le 2026-07-28 par rapport à la documentation officielle AWS liée ci-dessus.

Travaille avec DynamoDB sans la Console

Un client de bureau rapide pour DynamoDB qui exécute le vrai SQL que DynamoDB ne peut pas — JOINs, GROUP BY, agrégations — avec édition visuelle et un agent IA sur tes propres clés Bedrock.

Essai gratuit de 30 jours, sans carte bancaire — ensuite la formule Gratuit, sans limite de durée.