

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Node.js et DAX
<a name="DAX.client.run-application-nodejs-3"></a>

# Configuration du client par défaut pour Node.js
<a name="DAX-client-config-JS"></a>

Lors de la configuration du client DAX JavaScript SDK, vous pouvez personnaliser divers paramètres pour optimiser les performances, la gestion des connexions et la résilience aux erreurs. Le tableau suivant décrit les paramètres de configuration par défaut qui contrôlent la manière dont votre client interagit avec le cluster DAX, notamment les valeurs de délai d’expiration, les mécanismes de nouvelle tentative, la gestion des informations d’identification et les options de surveillance de l’état de santé. Pour plus d'informations, consultez [Dynamo DBClient Operations](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/).


**Paramètres par défaut du kit SDK JS DAX**  

| Paramètre | Type | Description | 
| --- | --- | --- | 
|  `region` facultatif  |  `string`  |   Région AWS À utiliser pour le client DAX (exemple : « us-east-1 »). Il s’agit d’un paramètre obligatoire s’il n’est pas fourni par la variable d’environnement.  | 
|  `endpoint` obligatoire  |  `string`  | Point de terminaison du cluster auquel le kit SDK se connecte. Exemples : Non crypté — .region.amazonaws.com dax-cluster-name Chiffré : dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com  | 
|  `requestTimeout` Par défaut : 6 000 ms  |  `number`  | Cela définit le temps maximum pendant lequel le client attend une réponse de DAX.  | 
|  `writeRetries` Par défaut : 1  |  `number`  | Nombre de nouvelles tentatives pour des demandes d’écriture qui ont échoué.  | 
|  `readRetries` Par défaut : 1  |  `number`  | Nombre de nouvelles tentatives pour des demandes de lecture qui ont échoué.  | 
|  `maxRetries` Par défaut : 1  |  `number`  | Nombre maximal de nouvelles tentatives en cas d’échec des demandes. S' readRetries/writeRetries ils sont définis, la configuration définie dans ReadRetries et WriteRetries a priorité sur MaxRetries.  | 
|  `connectTimeout` Par défaut : 10 000 ms  |  `number`  | Délai (en millisecondes) pour établir une connexion à l’un des nœuds du cluster.  | 
|  `maxConcurrentConnections` Par défaut : 100  |  `number`  | Limite le nombre total de connexions simultanées qu’une instance client peut créer par nœud dans un cluster DAX.  | 
|  `maxRetryDelay` Par défaut : 7 000 ms  |  `number`  | Lorsque le serveur DAX indique qu’une récupération est nécessaire en définissant l’indicateur `waitForRecoveryBeforeRetrying` sur true, le client fait une pause avant de réessayer. Pendant ces périodes de récupération, le paramètre `maxRetryDelay` détermine le temps d’attente maximal entre les tentatives. Cette configuration spécifique à la récupération s’applique uniquement lorsque le serveur DAX est en mode récupération. Pour tous les autres scénarios, le comportement des nouvelles tentatives suit l’un des deux modèles suivants : soit un délai exponentiel basé sur le nombre de tentatives (régi par les paramètres `writeRetries`, `readRetries` ou `maxRetries`), soit une nouvelle tentative immédiate en fonction du type d’exception.  | 
|  `credentials` facultatif  |  `[AwsCredentialIdentity](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-credential-providers/)` \$1 `[AwsCredentialIdentityProvider](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-credential-providers/)`  |  Les AWS informations d'identification à utiliser pour authentifier les demandes. Cela peut être fourni sous forme de AwsCredentialIdentity ou de AwsCredentialIdentityProvider. Si ces paramètres ne sont pas fournis, le kit SDK AWS utilisera automatiquement la chaîne du fournisseur d’informations d’identification par défaut. Exemple : `\$1 accessKeyId: 'AKIA... ' , secretAccessKey : ' ... ', SessionToken :'... '\$1 `\$1 @default Utilise la chaîne de fournisseurs d'informations d'identification AWS par défaut.  | 
|  `healthCheckInterval` Par défaut : 5 000 ms  |  `number`  | Intervalle (en millisecondes) entre les surveillances de l’état du cluster. Un intervalle inférieur permet d’effectuer des surveillances plus fréquentes.  | 
|  `healthCheckTimeout` Par défaut : 1 000 ms  |  `number`  | Délai (en millisecondes) nécessaire à l’exécution de la surveillance de l’état.  | 
|  `skipHostnameVerification` Par défaut : false  |  `boolean`  |  Ignore la vérification du nom d’hôte des connexions TLS. Cela n’a aucun impact sur les clusters non chiffrés. Par défaut, la vérification du nom d’hôte est effectuée. Si vous définissez ce paramètre sur True, la vérification sera ignorée. Assurez-vous de bien comprendre les conséquences de sa désactivation, à savoir l’impossibilité d’authentifier le cluster auquel vous vous connectez.   | 
|  `unhealthyConsecutiveErrorCount` Par défaut : 5  |  `number`  | Définit le nombre d’erreurs consécutives nécessaires pour signaler un nœud défectueux pendant l’intervalle de surveillance de l’état.  | 
|  `clusterUpdateInterval` Par défaut : 4 000 ms  |  `number`  | Renvoie l’intervalle entre les interrogations des membres du cluster pour les modifications d’appartenance.  | 
|  `clusterUpdateThreshold` Par défaut : 125  |  `number`  | Renvoie le seuil en dessous duquel le cluster ne sera pas interrogé pour les modifications d’appartenance.  | 
|  `credentailProvider` facultatif \$1 null par défaut  |  `[AwsCredentialIdentityProvider](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-credential-providers/)`  | Fournisseur défini par l'utilisateur pour les AWS informations d'identification utilisées pour authentifier les demandes adressées au DAX.  | 


**Configuration de pagination pour DaxDocument**  

| Nom | Type | Détail | 
| --- | --- | --- | 
|  `client`  |  DaxDocument  |  Instance de DaxDocument type.  | 
|  `pageSize`  |  number  |  Détermine le nombre d’éléments par page.  | 
|  `startingToken` Facultatif  |  any  |  LastEvaluatedKey La réponse précédente peut être utilisée pour les demandes suivantes.  | 

Pour plus d’informations sur l’utilisation de la pagination, consultez [TryDax.js](DAX.client.tutorial-TryDax.md).

# Migration vers le kit SDK Node.js DAX V3
<a name="DAX.client.run-application-nodejs-3-migrating"></a>

Ce guide de migration vous aidera à effectuer la transition de vos applications Node.js DAX existantes. Le nouveau kit SDK nécessite Node.js 18 ou une version ultérieure et introduit plusieurs modifications importantes dans la manière dont vous allez structurer votre code DynamoDB Accelerator. Ce guide vous expliquera les principales différences, notamment les modifications de syntaxe, les nouvelles méthodes d’importation et les modèles de programmation asynchrone mis à jour.

## Utilisation de Node.js DAX V2
<a name="DAX.client.run-application-nodejs-3-migrating-V2-usage"></a>

```
const AmazonDaxClient = require('amazon-dax-client');
const AWS = require('aws-sdk');

var region = "us-west-2";

AWS.config.update({
  region: region,
});

var client = new AWS.DynamoDB.DocumentClient();

if (process.argv.length > 2) {
  var dax = new AmazonDaxClient({
    endpoints: [process.argv[2]],
    region: region,
  });
  client = new AWS.DynamoDB.DocumentClient({ service: dax });
}

// Make Get Call using Dax
var params = {
    TableName: 'TryDaxTable',
    pk: 1,
    sk: 1
}
client.get(params, function (err, data) {
    if (err) {
        console.error(
            "Unable to read item. Error JSON:",
            JSON.stringify(err, null, 2)
          );
    } else {
        console.log(data);
    }
});
```

## Utilisation de Node.js DAX V3
<a name="DAX.client.run-application-nodejs-3-migrating-V3-dax-usage"></a>

Concernant l’utilisation de DAX Node.js V3, la version 18 ou supérieure est la version préférée. Pour passer à Node 18, utilisez les éléments suivants :

```
import { DaxDocument } from '@amazon-dax-sdk/lib-dax';
import { DynamoDBDocument } from '@aws-sdk/lib-dynamodb';
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';

let client: DynamoDBDocument | DaxDocument = DynamoDBDocument.from(
  new DynamoDBClient({ region: 'us-west-2' })
);

if (process.argv.length > 2) {
  client = new DaxDocument({
    endpoints: [process.argv[2]],
    region: 'us-west-2',
  });
}

const params = {
  TableName: 'TryDaxTable',
  Key: { pk: 1, sk: 1 },
};

try {
  const results = await client.get(params);
  console.log(results);
} catch (err) {
  console.error(err);
}
```

Le kit SDK DAX pour Node.js v3.x est compatible avec [l’AWS SDK pour Node.js v3.x](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/introduction/). Le kit SDK DAX pour Node.js v3.x prend en charge l’utilisation de clients [regroupés](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/introduction/#high-level-concepts). Notez que DAX ne prend pas en charge la création de clients bone. Pour plus de détails sur les fonctionnalités non prises en charge, consultez [Fonctionnalités non comparables à celles du AWS SDK V3](#DAX.client.run-application-nodejs-3-not-in-parity).

Pour exécuter l’exemple d’application Node.js sur votre instance Amazon EC2, procédez comme suit.

**Pour exécuter l’exemple Node.js pour DAX**

1. Configurez Node.js sur votre instance Amazon EC2, comme suit :

   1. Installez le gestionnaire de version de nœud (`nvm`).

      ```
      curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
      ```

   1. Utilisez nvm pour installer Node.js.

      ```
      nvm install 18
      ```

   1. Utilisez nvm pour l’utilisation de Node 18

      ```
      nvm use 18
      ```

   1. Testez que Node.js est installé et fonctionne correctement.

      ```
      node -e "console.log('Running Node.js ' + process.version)"
      ```

      Le message suivant doit s’afficher.

      `Running Node.js v18.x.x`

1. Installez le client DaxDocument Node.js à l'aide du gestionnaire de packages de nœuds (`npm`).

   ```
   npm install @amazon-dax-sdk/lib-dax
   ```

## TryDax exemple de code
<a name="DAX.client.run-application-nodejs-3-TryDax-sample-code"></a>

Pour évaluer les avantages en matière de performances de DynamoDB Accelerator (DAX), procédez comme suit pour exécuter un exemple de test qui compare les temps de lecture entre DynamoDB standard et un cluster DAX.

1. Après avoir configuré votre espace de travail et installé `lib-dax` en tant que dépendance, copiez [TryDax.js](DAX.client.tutorial-TryDax.md) dans votre projet.

1. Exécutez le programme sur votre cluster DAX. Pour déterminer le point de terminaison de votre cluster DAX, choisissez l’une des options suivantes : 
   +  **Utilisation de la console DynamoDB** – Choisissez votre cluster DAX. Le point de terminaison du cluster s’affiche dans la console, comme dans l’exemple suivant.

     ```
     dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com
     ```
   + **À l'aide** de AWS CLI— Entrez la commande suivante.

     ```
     aws dax describe-clusters --query "Clusters[*].ClusterDiscoveryEndpoint"
     ```

     Le point de terminaison du cluster apparaît dans la sortie, comme dans l’exemple suivant.

     ```
     {
         "Address": "my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com",
         "Port": 8111,
         "URL": "dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com"
     }
     ```

1. À présent, exécutez le programme en spécifiant le point de terminaison de cluster comme paramètre de ligne de commande.

   ```
   node TryDax.js dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com
   ```

   Vous devez voir des résultats similaires à ce qui suit :

   ```
   Attempting to create table; please wait...
   Successfully created table. Table status: ACTIVE
   Writing data to the table...
   Writing 20 items for partition key:  1
   Writing 20 items for partition key:  2
   Writing 20 items for partition key:  3
   ...
   Running GetItem Test
           Total time: 153555.10 µs - Avg time: 383.89 µs
           Total time: 44679.96 µs - Avg time: 111.70 µs
           Total time: 36885.86 µs - Avg time: 92.21 µs
           Total time: 32467.25 µs - Avg time: 81.17 µs
           Total time: 32202.60 µs - Avg time: 80.51 µs
   Running Query Test
           Total time: 14869.25 µs - Avg time: 2973.85 µs
           Total time: 3036.31 µs - Avg time: 607.26 µs
           Total time: 2468.92 µs - Avg time: 493.78 µs
           Total time: 2062.53 µs - Avg time: 412.51 µs
           Total time: 2178.22 µs - Avg time: 435.64 µs
   Running Scan Test
           Total time: 2395.88 µs - Avg time: 479.18 µs
           Total time: 2207.16 µs - Avg time: 441.43 µs
           Total time: 2443.14 µs - Avg time: 488.63 µs
           Total time: 2038.24 µs - Avg time: 407.65 µs
           Total time: 1972.17 µs - Avg time: 394.43 µs
   Running Pagination Test
   Scan Pagination
   [
     { pk: 1, sk: 1, someData: 'XXXXXXXXXX' },
     { pk: 1, sk: 2, someData: 'XXXXXXXXXX' },
     { pk: 1, sk: 3, someData: 'XXXXXXXXXX' }
   ]
   [
     { pk: 1, sk: 4, someData: 'XXXXXXXXXX' },
     { pk: 1, sk: 5, someData: 'XXXXXXXXXX' },
     { pk: 1, sk: 6, someData: 'XXXXXXXXXX' }
   ]
   ...
   Query Pagination
   [
     { pk: 1, sk: 1, someData: 'XXXXXXXXXX' },
     { pk: 1, sk: 2, someData: 'XXXXXXXXXX' },
     { pk: 1, sk: 3, someData: 'XXXXXXXXXX' }
   ]
   [
     { pk: 1, sk: 4, someData: 'XXXXXXXXXX' },
     { pk: 1, sk: 5, someData: 'XXXXXXXXXX' },
     { pk: 1, sk: 6, someData: 'XXXXXXXXXX' }
   ]
   ...
   Attempting to delete table; please wait...
   Successfully deleted table.
   ```

   Notez les informations relatives à la durée, c’est-à-dire le nombre de microsecondes requis pour les tests `GetItem`, `Query` et `Scan`.

1. Dans ce cas, vous avez exécuté les programmes sur le cluster DAX. Vous allez maintenant réexécuter le programme mais, cette fois, sur DynamoDB.

1. À présent, réexécutez le programme mais, cette fois, sans l’URL du point de terminaison du cluster en tant que paramètre de ligne de commande.

   ```
   node TryDax.js
   ```

   Examinez la sortie et notez les informations de durée. Les délais écoulés pour `GetItem`, `Query` et `Scan` devraient être sensiblement inférieurs avec DAX par rapport à DynamoDB.

## Fonctionnalités non comparables à celles du AWS SDK V3
<a name="DAX.client.run-application-nodejs-3-not-in-parity"></a>
+ Clients [bone](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/introduction/#high-level-concepts) : Dax Node.js V3 ne prend pas en charge les clients élémentaires. 

  ```
  const dynamoDBClient = new DynamoDBClient({ region: 'us-west-2' });
  const regularParams = {
      TableName: 'TryDaxTable',
      Key: {
          pk: 1,
          sk: 1
      }
  };
  // The DynamoDB client supports the send operation.
  const dynamoResult = await dynamoDBClient.send(new GetCommand(regularParams));
  
  // However, the DaxDocument client does not support the send operation.
  const daxClient = new DaxDocument({
      endpoints: ['your-dax-endpoint'],
      region: 'us-west-2',
  });
  
  const params = {
      TableName: 'TryDaxTable',
      Key: {
          pk: 1,
          sk: 1
      }
  };
  
  // This will throw an error - send operation is not supported for DAX. Please refer to documentation.
  const result = await daxClient.send(new GetCommand(params));
  console.log(result);
  ```
+ [Pile d’intergiciel](https://aws.amazon.com/blogs/developer/middleware-stack-modular-aws-sdk-js/) : Dax Node.js V3 ne prend pas en charge l’utilisation des fonctions d’intergiciel.

  ```
  const dynamoDBClient = new DynamoDBClient({ region: 'us-west-2' });
  // The DynamoDB client supports the middlewareStack.
  dynamoDBClient.middlewareStack.add(
    (next, context) =>> async (args) => {
      console.log("Before operation:", args);
      const result = await next(args);
      console.log("After operation:", result);
      return result;
    },
    {
      step: "initialize", // or "build", "finalizeRequest", "deserialize"
      name: "loggingMiddleware",
    }
  );
  
  // However, the DaxDocument client does not support the middlewareStack.
  const daxClient = new DaxDocument({
      endpoints: ['your-dax-endpoint'],
      region: 'us-west-2',
  });
  
  // This will throw an error - custom middleware and middlewareStacks are not supported for DAX. Please refer to documentation.
  daxClient.middlewareStack.add(
    (next, context) => async (args) => {
      console.log("Before operation:", args);
      const result = await next(args);
      console.log("After operation:", result);
      return result;
    },
    {
      step: "initialize", // or "build", "finalizeRequest", "deserialize"
      name: "loggingMiddleware",
    }
  );
  ```

# TryDax.js
<a name="DAX.client.tutorial-TryDax"></a>

```
import { DynamoDB, waitUntilTableExists, waitUntilTableNotExists } from "@aws-sdk/client-dynamodb";
import { DaxDocument, daxPaginateScan, daxPaginateQuery } from "@amazon-dax-sdk/lib-dax";
import { DynamoDBDocument, paginateQuery, paginateScan } from "@aws-sdk/lib-dynamodb";

const region = "us-east-1";
const tableName = "TryDaxTable";

// Determine the client (DynamoDB or DAX)
let client = DynamoDBDocument.from(new DynamoDB({ region }));
if (process.argv.length > 2) {
  client = new DaxDocument({ region, endpoint: process.argv[2] });
}

// Function to create table
async function createTable() {
  const dynamodb = new DynamoDB({ region });
  const params = {
    TableName: tableName,
    KeySchema: [
      { AttributeName: "pk", KeyType: "HASH" },
      { AttributeName: "sk", KeyType: "RANGE" },
    ],
    AttributeDefinitions: [
      { AttributeName: "pk", AttributeType: "N" },
      { AttributeName: "sk", AttributeType: "N" },
    ],
    ProvisionedThroughput: { ReadCapacityUnits: 25, WriteCapacityUnits: 25 },
  };

  try {
    console.log("Attempting to create table; please wait...");
    await dynamodb.createTable(params);
    await waitUntilTableExists({ client: dynamodb, maxWaitTime: 30 }, { TableName: tableName });
    console.log("Successfully created table. Table status: ACTIVE");
  } catch (err) {
    console.error("Error in table creation:", err);
  }
}

// Function to insert data
async function writeData() {
  console.log("Writing data to the table...");
  const someData = "X".repeat(10);
  for (let ipk = 1; ipk <= 20; ipk++) {
    console.log("Writing 20 items for partition key: ", ipk)
    for (let isk = 1; isk <= 20; isk++) {
      try {
        await client.put({ TableName: tableName, Item: { pk: ipk, sk: isk, someData } });
      } catch (err) {
        console.error("Error inserting data:", err);
      }
    }
  }
}

// Function to test GetItem
async function getItemTest() {
  console.log("Running GetItem Test");
  for (let i = 0; i < 5; i++) {
    const startTime = performance.now();
    const promises = [];
    for (let ipk = 1; ipk <= 20; ipk++) {
      for (let isk = 1; isk <= 20; isk++) {
        promises.push(client.get({ TableName: tableName, Key: { pk: ipk, sk: isk } }));
      }
    }
    await Promise.all(promises);
    const endTime = performance.now();
    const iterTime = (endTime - startTime) * 1000;
    const totalTime = iterTime.toFixed(2).padStart(3, ' ');
    const avgTime = (iterTime / 400).toFixed(2).padStart(3, ' ');
    console.log(`\tTotal time: ${totalTime} \u00B5s - Avg time: ${avgTime} \u00B5s`);
  }
}

// Function to test Query
async function queryTest() {
  console.log("Running Query Test");
  for (let i = 0; i < 5; i++) {
    const startTime = performance.now();
    const promises = [];
    for (let pk = 1; pk <= 5; pk++) {
      const params = {
        TableName: tableName,
        KeyConditionExpression: "pk = :pkval and sk between :skval1 and :skval2",
        ExpressionAttributeValues: { ":pkval": pk, ":skval1": 1, ":skval2": 2 },
      };
      promises.push(client.query(params));
    }
    await Promise.all(promises);
    const endTime = performance.now();
    const iterTime = (endTime - startTime) * 1000;
    const totalTime = iterTime.toFixed(2).padStart(3, ' ');
    const avgTime = (iterTime / 5).toFixed(2).padStart(3, ' ');
    console.log(`\tTotal time: ${totalTime} \u00B5s - Avg time: ${avgTime} \u00B5s`);
  }
}

// Function to test Scan
async function scanTest() {
  console.log("Running Scan Test");
  for (let i = 0; i < 5; i++) {
    const startTime = performance.now();
    const promises = [];
    for (let pk = 1; pk <= 5; pk++) {
      const params = {
        TableName: tableName,
        FilterExpression: "pk = :pkval and sk between :skval1 and :skval2",
        ExpressionAttributeValues: { ":pkval": pk, ":skval1": 1, ":skval2": 2 },
      };
      promises.push(client.scan(params));
    }
    await Promise.all(promises);
    const endTime = performance.now();
    const iterTime = (endTime - startTime) * 1000;
    const totalTime = iterTime.toFixed(2).padStart(3, ' ');
    const avgTime = (iterTime / 5).toFixed(2).padStart(3, ' ');
    console.log(`\tTotal time: ${totalTime} \u00B5s - Avg time: ${avgTime} \u00B5s`);
  }
}

// Function to test Pagination
async function paginationTest() {
  console.log("Running Pagination Test");
  console.log("Scan Pagination");
  const scanParams = { TableName: tableName };
  const paginator = process.argv.length > 2 ? daxPaginateScan : paginateScan;
  for await (const page of paginator({ client, pageSize: 3 }, scanParams)) {
    console.log(page.Items);
  }

  console.log("Query Pagination");
  const queryParams = {
    TableName: tableName,
    KeyConditionExpression: "pk = :pkval and sk between :skval1 and :skval2",
    ExpressionAttributeValues: { ":pkval": 1, ":skval1": 1, ":skval2": 10 },
  };
  const queryPaginator = process.argv.length > 2 ? daxPaginateQuery : paginateQuery;
  for await (const page of queryPaginator({ client, pageSize: 3 }, queryParams)) {
    console.log(page.Items);
  }
}

// Function to delete the table
async function deleteTable() {
  const dynamodb = new DynamoDB({ region });
  console.log("Attempting to delete table; please wait...")
  try {
    await dynamodb.deleteTable({ TableName: tableName });
    await waitUntilTableNotExists({ client: dynamodb, maxWaitTime: 30 }, { TableName: tableName });
    console.log("Successfully deleted table.");
  } catch (err) {
    console.error("Error deleting table:", err);
  }
}

// Execute functions sequentially
(async function () {
  await createTable();
  await writeData();
  await getItemTest();
  await queryTest();
  await scanTest();
  await paginationTest();
  await deleteTable();
})();
```