

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.

# Programmation avec DynamoDB et le AWS SDKs
<a name="Programming"></a>

Cette section contient des rubriques destinées aux développeurs. Si vous voulez plutôt exécuter des exemples de code, consultez [Exécution des exemples de code du Guide du développeur](CodeSamples.md). 

**Note**  
En décembre 2017, le processus de migration de tous les points de terminaison Amazon DynamoDB AWS a débuté afin d'utiliser des certificats sécurisés émis par Amazon Trust Services (ATS). Pour de plus amples informations, veuillez consulter [Résolution des problèmes d'établissement de SSL/TLS connexion avec DynamoDB](ats-certs.md). 

**Topics**
+ [Présentation de la prise en charge du AWS SDK pour DynamoDB](Programming.SDKOverview.md)
+ [Programmation d’Amazon DynamoDB avec Python et Boto3](programming-with-python.md)
+ [Programmation d'Amazon DynamoDB avec JavaScript](programming-with-javascript.md)
+ [Programmation de DynamoDB avec AWS SDK for Java 2.x](ProgrammingWithJava.md)
+ [Gestion des erreurs avec DynamoDB](Programming.Errors.md)
+ [Utilisation de DynamoDB avec un SDK AWS](sdk-general-information-section.md)

# Présentation de la prise en charge du AWS SDK pour DynamoDB
<a name="Programming.SDKOverview"></a>

Le schéma suivant fournit une présentation générale de la programmation d'applications Amazon DynamoDB à l'aide du. AWS SDKs

![\[Modèle de programmation pour utiliser DynamoDB avec. AWS SDKs\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/SDKSupport.png)


1. Vous écrivez une application à l'aide d'un AWS SDK pour votre langage de programmation.

1. Chaque AWS SDK fournit une ou plusieurs interfaces de programmation permettant d'utiliser DynamoDB. Les interfaces spécifiques disponibles dépendent du langage de programmation et du AWS SDK que vous utilisez. Voici les options :
   + [Interfaces de bas niveau compatibles avec DynamoDB](Programming.SDKs.Interfaces.md#Programming.SDKs.Interfaces.LowLevel)
   + [Interfaces de document compatibles avec DynamoDB](Programming.SDKs.Interfaces.md#Programming.SDKs.Interfaces.Document)
   + [Interfaces de persistance d’objets compatibles avec DynamoDB](Programming.SDKs.Interfaces.md#Programming.SDKs.Interfaces.Mapper)
   + [Interfaces de haut niveau](HigherLevelInterfaces.md)

1. Le AWS SDK crée des requêtes HTTP (S) à utiliser avec l'API DynamoDB de bas niveau.

1. Le AWS SDK envoie la demande au point de terminaison DynamoDB.

1. DynamoDB exécute la demande. Si la demande aboutit, DynamoDB renvoie un code de réponse HTTP 200 (OK). Si la demande échoue, DynamoDB renvoie un code d’erreur HTTP et un message d’erreur.

1. Le AWS SDK traite la réponse et la retransmet à votre application.

Chacun d'entre eux AWS SDKs fournit des services importants à votre application, notamment les suivants :
+ Mise en forme des demandes HTTP(S) et sérialisation des paramètres de demande.
+ Génération d’une signature de chiffrement pour chaque demande.
+ Transfert des demandes vers un point de terminaison DynamoDB et réception des réponses de DynamoDB.
+ Extraction des résultats de ces réponses.
+ Implémentation d’une logique de nouvelle tentative de base en cas d’erreurs.

Vous n’avez besoin d’écrire de code pour aucune de ces tâches.

**Note**  
Pour plus d'informations AWS SDKs, y compris les instructions d'installation et la documentation, consultez la section [Outils pour Amazon Web Services](https://aws.amazon.com/tools).

## Support du SDK pour les terminaux basés sur des AWS comptes
<a name="Programming.SDKs.endpoints"></a>

AWS déploie la prise en charge du SDK pour les AWS points de terminaison basés sur un compte pour DynamoDB, en commençant par le SDK pour AWS Java V1 le 4 septembre 2024. Ces nouveaux terminaux contribuent AWS à garantir des performances et une évolutivité élevées. La mise à jour SDKs utilisera automatiquement les nouveaux points de terminaison, qui ont le format`https://(account-id).ddb.(region).amazonaws.com`.

Si vous utilisez une seule instance d’un client SDK pour envoyer des demandes à plusieurs comptes, votre application aura moins de possibilités de réutiliser les connexions. AWS recommande de modifier vos applications afin de vous connecter à un moins grand nombre de comptes par instance client SDK. Une autre solution consiste à configurer votre client SDK pour qu'il continue à utiliser les points de terminaison régionaux à l'aide du `ACCOUNT_ID_ENDPOINT_MODE` paramètre, comme indiqué dans le guide de [https://docs.aws.amazon.com/sdkref/latest/guide/feature-account-endpoints.html](https://docs.aws.amazon.com/sdkref/latest/guide/feature-account-endpoints.html).

# Interfaces de programmation compatibles avec DynamoDB
<a name="Programming.SDKs.Interfaces"></a>

Chaque [kit SDK AWS](https://aws.amazon.com/tools) fournit une ou plusieurs interfaces de programmation utilisables avec Amazon DynamoDB. Ces interfaces vont de simples encapsuleurs DynamoDB de bas niveau à des couches de persistance orientées objet. Les interfaces disponibles varient en fonction du AWS SDK et du langage de programmation que vous utilisez.

![\[Différentes interfaces de programmation sont disponibles AWS SDKs pour travailler avec DynamoDB.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/SDKSupport.SDKInterfaces.png)


La section suivante met en évidence certaines des interfaces disponibles, en utilisant l’ AWS SDK pour Java en guise d’exemple (Toutes les interfaces ne sont pas toutes disponibles AWS SDKs.)

**Topics**
+ [Interfaces de bas niveau compatibles avec DynamoDB](#Programming.SDKs.Interfaces.LowLevel)
+ [Interfaces de document compatibles avec DynamoDB](#Programming.SDKs.Interfaces.Document)
+ [Interfaces de persistance d’objets compatibles avec DynamoDB](#Programming.SDKs.Interfaces.Mapper)

## Interfaces de bas niveau compatibles avec DynamoDB
<a name="Programming.SDKs.Interfaces.LowLevel"></a>

Chaque AWS SDK spécifique à un langage fournit une interface de bas niveau pour Amazon DynamoDB, avec des méthodes qui ressemblent étroitement aux requêtes d'API DynamoDB de bas niveau.

Dans certains cas, vous devrez identifier les types de données des attributs en utilisant des [Descripteurs de type de données](Programming.LowLevelAPI.md#Programming.LowLevelAPI.DataTypeDescriptors), tels que `S` pour String (chaîne) ou `N` pour Number (nombre).

**Note**  
Une interface de bas niveau est disponible dans chaque kit SDK  AWS spécifique d’un langage.

Le programme Java suivant utilise l’interface de bas niveau de l’ AWS SDK pour Java. 

### Exemple d’interface de bas niveau
<a name="low-level-example"></a>

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.GetItemRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 *
 * To get an item from an Amazon DynamoDB table using the AWS SDK for Java V2,
 * its better practice to use the
 * Enhanced Client, see the EnhancedGetItem example.
 */
public class GetItem {
    public static void main(String[] args) {
        final String usage = """

                Usage:
                    <tableName> <key> <keyVal>

                Where:
                    tableName - The Amazon DynamoDB table from which an item is retrieved (for example, Music3).\s
                    key - The key used in the Amazon DynamoDB table (for example, Artist).\s
                    keyval - The key value that represents the item to get (for example, Famous Band).
                """;

        if (args.length != 3) {
            System.out.println(usage);
            System.exit(1);
        }

        String tableName = args[0];
        String key = args[1];
        String keyVal = args[2];
        System.out.format("Retrieving item \"%s\" from \"%s\"\n", keyVal, tableName);
        Region region = Region.US_EAST_1;
        DynamoDbClient ddb = DynamoDbClient.builder()
                .region(region)
                .build();

        getDynamoDBItem(ddb, tableName, key, keyVal);
        ddb.close();
    }

    public static void getDynamoDBItem(DynamoDbClient ddb, String tableName, String key, String keyVal) {
        HashMap<String, AttributeValue> keyToGet = new HashMap<>();
        keyToGet.put(key, AttributeValue.builder()
                .s(keyVal)
                .build());

        GetItemRequest request = GetItemRequest.builder()
                .key(keyToGet)
                .tableName(tableName)
                .build();

        try {
            // If there is no matching item, GetItem does not return any data.
            Map<String, AttributeValue> returnedItem = ddb.getItem(request).item();
            if (returnedItem.isEmpty())
                System.out.format("No item found with the key %s!\n", key);
            else {
                Set<String> keys = returnedItem.keySet();
                System.out.println("Amazon DynamoDB table attributes: \n");
                for (String key1 : keys) {
                    System.out.format("%s: %s\n", key1, returnedItem.get(key1).toString());
                }
            }

        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
}
```

## Interfaces de document compatibles avec DynamoDB
<a name="Programming.SDKs.Interfaces.Document"></a>

Beaucoup AWS SDKs proposent une interface documentaire qui vous permet d'effectuer des opérations de plan de données (création, lecture, mise à jour, suppression) sur les tables et les index. Avec une interface de document, vous n’avez pas besoin de spécifier [Descripteurs de type de données](Programming.LowLevelAPI.md#Programming.LowLevelAPI.DataTypeDescriptors). Les types de données découlent de la sémantique des données proprement dites. Ils fournissent AWS SDKs également des méthodes permettant de convertir facilement des documents JSON vers et depuis des types de données Amazon DynamoDB natifs.

**Note**  
Les interfaces de document sont disponibles dans [Java](https://aws.amazon.com/sdk-for-java), [.NET](https://aws.amazon.com/sdk-for-net), [Node.js](https://aws.amazon.com/sdk-for-node-js) et [JavaScriptSDK](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/). AWS SDKs 

Le programme Java suivant utilise l’interface de document de l’ AWS SDK pour Java. Le programme crée un objet `Table` qui représente la table `Music`, puis demande à cet objet d’utiliser `GetItem` pour extraire une chanson. Le programme affiche ensuite l’année de sortie de la chanson.

La classe `software.amazon.dynamodb.document.DynamoDB` implémente l’interface de document de DynamoDB. Observez la manière dont `DynamoDB` agit en tant qu’encapsuleur autour du client de bas niveau (`AmazonDynamoDB`).

### Exemple d’interface de document
<a name="document-level-example"></a>

```
package com.amazonaws.codesamples.gsg;

import software.amazon.dynamodb.AmazonDynamoDB;
import software.amazon.dynamodb.AmazonDynamoDBClientBuilder;
import software.amazon.dynamodb.document.DynamoDB;
import software.amazon.dynamodb.document.GetItemOutcome;
import software.amazon.dynamodb.document.Table;

public class MusicDocumentDemo {

    public static void main(String[] args) {

        AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
        DynamoDB docClient = new DynamoDB(client);

        Table table = docClient.getTable("Music");
        GetItemOutcome outcome = table.getItemOutcome(
                "Artist", "No One You Know",
                "SongTitle", "Call Me Today");

        int year = outcome.getItem().getInt("Year");
        System.out.println("The song was released in " + year);

    }
}
```

## Interfaces de persistance d’objets compatibles avec DynamoDB
<a name="Programming.SDKs.Interfaces.Mapper"></a>

Certains AWS SDKs proposent une interface de persistance des objets dans laquelle vous n'effectuez pas directement d'opérations sur le plan de données. Au lieu de cela, vous créez des objets représentant des éléments dans des tables et index Amazon DynamoDB, et interagissez uniquement avec ces objets. Cela vous permet d’écrire du code orienté objet plutôt que du code orienté base de données.

**Note**  
Les interfaces de persistance des objets sont disponibles AWS SDKs pour Java et .NET. Pour plus d’informations, consultez [Interfaces de programmation de niveau supérieur pour DynamoDB](HigherLevelInterfaces.md) pour DynamoDB.

### Exemple d’interface de persistance des objets
<a name="mapper-level-example"></a>

```
import com.example.dynamodb.Customer;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.Key;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.enhanced.dynamodb.model.GetItemEnhancedRequest;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
```

```
import com.example.dynamodb.Customer;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.Key;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.enhanced.dynamodb.model.GetItemEnhancedRequest;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;

/*
 * Before running this code example, create an Amazon DynamoDB table named Customer with these columns:
 *   - id - the id of the record that is the key. Be sure one of the id values is `id101`
 *   - custName - the customer name
 *   - email - the email value
 *   - registrationDate - an instant value when the item was added to the table. These values
 *                        need to be in the form of `YYYY-MM-DDTHH:mm:ssZ`, such as 2022-07-11T00:00:00Z
 *
 * Also, ensure that you have set up your development environment, including your credentials.
 *
 * For information, see this documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */

public class EnhancedGetItem {
    public static void main(String[] args) {
        Region region = Region.US_EAST_1;
        DynamoDbClient ddb = DynamoDbClient.builder()
                .region(region)
                .build();

        DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
                .dynamoDbClient(ddb)
                .build();

        getItem(enhancedClient);
        ddb.close();
    }

    public static String getItem(DynamoDbEnhancedClient enhancedClient) {
        Customer result = null;
        try {
            DynamoDbTable<Customer> table = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));
            Key key = Key.builder()
                    .partitionValue("id101").sortValue("tred@noserver.com")
                    .build();

            // Get the item by using the key.
            result = table.getItem(
                    (GetItemEnhancedRequest.Builder requestBuilder) -> requestBuilder.key(key));
            System.out.println("******* The description value is " + result.getCustName());

        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
        return result.getCustName();
    }
}
```

# Interfaces de programmation de niveau supérieur pour DynamoDB
<a name="HigherLevelInterfaces"></a>

Ils AWS SDKs fournissent aux applications des interfaces de bas niveau pour travailler avec Amazon DynamoDB. Ces classes et méthodes côté client correspondent directement à l'API DynamoDB de bas niveau. Cependant, de nombreux développeurs sont confrontés à un sentiment de déconnexion ou à une *discordance d'impédance* quand ils doivent mapper des types de données complexes à des éléments dans une table de base de données. Avec une interface de base de données de bas niveau, les développeurs doivent écrire des méthodes pour lire ou écrire des données d'objet dans des tables de base de données, et inversement. La quantité de code supplémentaire requise pour chaque combinaison de type d'objet et de table de base de données peut sembler écrasante.

Pour simplifier le développement, les interfaces AWS SDKs pour Java et .NET fournissent des interfaces supplémentaires avec des niveaux d'abstraction plus élevés. Les interfaces de niveau supérieur pour DynamoDB vous permettent de définir les relations entre les objets dans votre programme et les tables de base de données qui stockent les données de ces objets. Après avoir défini ce mappage, vous appelez des méthodes d'objet simples telles que `save`, `load` ou `delete`, et les opérations DynamoDB de bas niveau sous-jacentes sont appelées automatiquement pour vous. Cela vous permet d'écrire du code orienté objet plutôt que du code orienté base de données.

Les interfaces de programmation de niveau supérieur pour DynamoDB sont disponibles pour Java et .NET. AWS SDKs 

**Java**
+ [Java 1.x : Dynamo DBMapper](DynamoDBMapper.md)
+ [Java 2.x : client amélioré DynamoDB](DynamoDBEnhanced.md)

**.NET**
+ [Utilisation du modèle de document .NET dans DynamoDB](DotNetSDKMidLevel.md)
+ [Utilisation du modèle de persistance des objets .NET et de DynamoDB](DotNetSDKHighLevel.md)

# Java 1.x : Dynamo DBMapper
<a name="DynamoDBMapper"></a>

**Note**  
Le kit SDK pour Java est disponible en deux versions : 1.x et 2.x. Le end-of-support for 1.x a été [annoncé](https://aws.amazon.com/blogs/developer/announcing-end-of-support-for-aws-sdk-for-java-v1-x-on-december-31-2025/) le 12 janvier 2024. Il le sera et end-of-support doit être remis le 31 décembre 2025. Pour les nouveaux développements, nous vous recommandons vivement d’utiliser la version 2.x.

 AWS SDK pour Java fournit une `DynamoDBMapper` classe qui vous permet de mapper vos classes côté client aux tables Amazon DynamoDB. Pour utiliser `DynamoDBMapper`, vous définissez la relation entre éléments d’une table DynamoDB et leurs instances d’objet correspondantes dans votre code. La classe `DynamoDBMapper` vous permet d’effectuer diverses opérations de création, de lecture, de mise à jour et de suppression (opérations CRUD) sur des éléments, ainsi que d’exécuter des requêtes et analyses sur des tables.

**Topics**
+ [Classe Dynamo DBMapper](DynamoDBMapper.Methods.md)
+ [Types de données pris en charge pour Dynamo DBMapper pour Java](DynamoDBMapper.DataTypes.md)
+ [Annotations Java pour DynamoDB](DynamoDBMapper.Annotations.md)
+ [Paramètres de configuration facultatifs pour Dynamo DBMapper](DynamoDBMapper.OptionalConfig.md)
+ [DynamoDB et verrouillage optimiste avec numéro de version](DynamoDBMapper.OptimisticLocking.md)
+ [Mappage des données arbitraires dans DynamoDB](DynamoDBMapper.ArbitraryDataMapping.md)
+ [Exemples DynamoDBMapper](DynamoDBMapper.Examples.md)

**Note**  
La classe `DynamoDBMapper` ne vous permet pas de créer, de mettre à jour ou de supprimer des tables. Pour effectuer ces tâches, utilisez plutôt l’interface du kit SDK de bas niveau pour Java.

Le kit SDK pour Java fournit un ensemble de types d’annotations qui vous permettent de mapper vos classes à des tables. Par exemple, imaginons une table `ProductCatalog` ayant `Id` en tant que clé de partition. 

```
ProductCatalog(Id, ...)
```

Vous pouvez mapper une classe de votre application client à la table `ProductCatalog`, comme illustré dans le code Java suivant. Cet exemple de code définit un objet Java ancien brut (Plain Old Java Object, POJO) nommé `CatalogItem` qui utilise des annotations pour mapper des champs d’objet à des noms d’attribut DynamoDB.

**Example**  

```
package com.amazonaws.codesamples;

import java.util.Set;

import software.amazon.dynamodb.datamodeling.DynamoDBAttribute;
import software.amazon.dynamodb.datamodeling.DynamoDBHashKey;
import software.amazon.dynamodb.datamodeling.DynamoDBIgnore;
import software.amazon.dynamodb.datamodeling.DynamoDBTable;

@DynamoDBTable(tableName="ProductCatalog")
public class CatalogItem {

    private Integer id;
    private String title;
    private String ISBN;
    private Set<String> bookAuthors;
    private String someProp;

    @DynamoDBHashKey(attributeName="Id")
    public Integer getId() { return id; }
    public void setId(Integer id) {this.id = id; }

    @DynamoDBAttribute(attributeName="Title")
    public String getTitle() {return title; }
    public void setTitle(String title) { this.title = title; }

    @DynamoDBAttribute(attributeName="ISBN")
    public String getISBN() { return ISBN; }
    public void setISBN(String ISBN) { this.ISBN = ISBN; }

    @DynamoDBAttribute(attributeName="Authors")
    public Set<String> getBookAuthors() { return bookAuthors; }
    public void setBookAuthors(Set<String> bookAuthors) { this.bookAuthors = bookAuthors; }

    @DynamoDBIgnore
    public String getSomeProp() { return someProp; }
    public void setSomeProp(String someProp) { this.someProp = someProp; }
}
```

Dans le code précédent, l’annotation `@DynamoDBTable` mappe la classe `CatalogItem` à la table `ProductCatalog`. Vous pouvez stocker des instances de classe individuelles en tant qu’éléments dans la table. Dans la définition de classe, l’annotation `@DynamoDBHashKey` mappe l’`Id` de propriété à la clé primaire. 

Par défaut, les propriétés de classe mappent avec les mêmes attributs de nom dans la table. Les propriétés `Title` et `ISBN` mappent avec les mêmes attributs de nom dans la table. 

L’annotation `@DynamoDBAttribute` est facultative si le nom de l’attribut DynamoDB correspond au nom de la propriété déclarée dans la classe. Si les noms diffèrent, utilisez cette annotation avec le paramètre `attributeName` pour spécifier l’attribut DynamoDB auquel cette propriété correspond. 

Dans l’exemple précédent, l’annotation `@DynamoDBAttribute` est ajoutée à chaque propriété afin de garantir que les noms de propriété correspondent exactement aux tables créées au cours d’une étape précédente et d’assurer la cohérence avec les noms d’attributs utilisés dans d’autres exemples de code dans ce guide. 

Votre définition de classe peut avoir des propriétés qui ne mappent avec aucun attribut de la table. Vous identifiez ces propriétés en ajoutant l’annotation `@DynamoDBIgnore`. Dans l’exemple précédent, la propriété `SomeProp` est marquée avec l’annotation `@DynamoDBIgnore`. Lorsque vous téléchargez une instance `CatalogItem` vers la table, votre instance `DynamoDBMapper` n’inclut pas de propriété `SomeProp`. En outre, l’outil de mappage ne retourne pas cet attribut lorsque vous récupérez un élément de la table. 

Une fois que vous avez défini votre classe de mappage, vous pouvez utiliser des méthodes `DynamoDBMapper` pour écrire une instance de cette classe d’un élément correspondant dans la table `Catalog`. L’exemple de code suivant illustre cette technique.

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();

DynamoDBMapper mapper = new DynamoDBMapper(client);

CatalogItem item = new CatalogItem();
item.setId(102);
item.setTitle("Book 102 Title");
item.setISBN("222-2222222222");
item.setBookAuthors(new HashSet<String>(Arrays.asList("Author 1", "Author 2")));
item.setSomeProp("Test");

mapper.save(item);
```

L’exemple de code suivant montre comment récupérer l’élément et accéder à certains de ses attributs :

```
CatalogItem partitionKey = new CatalogItem();

partitionKey.setId(102);
DynamoDBQueryExpression<CatalogItem> queryExpression = new DynamoDBQueryExpression<CatalogItem>()
    .withHashKeyValues(partitionKey);

List<CatalogItem> itemList = mapper.query(CatalogItem.class, queryExpression);

for (int i = 0; i < itemList.size(); i++) {
    System.out.println(itemList.get(i).getTitle());
    System.out.println(itemList.get(i).getBookAuthors());
}
```

`DynamoDBMapper` offre un moyen intuitif, naturel d’utiliser des données DynamoDB dans Java. Il offre aussi différentes fonctionnalités intégrées telles que le verrouillage optimiste, les transactions ACID, les valeurs de clé de tri et de clé de partition générées automatiquement et la gestion des versions d’objet.

# Classe Dynamo DBMapper
<a name="DynamoDBMapper.Methods"></a>



La classe `DynamoDBMapper` est le point d’entrée d’Amazon DynamoDB. Elle donne accès à un point de terminaison DynamoDB et vous permet d’accéder à vos données dans différentes tables. Elle vous permet également d’effectuer diverses opérations de création, de lecture, de mise à jour et de suppression (opérations CRUD) sur des éléments, ainsi que d’exécuter des requêtes et analyses sur des tables. Cette classe fournit les méthodes suivantes utiliser DynamoDB.

*Pour consulter la documentation Javadoc correspondante, consultez [Dynamo DBMapper](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapper.html) dans le manuel de référence des AWS SDK pour Java API.*

**Topics**
+ [enregistrer](#DynamoDBMapper.Methods.save)
+ [charge](#DynamoDBMapper.Methods.load)
+ [supprimer](#DynamoDBMapper.Methods.delete)
+ [query](#DynamoDBMapper.Methods.query)
+ [queryPage](#DynamoDBMapper.Methods.queryPage)
+ [scan](#DynamoDBMapper.Methods.scan)
+ [scanPage](#DynamoDBMapper.Methods.scanPage)
+ [parallelScan](#DynamoDBMapper.Methods.parallelScan)
+ [batchSave](#DynamoDBMapper.Methods.batchSave)
+ [batchLoad](#DynamoDBMapper.Methods.batchLoad)
+ [batchDelete](#DynamoDBMapper.Methods.batchDelete)
+ [batchWrite](#DynamoDBMapper.Methods.batchWrite)
+ [transactionWrite](#DynamoDBMapper.Methods.transactionWrite)
+ [transactionLoad](#DynamoDBMapper.Methods.transactionLoad)
+ [count](#DynamoDBMapper.Methods.count)
+ [generateCreateTableDemande](#DynamoDBMapper.Methods.generateCreateTableRequest)
+ [createS3Link](#DynamoDBMapper.Methods.createS3Link)
+ [Obtient S3 ClientCache](#DynamoDBMapper.Methods.getS3ClientCache)

## enregistrer
<a name="DynamoDBMapper.Methods.save"></a>

Enregistre l’objet spécifié dans la table. L’objet que vous voulez enregistrer est le seul paramètre requis pour cette méthode. Vous pouvez fournir des paramètres de configuration facultatifs en utilisant l’objet `DynamoDBMapperConfig`. 

Si un élément qui a la même clé primaire n’existe pas, cette méthode crée un nouvel élément dans la table. Si un élément qui a la même clé primaire existe, elle met à jour l’élément existant. Si la clé de partition et la clé de tri sont de type String, et annotées avec `@DynamoDBAutoGeneratedKey`, alors elles reçoivent un identificateur unique universel (UUID) aléatoire en cas de défaut d’initialisation. Les champs de version qui sont annotés avec `@DynamoDBVersionAttribute` seront incrémentés d’un niveau. En outre, si un champ de version est mis à jour ou généré par une clé, l’objet adopté est mis à jour à la suite de l’opération. 

Par défaut, seuls les attributs correspondants aux propriétés de classes mappées sont mis à jour. Tous les attributs supplémentaires existant sur un élément ne sont pas affectés. Toutefois, si vous spécifiez `SaveBehavior.CLOBBER`, vous pouvez forcer le remplacement complet de l’élément.

```
DynamoDBMapperConfig config = DynamoDBMapperConfig.builder()
    .withSaveBehavior(DynamoDBMapperConfig.SaveBehavior.CLOBBER).build();
        
mapper.save(item, config);
```

Si vous avez activé le contrôle de version, alors les versions d’élément côté client et côté serveur doivent correspondre. Toutefois, la version n’a pas besoin de correspondre si l’option `SaveBehavior.CLOBBER` est utilisée. Pour plus d’informations sur la gestion des versions, consultez [DynamoDB et verrouillage optimiste avec numéro de version](DynamoDBMapper.OptimisticLocking.md).

## charge
<a name="DynamoDBMapper.Methods.load"></a>

Récupère un élément dans une table. Vous devez fournir la clé primaire de l’élément que vous voulez récupérer. Vous pouvez fournir des paramètres de configuration facultatifs en utilisant l’objet `DynamoDBMapperConfig`. Par exemple, vous pouvez demander le cas échéant des lectures fortement cohérentes afin de garantir que cette méthode récupère uniquement les dernières valeurs d’élément comme indiqué dans l’instruction Java suivante. 

```
DynamoDBMapperConfig config = DynamoDBMapperConfig.builder()
    .withConsistentReads(DynamoDBMapperConfig.ConsistentReads.CONSISTENT).build();

CatalogItem item = mapper.load(CatalogItem.class, item.getId(), config);
```

Par défaut, DynamoDB renvoie l’élément ayant des valeurs éventuellement cohérentes. Pour plus d’informations sur le modèle de cohérence éventuelle de DynamoDB, consultez [Cohérence en lecture DynamoDB](HowItWorks.ReadConsistency.md).

## supprimer
<a name="DynamoDBMapper.Methods.delete"></a>

Supprime un élément de la table. Vous devez communiquer une instance d’objet de la classe mappée. 

Si vous avez activé le contrôle de version, alors les versions d’élément côté client et côté serveur doivent correspondre. Toutefois, la version n’a pas besoin de correspondre si l’option `SaveBehavior.CLOBBER` est utilisée. Pour plus d’informations sur la gestion des versions, consultez [DynamoDB et verrouillage optimiste avec numéro de version](DynamoDBMapper.OptimisticLocking.md). 

## query
<a name="DynamoDBMapper.Methods.query"></a>

Interroge une table ou un index secondaire.

Supposons que vous ayez une table, `Reply`, qui stocke des réponses de threads de forum. Chaque objet thread peut avoir zéro ou plusieurs réponses. La clé primaire de la table `Reply` se compose des champs `Id` et `ReplyDateTime`, où `Id` est la clé de partition et `ReplyDateTime` est la clé de tri de la clé primaire.

```
Reply ( Id, ReplyDateTime, ... )
```

Supposons que vous ayez créé un mappage entre une classe `Reply` et la table `Reply` correspondante dans DynamoDB. L’exemple de code Java suivant utilise `DynamoDBMapper` pour trouver toutes les réponses au cours des deux dernières semaines pour un objet thread spécifique.

**Example**  

```
String forumName = "&DDB;";
String forumSubject = "&DDB; Thread 1";
String partitionKey = forumName + "#" + forumSubject;

long twoWeeksAgoMilli = (new Date()).getTime() - (14L*24L*60L*60L*1000L);
Date twoWeeksAgo = new Date();
twoWeeksAgo.setTime(twoWeeksAgoMilli);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
String twoWeeksAgoStr = df.format(twoWeeksAgo);

Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
eav.put(":v1", new AttributeValue().withS(partitionKey));
eav.put(":v2",new AttributeValue().withS(twoWeeksAgoStr.toString()));

DynamoDBQueryExpression<Reply> queryExpression = new DynamoDBQueryExpression<Reply>()
    .withKeyConditionExpression("Id = :v1 and ReplyDateTime > :v2")
    .withExpressionAttributeValues(eav);

List<Reply> latestReplies = mapper.query(Reply.class, queryExpression);
```

La requête renvoie un ensemble d’objets `Reply`. 

Par défaut, la méthode `query` renvoie une collection « avec chargement différé ». Elle ne renvoie initialement qu’une seule page de résultats puis effectue un appel de service pour la page suivante si nécessaire. Pour obtenir tous les éléments correspondants, itérez sur la collection `latestReplies`. 

Notez que l’appel de la méthode `size()` sur la collection chargera chaque résultat afin de fournir un décompte précis. Cela peut entraîner la consommation d’un débit alloué élevé et, sur une très grande table, pourrait même épuiser toute la mémoire de votre JVM.

Pour interroger un index, vous devez tout d’abord affecter un modèle à l’index en tant que classe d’outil de mappage. Supposons que la `Reply` table possède un index secondaire global nommé *PostedBy-Message-Index*. La clé de partition de cet index est `PostedBy`, et la clé de tri est `Message`. La définition de classe d’un élément dans l’index se présenterait comme suit :

```
@DynamoDBTable(tableName="Reply")
public class PostedByMessage {
    private String postedBy;
    private String message;

    @DynamoDBIndexHashKey(globalSecondaryIndexName = "PostedBy-Message-Index", attributeName = "PostedBy")
    public String getPostedBy() { return postedBy; }
    public void setPostedBy(String postedBy) { this.postedBy = postedBy; }

    @DynamoDBIndexRangeKey(globalSecondaryIndexName = "PostedBy-Message-Index", attributeName = "Message")
    public String getMessage() { return message; }
    public void setMessage(String message) { this.message = message; }

   // Additional properties go here.
}
```

L’annotation `@DynamoDBTable` indique que cet index est associé à la table `Reply`. L'`@DynamoDBIndexHashKey`annotation indique la clé de partition (*PostedBy*) de l'index et `@DynamoDBIndexRangeKey` la clé de tri (*Message*) de l'index.

Vous pouvez maintenant utiliser `DynamoDBMapper` pour interroger l’index, en récupérant un sous-ensemble de messages qui ont été publiés par un utilisateur particulier. Il n’est pas nécessaire de spécifier le nom de l’index si vous n’avez pas de mappages contradictoires entre les tables et les index et si les mappages sont déjà établis dans l’outil de mappage. L’outil de mappage déduit en fonction de la clé primaire et de la clé de tri. L’exemple de code suivant interroge un index secondaire global. Étant donné que les index globaux secondaires (gsi) prennent en charge des lectures cohérentes à terme, mais pas des lectures fortement cohérentes, vous devez spécifier `withConsistentRead(false)`.

```
HashMap<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
eav.put(":v1",  new AttributeValue().withS("User A"));
eav.put(":v2",  new AttributeValue().withS("DynamoDB"));

DynamoDBQueryExpression<PostedByMessage> queryExpression = new DynamoDBQueryExpression<PostedByMessage>()
    .withIndexName("PostedBy-Message-Index")
    .withConsistentRead(false)
    .withKeyConditionExpression("PostedBy = :v1 and begins_with(Message, :v2)")
    .withExpressionAttributeValues(eav);

List<PostedByMessage> iList =  mapper.query(PostedByMessage.class, queryExpression);
```

La requête renvoie un ensemble d’objets `PostedByMessage`.

## queryPage
<a name="DynamoDBMapper.Methods.queryPage"></a>

Interroge une table ou un index secondaire, et renvoie une seule page de résultats correspondants. Comme avec la méthode `query`, vous devez spécifier une valeur de clé de partition et un filtre de requête qui est appliqué à l’attribut de clé de tri. Toutefois, `queryPage` renvoie uniquement la première « page » de données, c’est-à-dire la quantité de données pouvant tenir dans 1 Mo 

## scan
<a name="DynamoDBMapper.Methods.scan"></a>

Analyse une table ou un index secondaire entiers. Vous pouvez spécifier le cas échéant un `FilterExpression` pour filtrer l’ensemble de résultats.

Supposons que vous ayez une table, `Reply`, qui stocke des réponses de threads de forum. Chaque objet thread peut avoir zéro ou plusieurs réponses. La clé primaire de la table `Reply` se compose des champs `Id` et `ReplyDateTime`, où `Id` est la clé de partition et `ReplyDateTime` est la clé de tri de la clé primaire.

```
Reply ( Id, ReplyDateTime, ... )
```

Si vous avez mappé une classe Java à la table `Reply`, vous pouvez utiliser le `DynamoDBMapper` pour analyser la table. Par exemple, le code Java suivant analyse l’ensemble de la table `Reply`, en renvoyant uniquement les réponses pour une année donnée.

**Example**  

```
HashMap<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
eav.put(":v1", new AttributeValue().withS("2015"));

DynamoDBScanExpression scanExpression = new DynamoDBScanExpression()
    .withFilterExpression("begins_with(ReplyDateTime,:v1)")
    .withExpressionAttributeValues(eav);

List<Reply> replies =  mapper.scan(Reply.class, scanExpression);
```

Par défaut, la méthode `scan` renvoie une collection « avec chargement différé ». Elle ne renvoie initialement qu’une seule page de résultats puis effectue un appel de service pour la page suivante si nécessaire. Pour obtenir tous les éléments correspondants, itérez sur la collection `replies`.

Notez que l’appel de la méthode `size()` sur la collection chargera chaque résultat afin de fournir un décompte précis. Cela peut entraîner la consommation d’un débit alloué élevé et, sur une très grande table, pourrait même épuiser toute la mémoire de votre JVM.

Pour analyser un index, vous devez tout d’abord affecter un modèle à l’index en tant que classe d’outil de mappage. Supposons que la table `Reply` a un index secondaire global nommé `PostedBy-Message-Index`. La clé de partition de cet index est `PostedBy`, et la clé de tri est `Message`. Une classe d’outil de mappage pour cet index est disponible dans la section [query](#DynamoDBMapper.Methods.query). Elle utilise les annotations `@DynamoDBIndexHashKey` et `@DynamoDBIndexRangeKey` pour spécifier la clé de partition et la clé de tri de l’index.

L’exemple de code suivant présente analyse `PostedBy-Message-Index`. Il n’utilise pas un filtre d’analyse. Ainsi, tous les éléments dans l’index vous sont renvoyés.

```
DynamoDBScanExpression scanExpression = new DynamoDBScanExpression()
    .withIndexName("PostedBy-Message-Index")
    .withConsistentRead(false);

    List<PostedByMessage> iList =  mapper.scan(PostedByMessage.class, scanExpression);
    Iterator<PostedByMessage> indexItems = iList.iterator();
```

## scanPage
<a name="DynamoDBMapper.Methods.scanPage"></a>

Analyse une table ou un index secondaire, et renvoie une seule page de résultats correspondants. Comme avec la méthode `scan`, vous pouvez spécifier le cas échéant un `FilterExpression` pour filtrer le jeu de résultats. Toutefois, `scanPage` renvoie uniquement la première « page » de données, c’est-à-dire la quantité de données pouvant tenir dans 1 Mo.

## parallelScan
<a name="DynamoDBMapper.Methods.parallelScan"></a>

Effectue une analyse parallèle d’une table ou d’un index secondaire entiers. Vous spécifiez un certain nombre de segments logiques pour la table, avec une expression d’analyse pour filtrer les résultats. Le `parallelScan` répartit la tâche d’analyse entre plusieurs instances de travail, une pour chaque segment logique ; les instances de travail traitent les données en parallèle et renvoient les résultats.

L’exemple de code Java suivant effectue une analyse parallèle sur la table `Product`.

```
int numberOfThreads = 4;

Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
eav.put(":n", new AttributeValue().withN("100"));

DynamoDBScanExpression scanExpression = new DynamoDBScanExpression()
    .withFilterExpression("Price <= :n")
    .withExpressionAttributeValues(eav);

List<Product> scanResult = mapper.parallelScan(Product.class, scanExpression, numberOfThreads);
```

## batchSave
<a name="DynamoDBMapper.Methods.batchSave"></a>

Enregistre des objets dans une ou plusieurs tables à l’aide d’un ou de plusieurs appels à la méthode `AmazonDynamoDB.batchWriteItem`. Cette méthode n’offre pas de garanties de transaction.

Le code Java enregistre deux éléments (livres) dans la table `ProductCatalog`.

```
Book book1 = new Book();
book1.setId(901);
book1.setProductCategory("Book");
book1.setTitle("Book 901 Title");

Book book2 = new Book();
book2.setId(902);
book2.setProductCategory("Book");
book2.setTitle("Book 902 Title");

mapper.batchSave(Arrays.asList(book1, book2));
```

## batchLoad
<a name="DynamoDBMapper.Methods.batchLoad"></a>

Récupère plusieurs éléments d’une ou de plusieurs tables en utilisant leurs clés primaires.

Le code Java suivant récupère deux éléments dans deux tables différentes.

```
ArrayList<Object> itemsToGet = new ArrayList<Object>();

ForumItem forumItem = new ForumItem();
forumItem.setForumName("Amazon DynamoDB");
itemsToGet.add(forumItem);

ThreadItem threadItem = new ThreadItem();
threadItem.setForumName("Amazon DynamoDB");
threadItem.setSubject("Amazon DynamoDB thread 1 message text");
itemsToGet.add(threadItem);

Map<String, List<Object>> items = mapper.batchLoad(itemsToGet);
```

## batchDelete
<a name="DynamoDBMapper.Methods.batchDelete"></a>

Supprime des objets d’une ou de plusieurs tables à l’aide d’un ou de plusieurs appels à la méthode `AmazonDynamoDB.batchWriteItem`. Cette méthode n’offre pas de garanties de transaction. 

Le code Java supprime deux éléments (livres) dans la table `ProductCatalog`.

```
Book book1 = mapper.load(Book.class, 901);
Book book2 = mapper.load(Book.class, 902);
mapper.batchDelete(Arrays.asList(book1, book2));
```

## batchWrite
<a name="DynamoDBMapper.Methods.batchWrite"></a>

Enregistre et supprime des objets dans une ou plusieurs des tables à l’aide d’un ou de plusieurs appels à la méthode `AmazonDynamoDB.batchWriteItem`. Cette méthode ne fournit pas des garanties de transactions et ne prend pas en charge le contrôle de version (suppressions ou insertions conditionnelles).

Le code Java suivant écrit un nouvel élément dans la table `Forum`, écrit un nouvel élément dans la table `Thread` et supprime un élément de la table `ProductCatalog`.

```
// Create a Forum item to save
Forum forumItem = new Forum();
forumItem.setName("Test BatchWrite Forum");

// Create a Thread item to save
Thread threadItem = new Thread();
threadItem.setForumName("AmazonDynamoDB");
threadItem.setSubject("My sample question");

// Load a ProductCatalog item to delete
Book book3 = mapper.load(Book.class, 903);

List<Object> objectsToWrite = Arrays.asList(forumItem, threadItem);
List<Book> objectsToDelete = Arrays.asList(book3);

mapper.batchWrite(objectsToWrite, objectsToDelete);
```

## transactionWrite
<a name="DynamoDBMapper.Methods.transactionWrite"></a>

Enregistre et supprime des objets dans une ou plusieurs des tables à l’aide d’un appel à la méthode `AmazonDynamoDB.transactWriteItems`. 

[Pour obtenir la liste des exceptions spécifiques aux transactions, consultez TransactWriteItems la section Erreurs.](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html#API_TransactWriteItems_Errors) 

Pour plus d’informations sur les transactions DynamoDB et les garanties d’atomicité, de cohérence, d’isolation et de durabilité (ACID) offertes, consultez [Transactions d’Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transactions.html). 

**Note**  
 Cette méthode ne prend pas en charge :  
[DBMapperConfig Dynamo. SaveBehavior](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.OptionalConfig.html).

Le code Java suivant écrit un nouvel élément dans chacune des tables `Forum` et `Thread`, par voie de transaction.

```
Thread s3ForumThread = new Thread();
s3ForumThread.setForumName("S3 Forum");
s3ForumThread.setSubject("Sample Subject 1");
s3ForumThread.setMessage("Sample Question 1");

Forum s3Forum = new Forum();
s3Forum.setName("S3 Forum");
s3Forum.setCategory("Amazon Web Services");
s3Forum.setThreads(1);

TransactionWriteRequest transactionWriteRequest = new TransactionWriteRequest();
transactionWriteRequest.addPut(s3Forum);
transactionWriteRequest.addPut(s3ForumThread);
mapper.transactionWrite(transactionWriteRequest);
```

## transactionLoad
<a name="DynamoDBMapper.Methods.transactionLoad"></a>

Charge des objets d’une ou de plusieurs tables à l’aide d’un appel à la méthode `AmazonDynamoDB.transactGetItems`. 

[Pour obtenir la liste des exceptions spécifiques aux transactions, consultez TransactGetItems la section Erreurs.](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html#API_TransactGetItems_Errors) 

Pour plus d’informations sur les transactions DynamoDB et les garanties d’atomicité, de cohérence, d’isolation et de durabilité (ACID) offertes, consultez [Transactions d’Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transactions.html). 

L’extrait de code Java suivent charge un élément à partir de chacune des tables `Forum` et `Thread`, par voie de transaction.

```
Forum dynamodbForum = new Forum();
dynamodbForum.setName("DynamoDB Forum");
Thread dynamodbForumThread = new Thread();
dynamodbForumThread.setForumName("DynamoDB Forum");

TransactionLoadRequest transactionLoadRequest = new TransactionLoadRequest();
transactionLoadRequest.addLoad(dynamodbForum);
transactionLoadRequest.addLoad(dynamodbForumThread);
mapper.transactionLoad(transactionLoadRequest);
```

## count
<a name="DynamoDBMapper.Methods.count"></a>

Évalue l’expression d’analyse spécifiée et renvoie le nombre d’éléments correspondants. Aucun élément de données n’est renvoyé.

## generateCreateTableDemande
<a name="DynamoDBMapper.Methods.generateCreateTableRequest"></a>

Analyse une classe POJO représentant une table DynamoDB, et renvoie une `CreateTableRequest` pour cette table.

## createS3Link
<a name="DynamoDBMapper.Methods.createS3Link"></a>

Crée un lien vers un objet dans Amazon S3. Vous devez spécifier un nom de compartiment et un nom de clé identifiant l’objet de manière unique dans le compartiment.

Pour utiliser `createS3Link`, votre classe d’outil de mappage doit définir des méthodes getter et setter. L'exemple de code suivant illustre cela en ajoutant un nouvel attribut et de nouvelles getter/setter méthodes à la `CatalogItem` classe.

```
@DynamoDBTable(tableName="ProductCatalog")
public class CatalogItem {

    ...

    public S3Link productImage;

    ....

    @DynamoDBAttribute(attributeName = "ProductImage")
    public S3Link getProductImage() {
            return productImage;
    }

    public void setProductImage(S3Link productImage) {
        this.productImage = productImage;
    }

...
}
```

Le code Java suivant définit un nouvel élément à écrire dans la table `Product`. L’élément inclut un lien vers une image de produit ; les données d’image sont chargées dans Amazon S3.

```
CatalogItem item = new CatalogItem();

item.setId(150);
item.setTitle("Book 150 Title");

String amzn-s3-demo-bucket = "amzn-s3-demo-bucket";
String myS3Key = "productImages/book_150_cover.jpg";
item.setProductImage(mapper.createS3Link(amzn-s3-demo-bucket, myS3Key));

item.getProductImage().uploadFrom(new File("/file/path/book_150_cover.jpg"));

mapper.save(item);
```

La classe `S3Link` fournit de nombreuses autres méthodes pour la manipulation d’objets dans Amazon S3. Pour plus d’informations, consultez [Javadocs pour `S3Link`](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/S3Link.html).

## Obtient S3 ClientCache
<a name="DynamoDBMapper.Methods.getS3ClientCache"></a>

Renvoie le `S3ClientCache` sous-jacent pour l’accès à Amazon S3. Un `S3ClientCache` est une carte intelligente pour des objets `AmazonS3Client`. Si vous avez plusieurs clients, cela `S3ClientCache` peut vous aider à organiser les clients par AWS région et à créer de nouveaux clients Amazon S3 à la demande.

# Types de données pris en charge pour Dynamo DBMapper pour Java
<a name="DynamoDBMapper.DataTypes"></a>

Cette section décrit les types de données Java primitifs, les collections et les types de données arbitraires pris en charge dans Amazon DynamoDB. 

Amazon DynamoDB prend en charge les types de données Java primitifs et les classes wrapper primitives suivants. 
+ `String`
+ `Boolean`, `boolean`
+ `Byte`, `byte`
+ `Date` (en tant que chaîne de précision à la milliseconde [ISO\$18601](http://en.wikipedia.org/wiki/ISO_8601), passée sur UTC)
+ `Calendar` (en tant que chaîne de précision à la milliseconde [ISO\$18601](http://en.wikipedia.org/wiki/ISO_8601), passée sur UTC)
+ `Long`, `long`
+ `Integer`, `int`
+ `Double`, `double`
+ `Float`, `float`
+ `BigDecimal`
+ `BigInteger`

**Note**  
Pour plus d’informations sur les règles de dénomination de DynamoDB et les différents types de données pris en charge, consultez [Types de données et règles de dénomination pris en charge dans Amazon DynamoDB](HowItWorks.NamingRulesDataTypes.md). 
Les valeurs binaires vides sont prises en charge par le Dynamo. DBMapper
 AWS SDK for Java 2.x prend en charge les valeurs String vides.  
Dans le AWS SDK for Java 1.x, DBMapper Dynamo prend en charge la lecture de valeurs d'attributs de chaîne vides, mais il n'écrit pas de valeurs d'attribut de chaîne vides car ces attributs sont supprimés de la demande.

DynamoDB prend en charge les types de collections Java [Set](http://docs.oracle.com/javase/6/docs/api/java/util/Set.html) (ensemble), [List](http://docs.oracle.com/javase/6/docs/api/java/util/List.html) (liste) et [Map](http://docs.oracle.com/javase/6/docs/api/java/util/Map.html) (mappage). Le tableau suivant résume la manière dont ces types Java mappent aux types DynamoDB.


****  

| Type Java | Type DynamoDB | 
| --- | --- | 
|  Tous les types de numéro  |  `N` (type Number)  | 
|  Chaînes  |  `S` (type String)   | 
|  Booléen  |  `BOOL` (type booléen), 0 ou 1.  | 
|  ByteBuffer  |  `B` (type Binary)  | 
|  Date  |  `S` (type String). Les valeurs Date sont stockées comme chaînes formatées ISO-8601.  | 
| Types de collections [Set](http://docs.oracle.com/javase/6/docs/api/java/util/Set.html) |  Type `SS` (string set), type `NS` (number set) ou type `BS` (binary set).  | 

 L’interface `DynamoDBTypeConverter` vous permet de mapper vos propres types de données arbitraires à un type de données que DynamoDB prend en charge en mode natif. Pour de plus amples informations, veuillez consulter [Mappage des données arbitraires dans DynamoDB](DynamoDBMapper.ArbitraryDataMapping.md). 

# Annotations Java pour DynamoDB
<a name="DynamoDBMapper.Annotations"></a>

Cette section décrit les annotations disponibles pour le mappage de vos classes et propriétés à des tables et attributs dans Amazon DynamoDB.

Pour la documentation Javadoc correspondante, consultez [Annotation Types Summary](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/package-summary.html) dans la [Référence d’API AWS SDK pour Java](https://docs.aws.amazon.com/sdk-for-java/latest/reference/).

**Note**  
Dans les annotations suivantes, seules `DynamoDBTable` et `DynamoDBHashKey` sont obligatoires. 

**Topics**
+ [Dynamo DBAttribute](#DynamoDBMapper.Annotations.DynamoDBAttribute)
+ [Dynamo DBAuto GeneratedKey](#DynamoDBMapper.Annotations.DynamoDBAutoGeneratedKey)
+ [Dynamo DBAuto GeneratedTimestamp](#DynamoDBMapper.Annotations.DynamoDBAutoGeneratedTimestamp)
+ [Dynamo DBDocument](#DynamoDBMapper.Annotations.DynamoDBDocument)
+ [Clé Dynamo DBHash](#DynamoDBMapper.Annotations.DynamoDBHashKey)
+ [Dynamo DBIgnore](#DynamoDBMapper.Annotations.DynamoDBIgnore)
+ [Dynamo DBIndex HashKey](#DynamoDBMapper.Annotations.DynamoDBIndexHashKey)
+ [Dynamo DBIndex RangeKey](#DynamoDBMapper.Annotations.DynamoDBIndexRangeKey)
+ [Clé Dynamo DBRange](#DynamoDBMapper.Annotations.DynamoDBRangeKey)
+ [Dynamo DBTable](#DynamoDBMapper.Annotations.DynamoDBTable)
+ [Dynamo convertie DBType](#DynamoDBMapper.Annotations.DynamoDBTypeConverted)
+ [Dynamo DBTyped](#DynamoDBMapper.Annotations.DynamoDBTyped)
+ [Attribut Dynamo DBVersion](#DynamoDBMapper.Annotations.DynamoDBVersionAttribute)

## Dynamo DBAttribute
<a name="DynamoDBMapper.Annotations.DynamoDBAttribute"></a>

Mappe une propriété avec un attribut de table. Par défaut, chaque propriété de classe mappe un attribut d’élément avec le même nom. Toutefois, si les noms ne sont pas les mêmes, vous pouvez utiliser cette annotation pour mapper une propriété avec l’attribut. Dans l’extrait Java suivant, l’`DynamoDBAttribute` mappe la propriété `BookAuthors` avec le nom d’attribut `Authors` de la table.

```
@DynamoDBAttribute(attributeName = "Authors")
public List<String> getBookAuthors() { return BookAuthors; }
public void setBookAuthors(List<String> BookAuthors) { this.BookAuthors = BookAuthors; }
```

Le `DynamoDBMapper` utilise `Authors` en tant que nom d’attribut lors de l’enregistrement de l’objet vers la table. 

## Dynamo DBAuto GeneratedKey
<a name="DynamoDBMapper.Annotations.DynamoDBAutoGeneratedKey"></a>

Marque une propriété de clé de tri ou de clé de partition comme étant générée automatiquement. `DynamoDBMapper` génère un [UUID](http://docs.oracle.com/javase/6/docs/api/java/util/UUID.html) aléatoire lors de l’enregistrement de ces attributs. Seules les propriétés String peuvent être marquées en tant que clés générées automatiquement. 

L’exemple suivant illustre l’utilisation clés générées automatiquement.

```
@DynamoDBTable(tableName="AutoGeneratedKeysExample")
public class AutoGeneratedKeys {
    private String id;
    private String payload;

    @DynamoDBHashKey(attributeName = "Id")
    @DynamoDBAutoGeneratedKey
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }

    @DynamoDBAttribute(attributeName="payload")
    public String getPayload() { return this.payload; }
    public void setPayload(String payload) { this.payload = payload; }

    public static void saveItem() {
        AutoGeneratedKeys obj = new AutoGeneratedKeys();
        obj.setPayload("abc123");

        // id field is null at this point
        DynamoDBMapper mapper = new DynamoDBMapper(dynamoDBClient);
        mapper.save(obj);

        System.out.println("Object was saved with id " + obj.getId());
    }
}
```

## Dynamo DBAuto GeneratedTimestamp
<a name="DynamoDBMapper.Annotations.DynamoDBAutoGeneratedTimestamp"></a>

Génère automatiquement un horodatage.

```
@DynamoDBAutoGeneratedTimestamp(strategy=DynamoDBAutoGenerateStrategy.ALWAYS)
public Date getLastUpdatedDate() { return lastUpdatedDate; }
public void setLastUpdatedDate(Date lastUpdatedDate) { this.lastUpdatedDate = lastUpdatedDate; }
```

(Facultatif) La stratégie de génération automatique peut être définie en fournissant un attribut de stratégie. La valeur par défaut est `ALWAYS`.

## Dynamo DBDocument
<a name="DynamoDBMapper.Annotations.DynamoDBDocument"></a>

Indique qu’une classe peut être sérialisée sous forme de document Amazon DynamoDB.

Par exemple, supposons que vous voulez mapper un document JSON à un attribut DynamoDB de type Map (`M`). L’exemple de code suivant définit un élément contenant un attribut imbriqué de type de Map.

```
public class ProductCatalogItem {

    private Integer id;  //partition key
    private Pictures pictures;
    /* ...other attributes omitted... */

    @DynamoDBHashKey(attributeName="Id")
    public Integer getId() { return id;}
    public void setId(Integer id) {this.id = id;}

    @DynamoDBAttribute(attributeName="Pictures")
    public Pictures getPictures() { return pictures;}
    public void setPictures(Pictures pictures) {this.pictures = pictures;}

    // Additional properties go here.

    @DynamoDBDocument
    public static class Pictures {
        private String frontView;
        private String rearView;
        private String sideView;

        @DynamoDBAttribute(attributeName = "FrontView")
        public String getFrontView() { return frontView; }
        public void setFrontView(String frontView) { this.frontView = frontView; }

        @DynamoDBAttribute(attributeName = "RearView")
        public String getRearView() { return rearView; }
        public void setRearView(String rearView) { this.rearView = rearView; }

        @DynamoDBAttribute(attributeName = "SideView")
        public String getSideView() { return sideView; }
        public void setSideView(String sideView) { this.sideView = sideView; }

     }
}
```

Vous pouvez alors enregistrer un nouvel élément `ProductCatalog` avec `Pictures`, comme illustré dans l’exemple suivant.

```
ProductCatalogItem item = new ProductCatalogItem();

Pictures pix = new Pictures();
pix.setFrontView("http://example.com/products/123_front.jpg");
pix.setRearView("http://example.com/products/123_rear.jpg");
pix.setSideView("http://example.com/products/123_left_side.jpg");
item.setPictures(pix);

item.setId(123);

mapper.save(item);
```

L’élément `ProductCatalog` qui en résulte se présente comme suit (au format JSON) :

```
{
  "Id" : 123
  "Pictures" : {
    "SideView" : "http://example.com/products/123_left_side.jpg",
    "RearView" : "http://example.com/products/123_rear.jpg",
    "FrontView" : "http://example.com/products/123_front.jpg"
  }
}
```

## Clé Dynamo DBHash
<a name="DynamoDBMapper.Annotations.DynamoDBHashKey"></a>

Mappe une propriété de classe avec la clé de partition de la table. La propriété doit être un des types binaire, numéro ou chaîne scalaire. La propriété ne peut pas être de type collection. 

Supposons que vous ayez une table, `ProductCatalog`, qui a un `Id` en tant que clé primaire. Le code Java suivant définit une classe `CatalogItem` et mappe sa propriété `Id` à la clé primaire de la table `ProductCatalog` à l’aide de la balise `@DynamoDBHashKey`.

```
@DynamoDBTable(tableName="ProductCatalog")
public class CatalogItem {
    private Integer Id;
   @DynamoDBHashKey(attributeName="Id")
   public Integer getId() {
        return Id;
   }
   public void setId(Integer Id) {
        this.Id = Id;
   }
   // Additional properties go here.
}
```

## Dynamo DBIgnore
<a name="DynamoDBMapper.Annotations.DynamoDBIgnore"></a>

Indique à l’instance `DynamoDBMapper` que la propriété associée doit être ignorée. Lors de l’enregistrement de données dans la table, `DynamoDBMapper` ne sauvegarde pas cette propriété dans la table.

 S’applique à la méthode getter ou au champ de classe pour une propriété non modélisée. Si l’annotation est appliquée directement au champ de classe, les méthodes getter et setter correspondantes doivent être déclarées dans la même classe. 

## Dynamo DBIndex HashKey
<a name="DynamoDBMapper.Annotations.DynamoDBIndexHashKey"></a>

Mappe une propriété de classe à la clé de partition d’un index secondaire global. La propriété doit être un des types binaire, numéro ou chaîne scalaire. La propriété ne peut pas être de type collection. 

Utilisez cette annotation si vous devez interroger (`Query`) un index secondaire global. Vous devez spécifier le nom d’index (`globalSecondaryIndexName`). Si le nom de la propriété de classe est différent de la clé de partition d’index, vous devez également spécifier le nom de cet attribut d’index (`attributeName`).

## Dynamo DBIndex RangeKey
<a name="DynamoDBMapper.Annotations.DynamoDBIndexRangeKey"></a>

Mappe une propriété de classe à la clé de tri d’un index secondaire global ou local. La propriété doit être un des types binaire, numéro ou chaîne scalaire. La propriété ne peut pas être de type collection. 

Utilisez cette annotation si vous devez interroger (`Query`) un index secondaire local ou global, et souhaitez affiner vos résultats à l’aide de la clé de tri d’index. Vous devez spécifier le nom d’index (soit `globalSecondaryIndexName`, soit `localSecondaryIndexName`). Si le nom de la propriété de classe est différent de la clé de tri d’index, vous devez également spécifier le nom de cet attribut d’index (`attributeName`).

## Clé Dynamo DBRange
<a name="DynamoDBMapper.Annotations.DynamoDBRangeKey"></a>

Mappe une propriété de classe avec la clé de tri de la table. La propriété doit être un des types binaire, numéro ou chaîne scalaire. Elle ne peut pas être de type collection. 

Si la clé primaire est composite (clé de partition et clé de tri), vous pouvez utiliser cette balise pour mapper votre champ de classe avec la clé de tri. Par exemple, supposons que vous ayez une table `Reply` qui stocke les réponses pour les threads de forum. Chaque thread peut avoir plusieurs réponses. Ainsi, la clé primaire de cette table est à la fois `ThreadId` et `ReplyDateTime`. La clé de partition est `ThreadId` et la clé de tri est `ReplyDateTime`. 

L’extrait de code Java suivant définit une classe `Reply` et la mappe à la table `Reply`. Il utilise les deux balises, `@DynamoDBHashKey` et `@DynamoDBRangeKey`, pour identifier les propriétés de classe qui sont mappées avec la clé primaire.

```
@DynamoDBTable(tableName="Reply")
public class Reply {
    private Integer id;
    private String replyDateTime;

    @DynamoDBHashKey(attributeName="Id")
    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }

    @DynamoDBRangeKey(attributeName="ReplyDateTime")
    public String getReplyDateTime() { return replyDateTime; }
    public void setReplyDateTime(String replyDateTime) { this.replyDateTime = replyDateTime; }

   // Additional properties go here.
}
```

## Dynamo DBTable
<a name="DynamoDBMapper.Annotations.DynamoDBTable"></a>

Identifie la table cible dans DynamoDB. Par exemple, l’extrait de code Java suivant définit une classe `Developer` et la mappe à la table `People` dans DynamoDB. 

```
@DynamoDBTable(tableName="People")
public class Developer { ...}
```

L’annotation `@DynamoDBTable` peut être héritée. Toute nouvelle classe qui hérite de la classe `Developer` se mappe également à la table `People`. Par exemple, supposons que vous génériez une classe `Lead` qui hérite de la classe `Developer`. Étant donné que vous avez mappé la classe `Developer` à la table `People`, les objets de la classe `Lead` sont également stockés dans la même table.

La `@DynamoDBTable` peut également être remplacée. Toute nouvelle classe qui hérite de la classe `Developer` par défaut se mappe à la même table `People`. Toutefois, vous pouvez substituer ce mappage par défaut. Par exemple, si vous créez une classe qui hérite de la classe `Developer`, vous pouvez explicitement la mapper à une autre table en ajoutant l’annotation `@DynamoDBTable` comme illustré dans l’extrait de code Java suivant.

```
@DynamoDBTable(tableName="Managers")
public class Manager extends Developer { ...}
```

## Dynamo convertie DBType
<a name="DynamoDBMapper.Annotations.DynamoDBTypeConverted"></a>

Une annotation permettant d’indiquer qu’une propriété utilise un convertisseur personnalisé. Peut être indiquée sur une annotation définie par l’utilisateur afin de transmettre des propriétés à `DynamoDBTypeConverter`. 

 L’interface `DynamoDBTypeConverter` vous permet de mapper vos propres types de données arbitraires à un type de données que DynamoDB prend en charge en mode natif. Pour de plus amples informations, veuillez consulter [Mappage des données arbitraires dans DynamoDB](DynamoDBMapper.ArbitraryDataMapping.md).

## Dynamo DBTyped
<a name="DynamoDBMapper.Annotations.DynamoDBTyped"></a>

Une annotation permettant de remplacer la liaison du type d’attribut standard. Les types standard ne nécessitent pas l’annotation si la liaison d’attribut par défaut est appliquée pour ce type. 

## Attribut Dynamo DBVersion
<a name="DynamoDBMapper.Annotations.DynamoDBVersionAttribute"></a>

Identifie une propriété de classe pour stocker un numéro de version de verrouillage optimiste. `DynamoDBMapper` affecte un numéro de version à cette propriété lorsqu’il enregistre un nouvel élément et l’augmente chaque fois que vous mettez à jour l’élément. Seuls les types scalaires de numéros sont pris en charge. Pour plus d’informations sur les types de données, consultez [Types de données](HowItWorks.NamingRulesDataTypes.md#HowItWorks.DataTypes), Pour plus d’informations sur la gestion des versions, consultez [DynamoDB et verrouillage optimiste avec numéro de version](DynamoDBMapper.OptimisticLocking.md).

# Paramètres de configuration facultatifs pour Dynamo DBMapper
<a name="DynamoDBMapper.OptionalConfig"></a>

Lorsque vous créez une instance de `DynamoDBMapper`, elle a certains comportements par défaut ; vous pouvez remplacer ces valeurs par défaut en utilisant la classe `DynamoDBMapperConfig`. 

L’extrait de code suivant crée un `DynamoDBMapper` avec des paramètres personnalisés :

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();

DynamoDBMapperConfig mapperConfig = DynamoDBMapperConfig.builder()
        .withSaveBehavior(DynamoDBMapperConfig.SaveBehavior.CLOBBER)
        .withConsistentReads(DynamoDBMapperConfig.ConsistentReads.CONSISTENT)
        .withTableNameOverride(null)
        .withPaginationLoadingStrategy(DynamoDBMapperConfig.PaginationLoadingStrategy.EAGER_LOADING)
    .build();

DynamoDBMapper mapper = new DynamoDBMapper(client, mapperConfig);
```

Pour plus d'informations, consultez [https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapperConfig.html](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapperConfig.html) dans le manuel de [référence de l'AWS SDK pour Java API](https://docs.aws.amazon.com/sdk-for-java/latest/reference/).

Vous pouvez utiliser les arguments suivants pour une instance de `DynamoDBMapperConfig` :
+ Une valeur d’énumération `DynamoDBMapperConfig.ConsistentReads` :
  + `EVENTUAL` – L’instance du mappeur utilise une demande de lecture éventuellement cohérente.
  + `CONSISTENT` – L’instance du mappeur utilise une demande de lecture fortement cohérente. Vous pouvez utiliser ce paramètre facultatif avec des opérations `load`, `query` ou `scan`. Les lectures fortement cohérentes ont des implications pour les performances et la facturation. Pour plus d’informations, consultez la [page détaillée du produit](https://aws.amazon.com/dynamodb).

  Si vous ne spécifiez pas un paramètre de cohérence de lecture pour votre instance d’outil de mappage, la valeur par défaut est `EVENTUAL`.
**Note**  
Cette valeur est appliquée dans les `batch load` opérations `query``querypage`,`load`, et de la Dynamo. DBMapper
+ Valeur d’énumération `DynamoDBMapperConfig.PaginationLoadingStrategy` – Contrôle la façon dont l’instance de mappeur traite une liste paginée de données, telle que les résultats d’une opération `query` ou `scan` :
  + `LAZY_LOADING` – L’instance de mappeur charge les données quand cela est possible, et conserve tous les résultats chargés en mémoire.
  + `EAGER_LOADING` – L’instance de mappeur charge les données dès que la liste est initialisée.
  + `ITERATION_ONLY` – Vous ne pouvez utiliser qu’un itérateur pour lire la liste. Pendant l’itération, la liste efface tous les résultats précédents avant de charger la page suivante, pour que la liste conserve en mémoire au maximum une page des résultats chargés. Cela signifie également que la liste ne peut être itérée qu’à une seule reprise. Cette stratégie est recommandée lors de la gestion d’éléments importants, afin de réduire les frais généraux de mémoire.

  Si vous ne spécifiez pas une stratégie de chargement de pagination pour votre instance d’outil de mappage, la valeur par défaut est `LAZY_LOADING`.
+ Une valeur d’énumération `DynamoDBMapperConfig.SaveBehavior` - Spécifie comment l’instance d’outil de mappage devrait traiter les attributs lors des opérations d’enregistrement :
  + `UPDATE` – Lors d’une opération d’enregistrement, tous les attributs modélisés sont mis à jour, et les attributs non modélisés ne sont pas affectés. Les types de numéros primitifs (octets, int, long) sont définis sur 0. Les types d’objets sont définis sur null. 
  + `CLOBBER` – Efface et remplace tous les attributs, y compris non modélisés, lors d’une opération d’enregistrement. Pour cela, il faut supprimer l’élément et le recréer. Les contraintes de champ avec version sont également ignorées.

   Si vous ne spécifiez pas le comportement de sauvegarde pour votre instance d’outil de mappage, la valeur par défaut est `UPDATE`.
**Note**  
Les opérations DBMapper transactionnelles Dynamo ne prennent pas en charge `DynamoDBMapperConfig.SaveBehavior` l'énumération. 
+ Objet `DynamoDBMapperConfig.TableNameOverride` – Indique à l’instance de mappeur d’ignorer le nom de table spécifié par l’annotation `DynamoDBTable` d’une classe, et d’utiliser plutôt un autre nom de table que vous fournissez. Cela est utile lors du partitionnement de vos données dans plusieurs tables au moment de l’exécution. 

Vous pouvez remplacer l’objet de configuration par défaut pour `DynamoDBMapper` par opération, en fonction des besoins.

# DynamoDB et verrouillage optimiste avec numéro de version
<a name="DynamoDBMapper.OptimisticLocking"></a>

Le *verrouillage optimiste* est une politique visant à garantir que l’élément côté client que vous mettez à jour (ou supprimez) est identique à l’élément dans Amazon DynamoDB. Si vous utilisez cette stratégie, les écritures de votre base de données ne peuvent pas être remplacées par les écritures d’autres, et vice versa.

Avec le verrouillage optimiste, chaque élément possède un attribut qui agit comme un numéro de version. Si vous récupérez un élément à partir d’une table, l’application enregistre le numéro de version de cet élément. Vous pouvez mettre à jour l’élément, mais uniquement si le numéro de version sur le côté serveur n’a pas changé. Si les versions ne correspondent pas, cela signifie que quelqu’un d’autre a modifié cet élément avant vous. La tentative de mise à jour échoue car vous possédez une version obsolète de l’élément. Si cela se produit, essayez à nouveau en récupérant l’élément, puis en tentant de le mettre à jour. Le verrouillage optimiste vous empêche de remplacer accidentellement les modifications effectuées par les autres. Il empêche également que vos modifications soient remplacées.

Bien que vous puissiez mettre en œuvre votre propre stratégie de verrouillage optimiste, AWS SDK pour Java elle fournit l'`@DynamoDBVersionAttribute`annotation. Dans la classe de mappage pour votre table, vous indiquez une propriété pour stocker le numéro de version et vous la marquez à l’aide de cette annotation. Lorsque vous enregistrez un objet, l’élément correspondant dans la table DynamoDB aura un attribut qui stocke le numéro de version. Le `DynamoDBMapper` attribue un numéro de version lors de l’enregistrement initial de l’objet, et il augmente automatiquement le numéro de version chaque fois que vous mettez à jour l’élément. Vos demandes de mise à jour ou de suppression aboutissent uniquement si la version d’objet côté client correspond au numéro de version de l’élément correspondant dans la table DynamoDB.

 `ConditionalCheckFailedException` est émis si : 
+  Vous utilisez le verrouillage optimiste avec `@DynamoDBVersionAttribute` et la valeur de version sur le serveur est différente de la valeur côté client. 
+  Vous spécifiez vos propres contraintes conditionnelles tout en enregistrant des données à l’aide de `DynamoDBMapper` avec `DynamoDBSaveExpression` et ces contraintes ont échoué. 

**Note**  
Les tables globales DynamoDB utilisent un rapprochement « last writer wins » (dernière version valide) entre des mises à jour concomitantes. Si vous utilisez des tables globales, la stratégie « last writer wins » (dernière version valide) s’applique. Dans ce cas, la stratégie de verrouillage ne fonctionne pas comme prévu.
Les opérations d’écriture transactionnelle `DynamoDBMapper` ne prennent pas en charge les expressions d’annotation et de condition `@DynamoDBVersionAttribute` sur le même objet. Si un objet dans une écriture transactionnelle est annoté avec une expression `@DynamoDBVersionAttribute` conditionnelle et possède également une expression conditionnelle, une SdkClientException sera émise.

Par exemple, le code Java suivant définit une classe `CatalogItem` qui possède plusieurs propriétés. La propriété `Version` est balisée avec l’annotation `@DynamoDBVersionAttribute`.

**Example**  

```
@DynamoDBTable(tableName="ProductCatalog")
public class CatalogItem {

    private Integer id;
    private String title;
    private String ISBN;
    private Set<String> bookAuthors;
    private String someProp;
    private Long version;

    @DynamoDBHashKey(attributeName="Id")
    public Integer getId() { return id; }
    public void setId(Integer Id) { this.id = Id; }

    @DynamoDBAttribute(attributeName="Title")
    public String getTitle() { return title; }
    public void setTitle(String title) { this.title = title; }

    @DynamoDBAttribute(attributeName="ISBN")
    public String getISBN() { return ISBN; }
    public void setISBN(String ISBN) { this.ISBN = ISBN;}

    @DynamoDBAttribute(attributeName = "Authors")
    public Set<String> getBookAuthors() { return bookAuthors; }
    public void setBookAuthors(Set<String> bookAuthors) { this.bookAuthors = bookAuthors; }

    @DynamoDBIgnore
    public String getSomeProp() { return someProp;}
    public void setSomeProp(String someProp) {this.someProp = someProp;}

    @DynamoDBVersionAttribute
    public Long getVersion() { return version; }
    public void setVersion(Long version) { this.version = version;}
}
```

Vous pouvez appliquer l’annotation `@DynamoDBVersionAttribute` aux types Nullable proposés par les classes de wrappers primitifs qui fournissent un type Nullable, par exemple `Long` et `Integer`. 

Le verrouillage optimiste a l’impact suivant sur ces méthodes `DynamoDBMapper` :
+ `save` – Pour un nouvel élément, le `DynamoDBMapper` attribue un numéro de version initial 1. Si vous récupérez un élément, que vous mettez à jour une ou plusieurs de ses propriétés et que vous tentez d’enregistrer les modifications, l’opération de sauvegarde n’aboutit que si les numéros de version côté client et côté serveur correspondent. Le `DynamoDBMapper` augmente le numéro de version automatiquement.
+ `delete` – La méthode `delete` prend un objet en tant que paramètre, et le `DynamoDBMapper` effectue une vérification de version avant de supprimer l’élément. Le contrôle de version peut être désactivé si `DynamoDBMapperConfig.SaveBehavior.CLOBBER` est spécifié dans la demande.

  L’implémentation interne de verrouillage optimiste au sein de `DynamoDBMapper` utilise la prise en charge de suppression et de mise à jour conditionnelles fournies par DynamoDB. 
+ `transactionWrite` —
  + `Put` – Pour un nouvel élément, le `DynamoDBMapper` attribue un numéro de version initial 1. Si vous récupérez un élément, que vous mettez à jour une ou plusieurs de ses propriétés et que vous tentez d’enregistrer les modifications, l’opération « Put » n’aboutit que si les numéros de version côté client et côté serveur correspondent. Le `DynamoDBMapper` augmente le numéro de version automatiquement.
  + `Update` – Pour un nouvel élément, le `DynamoDBMapper` attribue un numéro de version initial 1. Si vous récupérez un élément, que vous mettez à jour une ou plusieurs de ses propriétés et que vous tentez d’enregistrer les modifications, l’opération de mise à jour n’aboutit que si les numéros de version côté client et côté serveur correspondent. Le `DynamoDBMapper` augmente le numéro de version automatiquement.
  + `Delete` – Le `DynamoDBMapper` effectue une vérification de version avant de supprimer l’élément. L’opération de suppression n’aboutit que si les numéros de version côté client et côté serveur correspondent.
  + `ConditionCheck` – L’annotation `@DynamoDBVersionAttribute` n’est pas prise en charge pour les opérations `ConditionCheck`. Un SdkClientException sera lancé lorsqu'un `ConditionCheck` élément est annoté avec`@DynamoDBVersionAttribute`. 

## Désactivation du verrouillage optimiste
<a name="DynamoDBMapper.OptimisticLocking.Disabling"></a>

Pour désactiver le verrouillage optimiste, vous pouvez changer la valeur d’énumération `DynamoDBMapperConfig.SaveBehavior` de `UPDATE` à `CLOBBER`. Vous pouvez le faire en créant une instance `DynamoDBMapperConfig` qui ignore la vérification de version et utilise cette instance pour toutes vos demandes. Pour plus d’informations sur les paramètres `DynamoDBMapperConfig.SaveBehavior` et autres paramètres facultatifs `DynamoDBMapper`, consultez [Paramètres de configuration facultatifs pour Dynamo DBMapper](DynamoDBMapper.OptionalConfig.md). 

Vous pouvez également définir le comportement de verrouillage pour une opération spécifique uniquement. Par exemple, l’extrait de Java suivant utilise le `DynamoDBMapper` pour enregistrer un élément de catalogue. Il spécifie `DynamoDBMapperConfig.SaveBehavior` en ajoutant le paramètre `DynamoDBMapperConfig` facultatif à la méthode `save`. 

**Note**  
La méthode TransactionWrite ne prend pas en charge Dynamo Config. DBMapper SaveBehaviorconfiguration. La désactivation du verrouillage optimiste pour transactionWrite n’est pas prise en charge.

**Example**  

```
DynamoDBMapper mapper = new DynamoDBMapper(client);

// Load a catalog item.
CatalogItem item = mapper.load(CatalogItem.class, 101);
item.setTitle("This is a new title for the item");
...
// Save the item.
mapper.save(item,
    new DynamoDBMapperConfig(
        DynamoDBMapperConfig.SaveBehavior.CLOBBER));
```

# Mappage des données arbitraires dans DynamoDB
<a name="DynamoDBMapper.ArbitraryDataMapping"></a>

En plus des types Java pris en charge (voir [Types de données pris en charge pour Dynamo DBMapper pour Java](DynamoDBMapper.DataTypes.md)), vous pouvez utiliser des types dans votre application pour lesquels il n’y a pas de mappage direct aux types Amazon DynamoDB. Pour mapper ces types, vous devez fournir une implémentation qui convertit votre type complexe en un type pris en charge par DynamoDB et inversement, et annoter la méthode accesseur de type complexe en utilisant l’annotation `@DynamoDBTypeConverted`. Le code de convertisseur transforme les données lorsque des objets sont enregistrés ou chargés. Il est également utilisé pour toutes les opérations qui utilisent des types complexes. Notez que, lors de la comparaison de données pendant des opérations d’interrogation et d’analyse, les comparaisons sont faites par rapport aux données stockées dans DynamoDB.

Par exemple, envisagez la classe `CatalogItem` suivante qui définit une propriété, `Dimension`, qui est de `DimensionType`. Cette propriété stocke les dimensions de l’élément, telles que la hauteur, la largeur et l’épaisseur. Supposons que vous décidez de stocker ces dimensions d’élément sous la forme d’une chaîne (par exemple, 8.5x11x.05) dans DynamoDB. L’exemple suivant fournit un code de convertisseur qui convertit l’objet `DimensionType` en une chaîne et une chaîne en `DimensionType`.



**Note**  
Cet exemple de code part du principe que vous avez déjà chargé des données dans DynamoDB pour votre compte en suivant les instructions de la section [Création de tables et chargement de données pour des exemples de code dans DynamoDB](SampleData.md).  
Pour step-by-step obtenir des instructions relatives à l'exécution de l'exemple suivant, reportez-vous à[Exemples de code Java](CodeSamples.Java.md).

**Example**  

```
public class DynamoDBMapperExample {

    static AmazonDynamoDB client;

    public static void main(String[] args) throws IOException {

        // Set the AWS region you want to access.
        Regions usWest2 = Regions.US_WEST_2;
        client = AmazonDynamoDBClientBuilder.standard().withRegion(usWest2).build();

        DimensionType dimType = new DimensionType();
        dimType.setHeight("8.00");
        dimType.setLength("11.0");
        dimType.setThickness("1.0");

        Book book = new Book();
        book.setId(502);
        book.setTitle("Book 502");
        book.setISBN("555-5555555555");
        book.setBookAuthors(new HashSet<String>(Arrays.asList("Author1", "Author2")));
        book.setDimensions(dimType);

        DynamoDBMapper mapper = new DynamoDBMapper(client);
        mapper.save(book);

        Book bookRetrieved = mapper.load(Book.class, 502);
        System.out.println("Book info: " + "\n" + bookRetrieved);

        bookRetrieved.getDimensions().setHeight("9.0");
        bookRetrieved.getDimensions().setLength("12.0");
        bookRetrieved.getDimensions().setThickness("2.0");

        mapper.save(bookRetrieved);

        bookRetrieved = mapper.load(Book.class, 502);
        System.out.println("Updated book info: " + "\n" + bookRetrieved);
    }

    @DynamoDBTable(tableName = "ProductCatalog")
    public static class Book {
        private int id;
        private String title;
        private String ISBN;
        private Set<String> bookAuthors;
        private DimensionType dimensionType;

        // Partition key
        @DynamoDBHashKey(attributeName = "Id")
        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        @DynamoDBAttribute(attributeName = "Title")
        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        @DynamoDBAttribute(attributeName = "ISBN")
        public String getISBN() {
            return ISBN;
        }

        public void setISBN(String ISBN) {
            this.ISBN = ISBN;
        }

        @DynamoDBAttribute(attributeName = "Authors")
        public Set<String> getBookAuthors() {
            return bookAuthors;
        }

        public void setBookAuthors(Set<String> bookAuthors) {
            this.bookAuthors = bookAuthors;
        }

        @DynamoDBTypeConverted(converter = DimensionTypeConverter.class)
        @DynamoDBAttribute(attributeName = "Dimensions")
        public DimensionType getDimensions() {
            return dimensionType;
        }

        @DynamoDBAttribute(attributeName = "Dimensions")
        public void setDimensions(DimensionType dimensionType) {
            this.dimensionType = dimensionType;
        }

        @Override
        public String toString() {
            return "Book [ISBN=" + ISBN + ", bookAuthors=" + bookAuthors + ", dimensionType= "
                    + dimensionType.getHeight() + " X " + dimensionType.getLength() + " X "
                    + dimensionType.getThickness()
                    + ", Id=" + id + ", Title=" + title + "]";
        }
    }

    static public class DimensionType {

        private String length;
        private String height;
        private String thickness;

        public String getLength() {
            return length;
        }

        public void setLength(String length) {
            this.length = length;
        }

        public String getHeight() {
            return height;
        }

        public void setHeight(String height) {
            this.height = height;
        }

        public String getThickness() {
            return thickness;
        }

        public void setThickness(String thickness) {
            this.thickness = thickness;
        }
    }

    // Converts the complex type DimensionType to a string and vice-versa.
    static public class DimensionTypeConverter implements DynamoDBTypeConverter<String, DimensionType> {

        @Override
        public String convert(DimensionType object) {
            DimensionType itemDimensions = (DimensionType) object;
            String dimension = null;
            try {
                if (itemDimensions != null) {
                    dimension = String.format("%s x %s x %s", itemDimensions.getLength(), itemDimensions.getHeight(),
                            itemDimensions.getThickness());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return dimension;
        }

        @Override
        public DimensionType unconvert(String s) {

            DimensionType itemDimension = new DimensionType();
            try {
                if (s != null && s.length() != 0) {
                    String[] data = s.split("x");
                    itemDimension.setLength(data[0].trim());
                    itemDimension.setHeight(data[1].trim());
                    itemDimension.setThickness(data[2].trim());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            return itemDimension;
        }
    }
}
```

# Exemples DynamoDBMapper
<a name="DynamoDBMapper.Examples"></a>

Le kit AWS SDK fournit une classe `DynamoDBMapper` qui vous permet de mapper vos classes côté client à des tables DynamoDB. Pour utiliser `DynamoDBMapper`, vous définissez la relation entre éléments d’une table DynamoDB et leurs instances d’objet correspondantes dans votre code. La classe `DynamoDBMapper` vous permet d’effectuer diverses opérations de création, de lecture, de mise à jour et de suppression (opérations CRUD) sur des éléments, ainsi que d’exécuter des requêtes et analyses sur des tables.

Pour en savoir plus sur l’utilisation de `DynamoDBMapper`, consultez [DynamoDB Examples Using the AWS SDK for Java ](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/examples-dynamodb.html) dans le *Guide du développeur AWS SDK for Java 1.x*. 

# Java 2.x : client amélioré DynamoDB
<a name="DynamoDBEnhanced"></a>

Le client amélioré DynamoDB est une bibliothèque de haut niveau qui fait partie du kit AWS SDK pour Java version 2 (v2). Il offre un moyen simple de mapper des classes côté client à des tables DynamoDB. Vous définissez les relations entre des tables et leurs classes de modèle correspondantes dans votre code. Après avoir défini ces relations, vous pouvez effectuer de manière intuitive diverses opérations de création, de lecture, de mise à jour ou de suppression (CRUD) sur des tables ou des éléments dans DynamoDB.

Pour plus d'informations sur l'utilisation du client amélioré avec DynamoDB, consultez [Utilisation du client amélioré DynamoDB dans le kit AWS SDK pour Java version 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html). 

# Utilisation du modèle de document .NET dans DynamoDB
<a name="DotNetSDKMidLevel"></a>

AWS SDK pour .NET fournit des classes de modèle de document qui encapsulent certaines opérations Amazon DynamoDB de bas niveau pour simplifier davantage votre codage. Dans le modèle de document, les classes principales sont `Table` et `Document`. La classe `Table` fournit des méthodes d’opération de données telles que `PutItem`, `GetItem` et `DeleteItem`. Elle fournit aussi les méthodes `Query` et `Scan`. La classe `Document` représente un seul élément d’une table.

Les classes de modèle de document précédentes sont disponibles dans l’espace de noms `Amazon.DynamoDBv2.DocumentModel`.

**Note**  
Vous ne pouvez pas utiliser les classes de modèle de document pour créer, mettre à jour et supprimer des tables. Cependant, le modèle de document ne prend pas en charge les opérations de données les plus courantes.

**Topics**
+ [Types de données pris en charge](#MidLevelAPILimitations.SupportedTypes)

## Types de données pris en charge
<a name="MidLevelAPILimitations.SupportedTypes"></a>

Le modèle de document prend en charge un ensemble de types de données .NET primitifs et de types de données de collections. Le modèle prend en charge les types de données primitifs suivants. 
+ `bool`
+ `byte` 
+ `char`
+ `DateTime`
+ `decimal`
+ `double`
+ `float`
+ `Guid`
+ `Int16`
+ `Int32`
+ `Int64`
+ `SByte`
+ `string`
+ `UInt16`
+ `UInt32`
+ `UInt64`

Le tableau suivant résume le mappage des types .NET précédents aux types DynamoDB.


****  

| Type primitif .NET | Type DynamoDB | 
| --- | --- | 
|  Tous les types de numéro  |  `N` (type Number)  | 
|  Tous types de chaînes  |  `S` (type String)   | 
|  MemoryStream, byte[]  |  `B` (type Binary)   | 
| bool | N (type de nombre). 0 représente false et 1 représente true. | 
| DateTime | S (type String). Les valeurs DateTime sont stockées comme chaînes de format ISO-8601. | 
| Guid | S (type String). | 
| Types de collection (liste, HashSet et tableau) | Type BS (ensemble de binaires), type SS (ensemble de chaînes) ou type NS (ensemble de nombres). | 

AWS SDK pour .NET définit les types de mappages (boolean (booléen), null (nul), list (liste) et map (mappage) de DynamoDB à l’API de modèle de document .NET :
+ Utilisez `DynamoDBBool` pour le type booléen.
+ Utilisez `DynamoDBNull` pour le type null.
+ Utilisez `DynamoDBList` pour le type list.
+ Utilisez `Document` pour le type map.

**Note**  
Les valeurs binaires vides sont prises en charge.
La lecture des valeurs de chaîne vides est prise en charge. Les valeurs d’attribut de chaîne vides sont prises en charge dans les valeurs d’attribut de type de chaîne Set lors de l’écriture dans DynamoDB. Les valeurs d’attribut de chaîne vides de type String et les valeurs de chaîne vides contenues dans le type List ou Map sont supprimées des demandes d’écriture.

# Utilisation du modèle de persistance des objets .NET et de DynamoDB
<a name="DotNetSDKHighLevel"></a>

 AWS SDK pour .NET fournit un modèle de persistance des objets qui vous permet de mapper vos classes côté client aux tables Amazon DynamoDB. Ensuite, chaque instance d’objet est mappée à un élément des tables correspondantes. Pour enregistrer vos objets côté client dans les tables, le modèle de persistance des objets fournit la classe `DynamoDBContext`, un point d’entrée dans DynamoDB. Cette classe fournit une connexion à DynamoDB, et vous permet d’accéder aux tables, d’effectuer diverses opérations CRUD ainsi que d’exécuter des requêtes.

Le modèle de persistance des objets fournit un ensemble d'attributs permettant de mapper les classes côté client aux tables et properties/fields aux attributs des tables.

**Note**  
Le modèle de persistance des objets n’autorise pas une API à créer, mettre à jour ou supprimer des tables. Il fournit uniquement des opérations sur les données. Vous ne pouvez utiliser que l'API de AWS SDK pour .NET bas niveau pour créer, mettre à jour et supprimer des tables.

L’exemple suivant montre le fonctionnement du modèle de persistance des objets. Il commence par la table `ProductCatalog`. Sa clé primaire est `Id`.

```
ProductCatalog(Id, ...)
```

Supposons que vous avec une classe `Book` avec les propriétés `Title`, `ISBN` et `Authors`. Vous pouvez mapper la classe `Book` à la table `ProductCatalog` en ajoutant les attributs définis par le modèle de persistance des objets, comme illustré dans l’exemple de code C\$1 suivant.

**Example**  

```
[DynamoDBTable("ProductCatalog")]
  public class Book
  {
    [DynamoDBHashKey]
    public int Id { get; set; }

    public string Title { get; set; }
    public int ISBN { get; set; }

    [DynamoDBProperty("Authors")]
    public List<string> BookAuthors { get; set; }

    [DynamoDBIgnore]
    public string CoverPage { get; set; }
  }
```

Dans l’exemple précédent, l’attribut `DynamoDBTable` mappe la classe `Book` à la table `ProductCatalog`.

Le modèle de persistance des objets prend en charge les mappages explicite et par défaut entre les propriétés de classe et les attributs de table.
+ **Mappage explicite – **Pour mapper une propriété à une clé primaire, vous devez utiliser les attributs de modèle de persistance des objets `DynamoDBHashKey` et `DynamoDBRangeKey`. En outre, pour les attributs de clé non primaire, si un nom de propriété de votre classe et l’attribut de table correspondant auquel vous voulez le mapper ne sont pas identiques, vous devez définir le mappage en ajoutant explicitement l’attribut `DynamoDBProperty`.

  Dans l’exemple précédent, la propriété `Id` mappe à la clé primaire du même nom, et la propriété `BookAuthors` mappe à l’attribut `Authors` dans la table `ProductCatalog`.
+ **Mappage par défaut – **Par défaut, le modèle de persistance des objets mappe les propriétés de classe aux attributs du même nom dans la table.

  Dans l’exemple précédent, les propriétés `Title` et `ISBN` mappent aux attributs du même nom dans la table `ProductCatalog`.

Vous n’avez pas à mapper chaque propriété de classe. Vous identifiez ces propriétés en ajoutant l’attribut `DynamoDBIgnore`. Lorsque vous enregistrez une instance `Book` dans la table, le `DynamoDBContext` n’inclut pas la propriété `CoverPage`. Il ne renvoie pas non plus cette propriété lorsque vous récupérez l’instance livre.

Vous pouvez mapper des propriétés de types primitifs .NET tels que int et string. Vous pouvez également mapper n’importe quels types de données arbitraires tant que vous fournissez un convertisseur approprié pour mapper les données arbitraires à l’un des types DynamoDB. Pour en savoir plus sur le mappage de types arbitraires, consultez [Mappage de données arbitraires avec DynamoDB à l'aide AWS SDK pour .NET du modèle de persistance des objets](DynamoDBContext.ArbitraryDataMapping.md).

Le modèle de persistance des objets prend en charge le verrouillage optimiste. Au cours d’une opération de mise à jour, cela garantit que vous disposez de la dernière copie de l’élément que vous êtes sur le point de mettre à jour. Pour de plus amples informations, veuillez consulter [Verrouillage optimiste à l'aide de DynamoDB et du modèle de persistance des objets AWS SDK pour .NET](DynamoDBContext.VersionSupport.md).

Pour plus d’informations, consultez les rubriques ci-dessous.

**Topics**
+ [Types de données pris en charge](#DotNetDynamoDBContext.SupportedTypes)
+ [Attributs DynamoDB du modèle de persistance des objets .NET](DeclarativeTagsList.md)
+ [DBContext Classe Dynamo issue du modèle de persistance des objets .NET](DotNetDynamoDBContext.md)
+ [Verrouillage optimiste à l'aide de DynamoDB et du modèle de persistance des objets AWS SDK pour .NET](DynamoDBContext.VersionSupport.md)
+ [Mappage de données arbitraires avec DynamoDB à l'aide AWS SDK pour .NET du modèle de persistance des objets](DynamoDBContext.ArbitraryDataMapping.md)

## Types de données pris en charge
<a name="DotNetDynamoDBContext.SupportedTypes"></a>

Le modèle de persistance des objets prend en charge un ensemble de types de données .NET primitifs, de collections et de types de données arbitraires. Le modèle prend en charge les types de données primitifs suivants. 
+ `bool`
+ `byte` 
+ `char`
+ `DateTime`
+ `decimal`
+ `double`
+ `float`
+ `Int16`
+ `Int32`
+ `Int64`
+ `SByte`
+ `string`
+ `UInt16`
+ `UInt32`
+ `UInt64`

Le modèle de persistance des objets prend également en charge les types de collection .NET. `DynamoDBContext`est capable de convertir des types de collection concrets et de simples objets CLR ordinaires (POCOs).

Le tableau suivant résume le mappage des types .NET précédents aux types DynamoDB.


****  

| Type primitif .NET | Type DynamoDB | 
| --- | --- | 
|  Tous les types de numéro  |  `N` (type Number)  | 
|  Tous types de chaînes  |  `S` (type String)   | 
|  MemoryStream, octet []  |  `B` (type Binary)   | 
| bool | N (type de nombre). 0 représente false et 1 représente true. | 
| Types de collections | Type BS (ensemble de binaires), type SS (ensemble de chaînes) ou type NS (ensemble de nombres). | 
| DateTime | S (type String). Les valeurs DateTime sont stockées comme chaînes de format ISO-8601. | 

Le modèle de persistance des objets prend également en charge les types de données arbitraires. Toutefois, vous devez fournir un code de convertisseur pour mapper les types complexes aux types DynamoDB.

**Note**  
Les valeurs binaires vides sont prises en charge.
La lecture des valeurs de chaîne vides est prise en charge. Les valeurs d’attribut de chaîne vides sont prises en charge dans les valeurs d’attribut de type de chaîne Set lors de l’écriture dans DynamoDB. Les valeurs d’attribut de chaîne vides de type String et les valeurs de chaîne vides contenues dans le type List ou Map sont supprimées des demandes d’écriture.

# Attributs DynamoDB du modèle de persistance des objets .NET
<a name="DeclarativeTagsList"></a>

Cette section décrit les attributs qu’offre le modèle de persistance des objets afin que vous puissiez mapper vos classes et propriétés aux tables et attributs DynamoDB.

**Note**  
Dans les attributs suivants, seuls les attributs `DynamoDBTable` et `DynamoDBHashKey` sont obligatoires.

## Dynamo DBGlobal SecondaryIndexHashKey
<a name="w2aac17b9c21c23c37b7"></a>

Mappe une propriété de classe à la clé de partition d’un index secondaire global. Utilisez cet attribut si vous devez interroger (`Query`) un index secondaire global.

## Dynamo DBGlobal SecondaryIndexRangeKey
<a name="w2aac17b9c21c23c37b9"></a>

Mappe une propriété de classe à la clé de tri d’un index secondaire global. Utilisez cet attribut si vous devez interroger (`Query`) un index secondaire global, et souhaitez affiner vos résultats à l’aide de la clé de tri d’index.

## Clé Dynamo DBHash
<a name="w2aac17b9c21c23c37c11"></a>

Mappe une propriété de classe à la clé de partition de la clé primaire de la table. Les attributs de clé primaire ne peuvent pas être de type collection.

L’exemple de code C\$1 suivant mappe la classe `Book` à la table `ProductCatalog`, et la propriété `Id` à la clé de partition de clé primaire de la table.

```
[DynamoDBTable("ProductCatalog")]
public class Book 
{
    [DynamoDBHashKey]
    public int Id { get; set; }

    // Additional properties go here.
}
```

## Dynamo DBIgnore
<a name="w2aac17b9c21c23c37c13"></a>

Indique que la propriété associée devrait être ignorée. Si vous ne souhaitez enregistrer aucune de vos propriétés de classe, vous pouvez ajouter cet attribut afin de demander à `DynamoDBContext` de ne pas inclure cette propriété lors de l’enregistrement d’objets dans la table.

## Dynamo DBLocal SecondaryIndexRangeKey
<a name="w2aac17b9c21c23c37c15"></a>

Mappe une propriété de classe à la clé de tri d’un index secondaire local. Utilisez cet attribut si vous devez interroger (`Query`) un index secondaire local, et souhaitez affiner vos résultats à l’aide de la clé de tri d’index.

## Dynamo DBProperty
<a name="w2aac17b9c21c23c37c17"></a>

Mappe une propriété de classe à un attribut de table. Si la propriété de classe mappe à un attribut de table du même nom, vous n’avez pas besoin de spécifier cet attribut. Toutefois, si les noms ne sont pas les mêmes, vous pouvez utiliser cette étiquette pour indiquer le mappage. Dans l’instruction C\$1 suivante, la `DynamoDBProperty` mappe la propriété `BookAuthors` à l’attribut `Authors` dans la table. 

```
[DynamoDBProperty("Authors")]
public List<string> BookAuthors { get; set; }
```

`DynamoDBContext` utilise ces informations de mappage pour créer l’attribut `Authors` lors de l’enregistrement de données d’objet dans la table correspondante.

## Dynamo DBRenamable
<a name="w2aac17b9c21c23c37c19"></a>

Spécifie un autre nom pour une propriété de classe. Ceci est utile si vous écrivez un convertisseur personnalisé pour mapper des données arbitraires à une table DynamoDB où le nom d’une propriété de classe diffère du nom d’un attribut de table.

## Clé Dynamo DBRange
<a name="w2aac17b9c21c23c37c21"></a>

Mappe une propriété de classe à la clé de tri de la clé primaire de la table. Si la table possède une clé primaire composite (clé de partition et clé de tri), vous devez spécifier les attributs `DynamoDBHashKey` et `DynamoDBRangeKey` dans votre mappage de classe.

Par exemple, l’exemple de table `Reply` a une clé primaire composée de la clé de partition `Id` et de la clé de tri `Replenishment`. L’exemple de code C\$1 suivant mappe la classe `Reply` à la table `Reply`. La définition de classe indique également que deux de ses propriétés mappent à la clé primaire.

```
[DynamoDBTable("Reply")]
public class Reply 
{
   [DynamoDBHashKey]
   public int ThreadId { get; set; }
   [DynamoDBRangeKey]
   public string Replenishment { get; set; }
   
   // Additional properties go here.
}
```

## Dynamo DBTable
<a name="w2aac17b9c21c23c37c23"></a>

Identifie la table cible dans DynamoDB à laquelle la classe mappe. Par exemple, l’exemple de code C\$1 suivant mappe la classe `Developer` à la table `People` dans DynamoDB.

```
[DynamoDBTable("People")]
public class Developer { ...}
```

Cet attribut peut être hérité ou remplacé.
+ L’attribut `DynamoDBTable` peut être hérité. Dans l’exemple précédent, si vous ajoutez une nouvelle classe, `Lead`, qui hérite de la classe `Developer`, elle mappe également à la table `People`. Les objets `Developer` et `Lead` sont stockés dans la table `People`.
+ L’attribut `DynamoDBTable` peut également être remplacé. Dans l’exemple de code C\$1 suivant, la classe `Manager` hérite de la classe `Developer`. Cependant, l’ajout explicite de l’attribut `DynamoDBTable` a pour effet de mapper la classe à une autre table (`Managers`).

  ```
  [DynamoDBTable("Managers")]
  public class Manager : Developer { ...}
  ```

 Vous pouvez ajouter le paramètre facultatif, `LowerCamelCaseProperties`, pour demander à DynamoDB de mettre la première lettre du nom de propriété en minuscule lors du stockage des objets dans une table, comme dans l’exemple C\$1 suivant.

```
[DynamoDBTable("People", LowerCamelCaseProperties=true)]
public class Developer 
{
    string DeveloperName;
    ...
}
```

Lors de l’enregistrement d’instances de la classe `Developer`, `DynamoDBContext` enregistre la propriété `DeveloperName` en tant que `developerName`.

## Dynamo DBVersion
<a name="w2aac17b9c21c23c37c25"></a>

Identifie une propriété de classe pour stocker le numéro de version de l’élément. Pour plus d’informations sur la gestion des versions, consultez [Verrouillage optimiste à l'aide de DynamoDB et du modèle de persistance des objets AWS SDK pour .NET](DynamoDBContext.VersionSupport.md).

# DBContext Classe Dynamo issue du modèle de persistance des objets .NET
<a name="DotNetDynamoDBContext"></a>

La classe `DynamoDBContext` est le point d’entrée de la base de données Amazon DynamoDB. Elle fournit une connexion à DynamoDB, et vous permet d’accéder à vos données dans diverses tables, d’effectuer diverses opérations CRUD, ainsi que d’exécuter des requêtes. La classe `DynamoDBContext` fournit les méthodes suivantes.

**Topics**
+ [Créez MultiTable BatchGet](#w2aac17b9c21c23c39b7)
+ [Créez MultiTable BatchWrite](#w2aac17b9c21c23c39b9)
+ [CreateBatchGet](#w2aac17b9c21c23c39c11)
+ [CreateBatchWrite](#w2aac17b9c21c23c39c13)
+ [Suppression](#w2aac17b9c21c23c39c15)
+ [Dispose](#w2aac17b9c21c23c39c17)
+ [ExecuteBatchGet](#w2aac17b9c21c23c39c19)
+ [ExecuteBatchWrite](#w2aac17b9c21c23c39c21)
+ [FromDocument](#w2aac17b9c21c23c39c23)
+ [FromQuery](#w2aac17b9c21c23c39c25)
+ [FromScan](#w2aac17b9c21c23c39c27)
+ [GetTargetTable](#w2aac17b9c21c23c39c29)
+ [Equilibreur de](#w2aac17b9c21c23c39c31)
+ [Query](#w2aac17b9c21c23c39c33)
+ [Enregistrer](#w2aac17b9c21c23c39c35)
+ [Analyser](#w2aac17b9c21c23c39c37)
+ [ToDocument](#w2aac17b9c21c23c39c39)
+ [Spécification de paramètres facultatifs pour Dynamo DBContext](#OptionalConfigParams)

## Créez MultiTable BatchGet
<a name="w2aac17b9c21c23c39b7"></a>

Crée un objet `MultiTableBatchGet` composé de plusieurs objets `BatchGet`. Chacun de ces objets `BatchGet` peut être utilisé pour récupérer des éléments d’une table DynamoDB.

Pour récupérer les éléments des tables, utilisez la méthode `ExecuteBatchGet` en passant l’objet `MultiTableBatchGet` en tant que paramètre.

## Créez MultiTable BatchWrite
<a name="w2aac17b9c21c23c39b9"></a>

Crée un objet `MultiTableBatchWrite` composé de plusieurs objets `BatchWrite`. Chacun de ces objets `BatchWrite` peut être utilisé pour écrire ou supprimer des éléments dans une table DynamoDB.

Pour écrire dans des tables, utilisez la méthode `ExecuteBatchWrite` en passant l’objet `MultiTableBatchWrite` en tant que paramètre.

## CreateBatchGet
<a name="w2aac17b9c21c23c39c11"></a>

Crée un objet `BatchGet` que vous pouvez utiliser pour extraire plusieurs éléments d’une table. 

## CreateBatchWrite
<a name="w2aac17b9c21c23c39c13"></a>

Crée un objet `BatchWrite` que vous pouvez utiliser pour insérer plusieurs éléments dans une table ou supprimer plusieurs éléments d’une table. 

## Suppression
<a name="w2aac17b9c21c23c39c15"></a>

Supprime un élément de la table. La méthode requiert la clé primaire de l’élément que vous souhaitez supprimer. Vous pouvez fournir en tant que paramètre à cette méthode la valeur de clé primaire ou un objet côté client contenant une valeur de clé primaire.
+ Si vous spécifiez un objet côté client en tant que paramètre et avez activé le verrouillage optimiste, la suppression ne réussit que si les versions côté client et côté serveur de l’objet correspondent.
+ Si vous spécifiez uniquement la valeur de clé primaire en tant que paramètre, la suppression réussit, que vous ayez activé ou non le verrouillage optimiste.

**Note**  
Pour effectuer cette opération en arrière-plan, utilisez la méthode `DeleteAsync` à la place.

## Dispose
<a name="w2aac17b9c21c23c39c17"></a>

Élimine toutes les ressources gérées et non gérées.

## ExecuteBatchGet
<a name="w2aac17b9c21c23c39c19"></a>

Lit les données d’une ou plusieurs tables, en traitant tous les objets `BatchGet` en un objet `MultiTableBatchGet`.

**Note**  
Pour effectuer cette opération en arrière-plan, utilisez la méthode `ExecuteBatchGetAsync` à la place.

## ExecuteBatchWrite
<a name="w2aac17b9c21c23c39c21"></a>

Ecrit ou supprime des données dans une ou plusieurs tables, en traitant tous les objets `BatchWrite` en un objet `MultiTableBatchWrite`.

**Note**  
Pour effectuer cette opération en arrière-plan, utilisez la méthode `ExecuteBatchWriteAsync` à la place.

## FromDocument
<a name="w2aac17b9c21c23c39c23"></a>

Pour une instance de `Document`, la méthode `FromDocument` renvoie une instance d'une classe côté client.

Ceci est utile si vous souhaitez utiliser les classes de modèle de document avec le modèle de persistance des objets pour effectuer des opérations de données. Pour plus d'informations sur les classes de modèles de documents fournies par le AWS SDK pour .NET, consultez[Utilisation du modèle de document .NET dans DynamoDB](DotNetSDKMidLevel.md).

Supposons que vous ayez un objet `Document` nommé `doc` qui contient une représentation d’un l’élément `Forum`. (Pour voir comment construire cet objet, consultez la description de la méthode `ToDocument`, plus loin dans cette rubrique. Vous pouvez utiliser le paramètre `FromDocument` pour récupérer l’élément `Forum` à partir de `Document`, comme illustré dans l’exemple de code C\$1 suivant.

**Example**  

```
forum101 = context.FromDocument<Forum>(101);
```

**Note**  
Si votre objet `Document` implémente l’interface `IEnumerable`, vous pouvez utiliser la méthode `FromDocuments` à la place. Cela vous permet d'itérer sur toutes les instances de classe dans le `Document`.

## FromQuery
<a name="w2aac17b9c21c23c39c25"></a>

Exécute une opération `Query` avec les paramètres de requête définis dans un objet `QueryOperationConfig`.

**Note**  
Pour effectuer cette opération en arrière-plan, utilisez la méthode `FromQueryAsync` à la place.

## FromScan
<a name="w2aac17b9c21c23c39c27"></a>

Exécute une opération `Scan` avec les paramètres d'analyse définis dans un objet `ScanOperationConfig`.

**Note**  
Pour effectuer cette opération en arrière-plan, utilisez la méthode `FromScanAsync` à la place.

## GetTargetTable
<a name="w2aac17b9c21c23c39c29"></a>

Récupère la table cible pour le type spécifié. Ceci est utile si vous écrivez un convertisseur personnalisé pour mapper des données arbitraires à une table DynamoDB, et devez déterminer la table associée à un type de données personnalisé.

## Equilibreur de
<a name="w2aac17b9c21c23c39c31"></a>

Récupère un élément dans une table. La méthode requiert uniquement la clé primaire de l’élément que vous souhaitez extraire. 

Par défaut, DynamoDB renvoie l’élément ayant des valeurs éventuellement cohérentes. Pour plus d’informations sur le modèle de cohérence éventuelle, consultez [Cohérence en lecture DynamoDB](HowItWorks.ReadConsistency.md).

`Load`ou la `LoadAsync` méthode appelle l'[GetItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html)opération, qui vous oblige à spécifier la clé primaire de la table. Comme `GetItem` ignore le paramètre `IndexName`, vous ne pouvez pas charger un élément à l’aide de la partition ou de la clé de tri d’un index. Vous devez donc utiliser la clé primaire de la table pour charger un élément.

**Note**  
Pour effectuer cette opération en arrière-plan, utilisez la méthode `LoadAsync` à la place. Pour voir un exemple d’utilisation de la méthode `LoadAsync` pour effectuer des opérations CRUD de haut niveau sur une table DynamoDB, consultez l’exemple suivant.

```
    /// <summary>
    /// Shows how to perform high-level CRUD operations on an Amazon DynamoDB
    /// table.
    /// </summary>
    public class HighLevelItemCrud
    {
        public static async Task Main()
        {
            var client = new AmazonDynamoDBClient();
            DynamoDBContext context = new DynamoDBContext(client);
            await PerformCRUDOperations(context);
        }

        public static async Task PerformCRUDOperations(IDynamoDBContext context)
        {
            int bookId = 1001; // Some unique value.
            Book myBook = new Book
            {
                Id = bookId,
                Title = "object persistence-AWS SDK for.NET SDK-Book 1001",
                Isbn = "111-1111111001",
                BookAuthors = new List<string> { "Author 1", "Author 2" },
            };

            // Save the book to the ProductCatalog table.
            await context.SaveAsync(myBook);

            // Retrieve the book from the ProductCatalog table.
            Book bookRetrieved = await context.LoadAsync<Book>(bookId);

            // Update some properties.
            bookRetrieved.Isbn = "222-2222221001";

            // Update existing authors list with the following values.
            bookRetrieved.BookAuthors = new List<string> { " Author 1", "Author x" };
            await context.SaveAsync(bookRetrieved);

            // Retrieve the updated book. This time, add the optional
            // ConsistentRead parameter using DynamoDBContextConfig object.
            await context.LoadAsync<Book>(bookId, new DynamoDBContextConfig
            {
                ConsistentRead = true,
            });

            // Delete the book.
            await context.DeleteAsync<Book>(bookId);

            // Try to retrieve deleted book. It should return null.
            Book deletedBook = await context.LoadAsync<Book>(bookId, new DynamoDBContextConfig
            {
                ConsistentRead = true,
            });

            if (deletedBook == null)
            {
                Console.WriteLine("Book is deleted");
            }
        }
    }
```

## Query
<a name="w2aac17b9c21c23c39c33"></a>

Interroge une table sur la base des paramètres de requête que vous fournissez.

Vous pouvez interroger une table uniquement si elle comporte une clé primaire composite (clé de partition et clé de tri). Lors de l’interrogation, vous devez spécifier une clé de partition et une condition qui s’applique à la clé de tri.

Supposons que vous disposez d’une classe `Reply` côté client mappée à la table `Reply` dans DynamoDB. L’exemple de code C\$1 suivant interroge la table `Reply` pour trouver les réponses des unités d’exécution de forum publiées au cours des 15 derniers jours. La table `Reply` possède une clé primaire qui a la clé de partition `Id` et la clé de tri `ReplyDateTime`.

**Example**  

```
DynamoDBContext context = new DynamoDBContext(client);

string replyId = "DynamoDB#DynamoDB Thread 1"; //Partition key
DateTime twoWeeksAgoDate = DateTime.UtcNow.Subtract(new TimeSpan(14, 0, 0, 0)); // Date to compare.
IEnumerable<Reply> latestReplies = context.Query<Reply>(replyId, QueryOperator.GreaterThan, twoWeeksAgoDate);
```

Ceci renvoie une collection d’objets `Reply`. 

La méthode `Query` renvoie une collection `IEnumerable` « avec chargement différé ». Elle ne renvoie initialement qu’une seule page de résultats puis effectue un appel de service pour la page suivante si nécessaire. Pour obtenir tous les éléments correspondants, vous devez itérer uniquement sur la collection `IEnumerable`.

Si votre table possède une clé primaire simple (clé de partition), vous ne pouvez pas utiliser la méthode `Query`. Au lieu de cela, vous pouvez utiliser la méthode `Load` et fournir la clé de partition pour récupérer l’élément.

**Note**  
Pour effectuer cette opération en arrière-plan, utilisez la méthode `QueryAsync` à la place.

## Enregistrer
<a name="w2aac17b9c21c23c39c35"></a>

Enregistre l’objet spécifié dans la table. Si la clé primaire spécifiée dans l’objet d’entrée n’existe pas dans la table, la méthode ajoute un nouvel élément à celle-ci. Si la clé primaire existe, la méthode met à jour l’élément existant.

Si le verrouillage optimiste est configuré, la mise à jour ne réussit que si les versions client et serveur de l’élément correspondent. Pour de plus amples informations, veuillez consulter [Verrouillage optimiste à l'aide de DynamoDB et du modèle de persistance des objets AWS SDK pour .NET](DynamoDBContext.VersionSupport.md).

**Note**  
Pour effectuer cette opération en arrière-plan, utilisez la méthode `SaveAsync` à la place.

## Analyser
<a name="w2aac17b9c21c23c39c37"></a>

Effectue une analyse de la table toute entière. 

Vous pouvez filtrer les résultats d’analyse en spécifiant une condition d’analyse. La condition peut être évaluée sur n’importe quel attribut dans la table. Supposons que vous disposez d’une classe `Book` côté client mappée à la table `ProductCatalog` dans DynamoDB. L’exemple C \$1 suivant analyse la table et renvoie uniquement les éléments livre dont le prix est inférieur à 0.

**Example**  

```
IEnumerable<Book> itemsWithWrongPrice = context.Scan<Book>(
                    new ScanCondition("Price", ScanOperator.LessThan, price),
                    new ScanCondition("ProductCategory", ScanOperator.Equal, "Book")
      );
```

La méthode `Scan` renvoie une collection `IEnumerable` « avec chargement différé ». Elle ne renvoie initialement qu’une seule page de résultats puis effectue un appel de service pour la page suivante si nécessaire. Pour obtenir tous les éléments correspondants, vous devez seulement itérer sur la collection `IEnumerable`.

Pour des raisons de performance, vous devez interroger vos tables et éviter une analyse de table.

**Note**  
Pour effectuer cette opération en arrière-plan, utilisez la méthode `ScanAsync` à la place.

## ToDocument
<a name="w2aac17b9c21c23c39c39"></a>

Renvoie une instance de la classe de modèle de document `Document` de votre instance de classe. 

Ceci est utile si vous souhaitez utiliser les classes de modèle de document avec le modèle de persistance des objets pour effectuer des opérations de données. Pour plus d'informations sur les classes de modèles de documents fournies par le AWS SDK pour .NET, consultez[Utilisation du modèle de document .NET dans DynamoDB](DotNetSDKMidLevel.md). 

Supposons que vous disposez d’une classe côté client mappée à l’exemple de table `Forum`. Vous pouvez ensuite utiliser un `DynamoDBContext` pour obtenir un élément en tant qu’objet `Document` à partir de la table `Forum`, comme illustré dans l’exemple de code C\$1 suivant.

**Example**  

```
DynamoDBContext context = new DynamoDBContext(client);

Forum forum101 = context.Load<Forum>(101); // Retrieve a forum by primary key.
Document doc = context.ToDocument<Forum>(forum101);
```

## Spécification de paramètres facultatifs pour Dynamo DBContext
<a name="OptionalConfigParams"></a>

Lors de l’utilisation du modèle de persistance des objets, vous pouvez spécifier les paramètres facultatifs suivants pour le `DynamoDBContext`.
+ **`ConsistentRead` – **Lors de la récupération de données à l’aide des opérations `Load`, `Query` ou `Scan`, vous pouvez ajouter ce paramètre facultatif pour demander les dernières valeurs pour les données.
+ **`IgnoreNullValues` – **Ce paramètre informe `DynamoDBContext` d’ignorer les valeurs null sur les attributs lors d’une opération `Save`. Si ce paramètre a la valeur false (ou s’il n’est pas défini), une valeur null est interprétée comme une directive pour supprimer l’attribut spécifique. 
+ **`SkipVersionCheck` – **Ce paramètre informe `DynamoDBContext` ne pas comparer les versions lors de l’enregistrement ou de la suppression d’un élément. Pour plus d’informations sur la gestion des versions, consultez [Verrouillage optimiste à l'aide de DynamoDB et du modèle de persistance des objets AWS SDK pour .NET](DynamoDBContext.VersionSupport.md).
+ **`TableNamePrefix` – **Préfixe tous les noms de table avec une chaîne spécifique. Si ce paramètre a la valeur null (ou s’il n’est pas défini), aucun préfixe n’est utilisé.
+ `DynamoDBEntryConversion` – Spécifie le schéma de conversion utilisé par le client. Vous pouvez définir ce paramètre sur la version V1 ou V2. V1 est la version par défaut.

  En fonction de la version que vous définissez, le comportement de ce paramètre change. Par exemple :
  + Dans la version 1, le type de données `bool` est converti en type numérique `N`, où 0 représente false et 1 représente true. Dans la version 2, `bool` est converti en `BOOL`.
  + Dans la version 2, les listes et les tableaux ne sont pas regroupés avec HashSets. Les listes et tableaux de nombres, de types basés sur des chaînes et de types binaires sont convertis en type `L` (Liste), qui peut être envoyé vide pour mettre à jour une liste. Ce n’est pas le cas de la version 1, dans laquelle une liste vide n’est pas envoyée sur le réseau.

    Dans la version 1, les types de collection, tels que List HashSet, et les tableaux sont traités de la même manière. La liste et le tableau de chiffres sont convertis au type `NS` (ensemble de nombres). HashSet 

  L’exemple suivant définit la version du schéma de conversion sur V2, ce qui modifie le comportement de conversion entre les types .NET et les types de données DynamoDB.

  ```
  var config = new DynamoDBContextConfig
  {
      Conversion = DynamoDBEntryConversion.V2
  };
  var contextV2 = new DynamoDBContext(client, config);
  ```

L’exemple de code C\$1 suivant crée un nouveau `DynamoDBContext` en spécifiant deux des paramètres facultatifs précédents, `ConsistentRead` et `SkipVersionCheck`.

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
...
DynamoDBContext context =
       new DynamoDBContext(client, new DynamoDBContextConfig { ConsistentRead = true, SkipVersionCheck = true});
```

`DynamoDBContext` inclut ces paramètres facultatifs avec chaque demande que vous envoyez à l’aide de ce contexte. 

Au lieu de définir ces paramètres au niveau de `DynamoDBContext`, vous pouvez les spécifier pour des opérations individuelles que vous exécutez à l’aide de `DynamoDBContext`, comme illustré dans l’exemple de code C\$1 suivant. L’exemple charge un élément livre spécifique. La méthode `Load` de `DynamoDBContext` spécifie les paramètres facultatifs précédents, `ConsistentRead` et `SkipVersionCheck`.

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
...
DynamoDBContext context = new DynamoDBContext(client);
Book bookItem = context.Load<Book>(productId,new DynamoDBContextConfig{ ConsistentRead = true, SkipVersionCheck = true });
```

Dans ce cas, `DynamoDBContext` inclut ces paramètres uniquement lors de l’envoi de la demande `Get`.

# Verrouillage optimiste à l'aide de DynamoDB et du modèle de persistance des objets AWS SDK pour .NET
<a name="DynamoDBContext.VersionSupport"></a>

La prise en charge du verrouillage optimiste dans le modèle de persistance des objets garantit que la version de l’élément pour votre application est identique à la version de l’élément côté serveur avant de mettre à jour ou de supprimer l’élément. Supposons que vous récupérez un élément à mettre à jour. Toutefois, avant de renvoyer vos mises à jour, une autre application met à jour le même élément. Maintenant, votre demande a une copie obsolète de l’élément. A défaut de verrouillage optimiste, toute mise à jour que vous effectuez remplace la mise à jour effectuée par l’autre application. 

La fonction de verrouillage optimiste du modèle de persistance des objets fournit l’étiquette `DynamoDBVersion` que vous pouvez utiliser pour activer le verrouillage optimiste. Pour utiliser cette fonctionnalité, vous ajoutez une propriété à votre classe pour stocker le numéro de version. Vous ajoutez l’attribut `DynamoDBVersion` à la propriété. Lorsque vous enregistrez l’objet pour la première fois, le `DynamoDBContext` attribue un numéro de version et incrémente cette valeur chaque fois que vous mettez à jour l’élément. 

Votre demande de mise à jour ou de suppression aboutit uniquement si la version de l’objet côté client correspond au numéro de version de l’élément côté serveur. Si votre application a une copie obsolète de l’élément, elle doit obtenir du serveur la dernière version de l’élément avant de pouvoir le mettre à jour ou le supprimer.

L’exemple de code C\$1 suivant définit une classe `Book` avec des attributs de persistance des objets qui la mappent à la table `ProductCatalog`. La propriété `VersionNumber` dans la classe décorée avec l’attribut `DynamoDBVersion` stocke la valeur du numéro de version.

**Example**  

```
[DynamoDBTable("ProductCatalog")]
  public class Book
  {
    [DynamoDBHashKey]   //Partition key
    public int Id { get; set; }
    [DynamoDBProperty]
    public string Title { get; set; }
    [DynamoDBProperty]
    public string ISBN { get; set; }
    [DynamoDBProperty("Authors")]
    public List<string> BookAuthors { get; set; }
    [DynamoDBVersion]
    public int? VersionNumber { get; set; }
  }
```

**Note**  
Vous pouvez appliquer l’attribut `DynamoDBVersion` uniquement à un type primitif numérique nullable (tel que `int?`). 

Le verrouillage optimiste a l’impact suivant sur les opérations `DynamoDBContext` :
+ Pour un nouvel élément, `DynamoDBContext` attribue le numéro de version initial 0. Si vous récupérez un élément existant, mettez à jour une ou plusieurs de ses propriétés, puis tentez d’enregistrer les modifications, l’opération d’enregistrement n’aboutit que si les numéros de version côté client et côté serveur correspondent. `DynamoDBContext` incrémente le numéro de version. Vous n’avez pas besoin de définir le numéro de version.
+ La méthode `Delete` fournit des surcharges pouvant prendre une valeur de clé primaire ou un objet en tant que paramètre, comme illustré dans l’exemple de code C\$1 suivant.  
**Example**  

  ```
  DynamoDBContext context = new DynamoDBContext(client);
  ...
  // Load a book.
  Book book = context.Load<ProductCatalog>(111);
  // Do other operations.
  // Delete 1 - Pass in the book object.
  context.Delete<ProductCatalog>(book);
  
  // Delete 2 - Pass in the Id (primary key)
  context.Delete<ProductCatalog>(222);
  ```

  Si vous fournissez un objet en tant que paramètre, la suppression ne réussit que si la version de l’objet correspond à la version de l’élément côté serveur. Toutefois, si vous fournissez une valeur de clé primaire en tant que paramètre, `DynamoDBContext` ne connaît aucun numéro de version, et supprime l’élément sans effectuer la vérification de version. 

  Notez que l’implémentation interne du verrouillage optimiste dans le code du modèle de persistance des objets utilise les actions d’API de mise à jour conditionnelle et de suppression conditionnelle dans DynamoDB.

## Désactivation du verrouillage optimiste
<a name="DotNetDynamoDBContext.DisablingOptimisticLocking"></a>

Pour désactiver le verrouillage optimiste, utilisez la propriété de configuration `SkipVersionCheck`. Vous pouvez définir cette propriété lors de la création de `DynamoDBContext`. Dans ce cas, le verrouillage optimiste est désactivé pour toutes les demandes que vous effectuez à l’aide du contexte. Pour de plus amples informations, veuillez consulter [Spécification de paramètres facultatifs pour Dynamo DBContext](DotNetDynamoDBContext.md#OptionalConfigParams). 

Au lieu de définir la propriété au niveau du contexte, vous pouvez désactiver le verrouillage optimiste pour une opération spécifique, comme dans l’exemple de code C\$1 suivant. L’exemple utilise le contexte pour supprimer un élément livre. La méthode `Delete` définit la propriété `SkipVersionCheck` sur true, ce qui a pour effet de désactiver la vérification de version.

**Example**  

```
DynamoDBContext context = new DynamoDBContext(client);
// Load a book.
Book book = context.Load<ProductCatalog>(111);
...
// Delete the book.
context.Delete<Book>(book, new DynamoDBContextConfig { SkipVersionCheck = true });
```

# Mappage de données arbitraires avec DynamoDB à l'aide AWS SDK pour .NET du modèle de persistance des objets
<a name="DynamoDBContext.ArbitraryDataMapping"></a>

En plus des types .NET pris en charge (voir [Types de données pris en charge](DotNetSDKHighLevel.md#DotNetDynamoDBContext.SupportedTypes)), vous pouvez utiliser des types dans votre application pour lesquels il n’y a pas de mappage direct aux types Amazon DynamoDB. Le modèle de persistance des objets prend en charge le stockage de données de types arbitraires tant que vous fournissez le convertisseur pour convertir les données du type arbitraire au type DynamoDB, et inversement. Le code de convertisseur transforme les données lors de l’enregistrement et du chargement des objets.

Vous pouvez créer n’importe quel type côté client. Cependant, les données stockées dans les tables sont l’un des types DynamoDB et, lors de la requête et de l’analyse, toutes les comparaisons de données effectuées sont faites par rapport aux données stockées dans DynamoDB.

L’exemple de code C\$1 suivant définit une classe `Book` avec les propriétés `Id`, `Title`, `ISBN` et `Dimension`. La propriété `Dimension` est du `DimensionType` qui décrit les propriétés `Height`, `Width` et `Thickness`. L’exemple de code fournit les méthodes de convertisseur `ToEntry` et `FromEntry` pour convertir les données entre le `DimensionType` et les types de chaîne DynamoDB. Par exemple, lors de l’enregistrement d’une instance `Book`, le convertisseur crée une chaîne de `Dimension` de livre telle que « 8.5x11x.05 ». Lorsque vous récupérez un livre, il convertit la chaîne en instance `DimensionType`.

L’exemple mappe le type `Book` à la table `ProductCatalog`. Il enregistre un exemple d’instance `Book`, le récupère, met à jour ses dimensions et enregistre de nouveau le `Book` mis à jour.



Pour step-by-step obtenir des instructions sur le test de l'exemple suivant, reportez-vous à[Exemples de code .NET](CodeSamples.DotNet.md).

**Example**  

```
using System;
using System.Collections.Generic;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DataModel;
using Amazon.DynamoDBv2.DocumentModel;
using Amazon.Runtime;
using Amazon.SecurityToken;

namespace com.amazonaws.codesamples
{
    class HighLevelMappingArbitraryData
    {
        private static AmazonDynamoDBClient client = new AmazonDynamoDBClient();

        static void Main(string[] args)
        {
            try
            {
                DynamoDBContext context = new DynamoDBContext(client);

                // 1. Create a book.
                DimensionType myBookDimensions = new DimensionType()
                {
                    Length = 8M,
                    Height = 11M,
                    Thickness = 0.5M
                };

                Book myBook = new Book
                {
                    Id = 501,
                    Title = "AWS SDK for .NET Object Persistence Model Handling Arbitrary Data",
                    ISBN = "999-9999999999",
                    BookAuthors = new List<string> { "Author 1", "Author 2" },
                    Dimensions = myBookDimensions
                };

                context.Save(myBook);

                // 2. Retrieve the book.
                Book bookRetrieved = context.Load<Book>(501);

                // 3. Update property (book dimensions).
                bookRetrieved.Dimensions.Height += 1;
                bookRetrieved.Dimensions.Length += 1;
                bookRetrieved.Dimensions.Thickness += 0.2M;
                // Update the book.
                context.Save(bookRetrieved);

                Console.WriteLine("To continue, press Enter");
                Console.ReadLine();
            }
            catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); }
            catch (AmazonServiceException e) { Console.WriteLine(e.Message); }
            catch (Exception e) { Console.WriteLine(e.Message); }
        }
    }
    [DynamoDBTable("ProductCatalog")]
    public class Book
    {
        [DynamoDBHashKey] //Partition key
        public int Id
        {
            get; set;
        }
        [DynamoDBProperty]
        public string Title
        {
            get; set;
        }
        [DynamoDBProperty]
        public string ISBN
        {
            get; set;
        }
        // Multi-valued (set type) attribute.
        [DynamoDBProperty("Authors")]
        public List<string> BookAuthors
        {
            get; set;
        }
        // Arbitrary type, with a converter to map it to DynamoDB type.
        [DynamoDBProperty(typeof(DimensionTypeConverter))]
        public DimensionType Dimensions
        {
            get; set;
        }
    }

    public class DimensionType
    {
        public decimal Length
        {
            get; set;
        }
        public decimal Height
        {
            get; set;
        }
        public decimal Thickness
        {
            get; set;
        }
    }

    // Converts the complex type DimensionType to string and vice-versa.
    public class DimensionTypeConverter : IPropertyConverter
    {
        public DynamoDBEntry ToEntry(object value)
        {
            DimensionType bookDimensions = value as DimensionType;
            if (bookDimensions == null) throw new ArgumentOutOfRangeException();

            string data = string.Format("{1}{0}{2}{0}{3}", " x ",
                            bookDimensions.Length, bookDimensions.Height, bookDimensions.Thickness);

            DynamoDBEntry entry = new Primitive
            {
                Value = data
            };
            return entry;
        }

        public object FromEntry(DynamoDBEntry entry)
        {
            Primitive primitive = entry as Primitive;
            if (primitive == null || !(primitive.Value is String) || string.IsNullOrEmpty((string)primitive.Value))
                throw new ArgumentOutOfRangeException();

            string[] data = ((string)(primitive.Value)).Split(new string[] { " x " }, StringSplitOptions.None);
            if (data.Length != 3) throw new ArgumentOutOfRangeException();

            DimensionType complexData = new DimensionType
            {
                Length = Convert.ToDecimal(data[0]),
                Height = Convert.ToDecimal(data[1]),
                Thickness = Convert.ToDecimal(data[2])
            };
            return complexData;
        }
    }
}
```

# Exécution des exemples de code du Guide du développeur
<a name="CodeSamples"></a>

Ils AWS SDKs fournissent un support étendu pour Amazon DynamoDB dans les langues suivantes :
+ [Java](https://aws.amazon.com/sdk-for-java)
+ [JavaScript dans le navigateur](https://aws.amazon.com/sdk-for-browser)
+ [.NET](https://aws.amazon.com/sdk-for-net)
+ [Node.js](https://aws.amazon.com/sdk-for-node-js)
+ [PHP](https://aws.amazon.com/sdk-for-php)
+ [Python](https://aws.amazon.com/sdk-for-python)
+ [Ruby](https://aws.amazon.com/sdk-for-ruby)
+ [C\$1\$1](https://aws.amazon.com/sdk-for-cpp)
+ [Go](https://aws.amazon.com/sdk-for-go)
+ [Android](https://aws.amazon.com/mobile/sdk/)
+ [iOS](https://aws.amazon.com/mobile/sdk/)

Les exemples de code de ce guide du développeur couvrent de façon plus approfondie les opérations DynamoDB à l’aide des langages de programmation suivants :
+ [Exemples de code Java](CodeSamples.Java.md)
+ [Exemples de code .NET](CodeSamples.DotNet.md)

Avant de commencer cet exercice, vous devez créer un AWS compte, obtenir votre clé d'accès et votre clé secrète, puis configurer le AWS Command Line Interface (AWS CLI) sur votre ordinateur. Pour de plus amples informations, veuillez consulter [Configuration de DynamoDB (service web)](SettingUp.DynamoWebService.md).

**Note**  
Si vous utilisez la version téléchargeable de DynamoDB, vous devez utiliser AWS CLI le pour créer les tables et les exemples de données. Vous devez également spécifier le `--endpoint-url` paramètre pour chaque AWS CLI commande. Pour de plus amples informations, veuillez consulter [Définition du point de terminaison local](DynamoDBLocal.UsageNotes.md#DynamoDBLocal.Endpoint).

# Création de tables et chargement de données pour des exemples de code dans DynamoDB
<a name="SampleData"></a>

Vous trouverez ci-dessous des informations de base sur la création de tables dans DynamoDB, le chargement d'un exemple de jeu de données, l'interrogation des données et la mise à jour des données.
+ [Étape 1 : création d’une table dans DynamoDB](getting-started-step-1.md)
+ [Étape 2 : écrire des données dans une table DynamoDB](getting-started-step-2.md)
+ [Étape 3 : lire des données à partir d’une table DynamoDB](getting-started-step-3.md)
+ [Étape 4 : mettre à jour des données dans une table DynamoDB](getting-started-step-4.md)

# Exemples de code Java
<a name="CodeSamples.Java"></a>

**Topics**
+ [Java : Configuration de vos AWS informations d'identification](#CodeSamples.Java.Credentials)
+ [Java : définition de la AWS région et du point de terminaison](#CodeSamples.Java.RegionAndEndpoint)

Ce guide du développeur contient des extraits de code Java et ready-to-run des programmes. Vous pouvez trouver ces exemples de code dans les sections suivantes :
+ [Utilisation d’éléments et d’attributs dans DynamoDB](WorkingWithItems.md)
+ [Utilisation de tables et de données dans DynamoDB](WorkingWithTables.md)
+ [Interrogation de tables dans DynamoDB](Query.md)
+ [Analyse de tables dans DynamoDB](Scan.md)
+ [Amélioration de l’accès aux données avec les index secondaires dans DynamoDB](SecondaryIndexes.md)
+ [Java 1.x : Dynamo DBMapper](DynamoDBMapper.md)
+ [Modifier la récupération de données pour DynamoDB Streams](Streams.md)

Vous pouvez démarrer rapidement en utilisant Eclipse avec [AWS Toolkit for Eclipse](https://aws.amazon.com/eclipse/). En plus d'un IDE complet, vous bénéficiez également de mises à jour automatiques et de modèles préconfigurés pour créer AWS des applications. AWS SDK pour Java 

**Pour exécuter les exemples de code Java (à l’aide d’Eclipse)**

1. Téléchargez et installez l’IDE [Eclipse](http://www.eclipse.org).

1. Téléchargez et installez le kit [AWS Toolkit for Eclipse](https://aws.amazon.com/eclipse/).

1. Démarrez Eclipse et, dans le menu **Eclipse**, choisissez **File (Fichier)**, **New (Nouveau)**, puis **Other (Autre)**.

1. Dans **Sélectionner un assistant**, choisissez successivement **AWS**, **AWS Projet Java** et **Suivant**.

1. Dans **Create an AWS Java**, procédez comme suit :

   1. Dans **Project name (Nom de projet)**, saisissez un nom pour votre projet.

   1. Dans **Select Account**, choisissez votre profil d’informations d’identification dans la liste.

      Si c'est la première fois que vous utilisez le [AWS Toolkit for Eclipse](https://aws.amazon.com/eclipse/), choisissez **Configurer les AWS comptes** pour configurer vos AWS informations d'identification.

1. Choisissez **Finish** pour créer le projet.

1. Dans le menu **Eclipse**, choisissez **File**, **New**, puis **Class**.

1. Dans **Java Class (Classe Java)**, saisissez un nom pour votre classe dans **Name (Nom)** (utilisez le même nom que celui de l’exemple de code que vous souhaitez exécuter), puis choisissez **Finish (Terminer)** pour créer la classe.

1. Copiez l’exemple de code de la page de documentation dans l’éditeur Eclipse.

1. Pour exécuter le code, choisissez **Run (Exécuter)** dans le menu Eclipse.

Le kit SDK pour Java fournit des clients thread-safe à utiliser avec DynamoDB. En tant que bonne pratique, vos applications doivent créer un seul client et le réutiliser entre les threads.

Pour de plus amples informations, veuillez consulter [AWS SDK pour Java](https://aws.amazon.com/sdk-for-java).

**Note**  
Les exemples de code dans ce guide sont destinés à être utilisés avec la dernière version de AWS SDK pour Java.  
Si vous utilisez le AWS Toolkit for Eclipse, vous pouvez configurer des mises à jour automatiques pour le SDK for Java. Pour ce faire, dans Eclipse, allez dans **Préférences** et choisissez **AWS Toolkit**« **Télécharger le nouveau SDKs automatiquement** ». **AWS SDK pour Java**

## Java : Configuration de vos AWS informations d'identification
<a name="CodeSamples.Java.Credentials"></a>

Le SDK for Java nécessite que vous AWS fournissiez des informations d'identification à votre application lors de l'exécution. Les exemples de code présentés dans ce guide supposent que vous utilisez un fichier d' AWS informations d'identification, comme décrit dans la section [Configurer vos AWS informations d'identification](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/set-up-creds.html) dans le *guide du AWS SDK pour Java développeur*.

Voici un exemple de fichier d' AWS informations d'identification nommé`~/.aws/credentials`, où le caractère tilde (`~`) représente votre répertoire personnel.

```
[default]
aws_access_key_id = AWS access key ID goes here
aws_secret_access_key = Secret key goes here
```

## Java : définition de la AWS région et du point de terminaison
<a name="CodeSamples.Java.RegionAndEndpoint"></a>

Par défaut, les exemples de code accèdent à DynamoDB dans la région USA Ouest (Oregon). Vous pouvez modifier la région en modifiant les propriétés `AmazonDynamoDB`.

L’exemple de code suivant instancie un nouvel `AmazonDynamoDB`.

```
import software.amazon.dynamodb.AmazonDynamoDBClientBuilder;
import com.amazonaws.regions.Regions;
...
// This client will default to US West (Oregon)
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
.withRegion(Regions.US_WEST_2)
.build();
```

Vous pouvez utiliser la méthode `withRegion` pour exécuter votre code sur DynamoDB dans n’importe quelle région où il est disponible. Pour obtenir la liste complète, consultez [Régions et points de terminaison AWS](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region) dans le *Référence générale d'Amazon Web Services*.

Si vous souhaitez exécuter les exemples de code à l’aide de DynamoDB localement sur votre ordinateur, définissez le point de terminaison comme suit.

### AWS SDK V1
<a name="CodeSamples.Java.RegionAndEndpoint.V1"></a>

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "us-west-2"))
.build();
```

### AWS SDK V2
<a name="CodeSamples.Java.RegionAndEndpoint.V2"></a>

```
DynamoDbClient client = DynamoDbClient.builder()
    .endpointOverride(URI.create("http://localhost:8000"))
    // The region is meaningless for local DynamoDb but required for client builder validation
    .region(Region.US_EAST_1)
    .credentialsProvider(StaticCredentialsProvider.create(
    AwsBasicCredentials.create("dummy-key", "dummy-secret")))
    .build();
```

# Exemples de code .NET
<a name="CodeSamples.DotNet"></a>

**Topics**
+ [.NET : Configuration de vos AWS informations d'identification](#CodeSamples.DotNet.Credentials)
+ [.NET : définition de la AWS région et du point de terminaison](#CodeSamples.DotNet.RegionAndEndpoint)

Ce guide contient des extraits de code .NET et ready-to-run des programmes. Vous pouvez trouver ces exemples de code dans les sections suivantes :
+ [Utilisation d’éléments et d’attributs dans DynamoDB](WorkingWithItems.md)
+ [Utilisation de tables et de données dans DynamoDB](WorkingWithTables.md)
+ [Interrogation de tables dans DynamoDB](Query.md)
+ [Analyse de tables dans DynamoDB](Scan.md)
+ [Amélioration de l’accès aux données avec les index secondaires dans DynamoDB](SecondaryIndexes.md)
+ [Utilisation du modèle de document .NET dans DynamoDB](DotNetSDKMidLevel.md)
+ [Utilisation du modèle de persistance des objets .NET et de DynamoDB](DotNetSDKHighLevel.md)
+ [Modifier la récupération de données pour DynamoDB Streams](Streams.md)

Vous pouvez démarrer rapidement en utilisant le AWS SDK pour .NET Toolkit for Visual Studio.

**Pour exécuter les exemples de code .NET (à l’aide de Visual Studio)**

1. Téléchargez et installez [Microsoft Visual Studio](https://www.visualstudio.com).

1. (Facultatif) Téléchargez et installez le [Toolkit for Visual Studio](https://aws.amazon.com/visualstudio/).

1. Configurez vos AWS informations d'identification. Configurez un profil d'informations d'identification dans votre fichier AWS d'informations d'identification partagé (`~/.aws/credentials`). Pour de plus amples informations, veuillez consulter la section [Configurer les informations d'identification AWS](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html) du *Guide du développeur pour le kit AWS SDK pour .NET *.

1. Démarrez Visual Studio 2015. Choisissez **File (Fichier)**, **New (Nouveau)**, puis **Project (Projet)**.

1. Recherchez **Console App**, sélectionnez le modèle C\$1 qui cible .NET, puis choisissez **Next**. Configurez le nom et l'emplacement de votre projet, puis choisissez **Créer**.

1. Ajoutez le package AWS SDK pour NuGet DynamoDB à votre projet :

   1. Dans l'Explorateur de solutions, ouvrez le menu contextuel (clic droit) de votre projet, puis choisissez **Gérer les NuGet packages**.

   1. Dans le Gestionnaire de NuGet packages, choisissez **Parcourir**.

   1. Dans la zone de recherche, saisissez **AWSSDK.DynamoDBv2** et attendez la fin de la recherche.

   1. **Choisissez **AWSSDK.Dynamo DBv2**, puis choisissez Installer.**

1. Dans votre projet Visual Studio, ouvrez`Program.cs`. Remplacez le contenu par l'exemple de code de la page de documentation que vous souhaitez exécuter.

1. Pour exécuter le code, choisissez **Start (Début)** dans la barre d’outils Visual Studio.

 SDK pour .NET fournit des clients sécurisés pour travailler avec DynamoDB. En tant que bonne pratique, vos applications doivent créer un seul client et le réutiliser entre les threads.

Pour plus d’informations, consultez [Kit SDK AWS pour .NET](https://aws.amazon.com/sdk-for-net).

**Note**  
Les exemples de code dans ce guide sont destinés à être utilisés avec la dernière version de AWS SDK pour .NET.

## .NET : Configuration de vos AWS informations d'identification
<a name="CodeSamples.DotNet.Credentials"></a>

Vous devez fournir des AWS informations d'identification à votre application lors de l'exécution. SDK pour .NET Les exemples de code présentés dans ce guide supposent que vous utilisez le magasin du SDK pour gérer votre fichier AWS d'informations d'identification, comme décrit dans la section [Utilisation du magasin du SDK](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html#sdk-store) dans le manuel du *AWS SDK pour .NET développeur*.

Le Toolkit for Visual Studio prend en charge plusieurs jeux d’informations d’identification d’un nombre quelconque de comptes. Chaque ensemble est référencé comme *profil*. Visual Studio ajoute des entrées au `App.config` fichier du projet afin que votre application puisse trouver les AWS informations d'identification lors de l'exécution.

L’exemple suivant affiche le fichier `App.config` par défaut qui est généré lorsque vous créez un projet à l’aide du Toolkit for Visual Studio.

```
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
    <add key="AWSProfileName" value="default"/>
    <add key="AWSRegion" value="us-west-2" />
 </appSettings>
</configuration>
```

Au moment de l'exécution, le programme utilise l'`default`ensemble d' AWS informations d'identification, tel que spécifié par l'`AWSProfileName`entrée. Les AWS informations d'identification elles-mêmes sont conservées dans le SDK Store sous forme cryptée. Le Toolkit for Visual Studio fournit une interface utilisateur graphique pour gérer vos informations d’identification, le tout dans Visual Studio. Pour plus d’informations, consultez [Spécification d’informations d’identification](https://docs.aws.amazon.com/AWSToolkitVS/latest/UserGuide/tkv_setup.html#creds) dans le *Guide de l’utilisateur AWS Toolkit for Visual Studio *.

**Note**  
Par défaut, les exemples de code accèdent à DynamoDB dans la région USA Ouest (Oregon). Vous pouvez modifier la région en modifiant l’entrée `AWSRegion` dans le fichier App.config. Vous pouvez définir `AWSRegion` sur n’importe quelle région dans laquelle DynamoDB est disponible. Pour obtenir la liste complète, consultez [Régions et points de terminaison AWS](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region) dans le *Référence générale d'Amazon Web Services*.

## .NET : définition de la AWS région et du point de terminaison
<a name="CodeSamples.DotNet.RegionAndEndpoint"></a>

Par défaut, les exemples de code accèdent à DynamoDB dans la région USA Ouest (Oregon). Vous pouvez modifier la région en modifiant l’entrée `AWSRegion` dans le fichier `App.config`. Ou alors, vous pouvez modifier la région en modifiant les propriétés `AmazonDynamoDBClient`.

L’exemple de code suivant instancie un nouvel `AmazonDynamoDBClient`. Le client est modifié de telle sorte que le code s’exécute sur DynamoDB dans une autre région.

```
AmazonDynamoDBConfig clientConfig = new AmazonDynamoDBConfig();
// This client will access the US East 1 region.
clientConfig.RegionEndpoint = RegionEndpoint.USEast1;
AmazonDynamoDBClient client = new AmazonDynamoDBClient(clientConfig);
```

Pour obtenir la liste complète des régions prises en charge, consultez [Régions et points de terminaison AWS](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region) dans le *Référence générale d'Amazon Web Services*.

Si vous souhaitez exécuter les exemples de code à l’aide de DynamoDB localement sur votre ordinateur, définissez le point de terminaison comme suit.

```
AmazonDynamoDBConfig clientConfig = new AmazonDynamoDBConfig();
// Set the endpoint URL
clientConfig.ServiceURL = "http://localhost:8000";
AmazonDynamoDBClient client = new AmazonDynamoDBClient(clientConfig);
```

# API de bas niveau de DynamoDB
<a name="Programming.LowLevelAPI"></a>

L’*API de bas niveau* d’Amazon DynamoDB est l’interface au niveau du protocole pour DynamoDB. À ce niveau, chaque requête HTTPs doit être correctement mise en forme et présenter une signature numérique valide.

Ils créent AWS SDKs des requêtes d'API DynamoDB de bas niveau en votre nom et traitent les réponses de DynamoDB. Vous pouvez ainsi vous concentrer sur la logique de votre application, et non sur les détails de bas niveau. Cependant, vous pouvez continuer à bénéficier d’une connaissance de base du fonctionnement de l’API DynamoDB de bas niveau.

Pour plus d’informations sur l’API DynamoDB de bas niveau, consultez la [Référence d’API Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/).

**Note**  
DynamoDB Streams possède sa propre API de bas niveau, distincte de celle de DynamoDB et entièrement prise en charge par le. AWS SDKs  
Pour de plus amples informations, veuillez consulter [Modifier la récupération de données pour DynamoDB Streams](Streams.md). Pour l’API DynamoDB Streams de bas niveau, consultez la [Référence d’API Amazon DynamoDB Streams Reference](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Operations_Amazon_DynamoDB_Streams.html).

L'API DynamoDB de bas niveau JavaScript utilise la notation d'objet (JSON) comme format de protocole filaire. JSON présentant les données selon une hiérarchie, les valeurs des données et la structure des données sont transmises en même temps. Les paires nom-valeur sont définies au format `name:value`. La hiérarchie des données est définie par les crochets imbriqués des paires nom-valeur.

DynamoDB n’utilise JSON que comme protocole de transport, pas comme format de stockage. Ils AWS SDKs utilisent JSON pour envoyer des données à DynamoDB, et DynamoDB répond par JSON. DynamoDB ne stocke pas de données de manière persistante au format JSON.

**Note**  
Pour plus d’informations sur JSON, consultez [Introducing JSON](http://json.org) sur le site web `JSON.org`.

**Topics**
+ [Format des demandes](#Programming.LowLevelAPI.RequestFormat)
+ [Format de la réponse](#Programming.LowLevelAPI.ResponseFormat)
+ [Descripteurs de type de données](#Programming.LowLevelAPI.DataTypeDescriptors)
+ [Données numériques](#Programming.LowLevelAPI.Numbers)
+ [Données binaires](#Programming.LowLevelAPI.Binary)

![\[API de bas niveau DynamoDB et AWS SDKs comment gérer les demandes et réponses au niveau du protocole.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/SDKSupport.DDBLowLevelAPI.png)


## Format des demandes
<a name="Programming.LowLevelAPI.RequestFormat"></a>

L’API de bas niveau DynamoDB accepte des requêtes HTTP(S) `POST` en entrée. Ils AWS SDKs élaborent ces demandes pour vous.

Supposons que vous ayez une table nommée `Pets`, avec un schéma de clé composé de `AnimalType` (clé de partition) et `Name` (clé de tri). Ces deux attributs sont de type `string`. Pour récupérer un élément`Pets`, le AWS SDK crée la demande suivante.

```
POST / HTTP/1.1
Host: dynamodb.<region>.<domain>;
Accept-Encoding: identity
Content-Length: <PayloadSizeBytes>
User-Agent: <UserAgentString>
Content-Type: application/x-amz-json-1.0
Authorization: AWS4-HMAC-SHA256 Credential=<Credential>, SignedHeaders=<Headers>, Signature=<Signature>
X-Amz-Date: <Date> 
X-Amz-Target: DynamoDB_20120810.GetItem

{
    "TableName": "Pets",
    "Key": {
        "AnimalType": {"S": "Dog"},
        "Name": {"S": "Fido"}
    }
}
```

Notez ce qui suit à propos de cette demande :
+ L’en-tête `Authorization` contient les informations requises pour DynamoDB pour authentifier la demande. Pour plus d'informations, voir les [demandes d' AWS API](https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html) de [signature et le processus de signature de la version 4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) de Signature dans le *Référence générale d'Amazon Web Services*.
+ L’en-tête `X-Amz-Target` contient le nom d’une opération DynamoDB : `GetItem`. (On y trouve aussi la version de l’API de bas niveau, dans ce cas `20120810`.)
+ La charge utile (corps) de la demande contient les paramètres de l’opération, au format JSON. Pour l’opération `GetItem`, les paramètres sont `TableName` et `Key`.

## Format de la réponse
<a name="Programming.LowLevelAPI.ResponseFormat"></a>

À la réception de la demande, DynamoDB la traite et renvoie une réponse. Pour la demande illustrée précédemment, la charge utile de la réponse HTTP(S) contient les résultats de l’opération, comme dans l’exemple suivant.

```
HTTP/1.1 200 OK
x-amzn-RequestId: <RequestId>
x-amz-crc32: <Checksum>
Content-Type: application/x-amz-json-1.0
Content-Length: <PayloadSizeBytes>
Date: <Date>
{
    "Item": {
        "Age": {"N": "8"},
        "Colors": {
            "L": [
                {"S": "White"},
                {"S": "Brown"},
                {"S": "Black"}
            ]
        },
        "Name": {"S": "Fido"},
        "Vaccinations": {
            "M": {
                "Rabies": {
                    "L": [
                        {"S": "2009-03-17"},
                        {"S": "2011-09-21"},
                        {"S": "2014-07-08"}
                    ]
                },
                "Distemper": {"S": "2015-10-13"}
            }
        },
        "Breed": {"S": "Beagle"},
        "AnimalType": {"S": "Dog"}
    }
}
```

À ce stade, le AWS SDK renvoie les données de réponse à votre application pour un traitement ultérieur.

**Note**  
Si DynamoDB ne peut pas traiter une demande, il renvoie un code et un message d’erreur HTTP. Le kit SDK  AWS transmet ceux-ci à votre application sous la forme d’exceptions. Pour de plus amples informations, veuillez consulter [Gestion des erreurs avec DynamoDB](Programming.Errors.md).

## Descripteurs de type de données
<a name="Programming.LowLevelAPI.DataTypeDescriptors"></a>

Le protocole de l’API DynamoDB de bas niveau nécessite que chaque attribut soit accompagné d’un descripteur de type de données. Les *descripteurs de type de données* sont des jetons qui indiquent à DynamoDB comment interpréter chaque attribut.

Les exemples de [Format des demandes](#Programming.LowLevelAPI.RequestFormat)et [Format de la réponse](#Programming.LowLevelAPI.ResponseFormat) expliquent comment les descripteurs de type de données sont utilisés. La demande `GetItem` spécifie `S` pour les attributs du schéma de clé de `Pets` (`AnimalType` et `Name`), qui sont de type `string`. La réponse `GetItem` contient un élément *Pets* avec des attributs de type `string` (`S`), `number` (`N`), `map` (`M`) et `list` (`L`).

La liste suivante est la liste complète des descripteurs de type de données DynamoDB :
+ **`S`** – String (chaîne)
+ **`N`** – Number (nombre)
+ **`B`** – Binary (binaire)
+ **`BOOL`** – Boolean (booléen)
+ **`NULL`** – Null
+ **`M`** – Map (mappage)
+ **`L`** – List (liste)
+ **`SS`** – String Set (ensemble de chaînes)
+ **`NS`** – Number Set (ensemble de nombres)
+ **`BS`** – Binary Set (ensemble de binaires)

Le tableau suivant indique le format JSON correct pour chaque descripteur de type de données. Notez que les nombres sont représentés sous forme de chaînes pour préserver la précision, tandis que les booléens et les valeurs nulles utilisent leurs types JSON natifs.


| Descripteur | Format JSON | Remarques | 
| --- | --- | --- | 
| S | \$1"S": "Hello"\$1 | La valeur est une chaîne JSON. | 
| N | \$1"N": "123.45"\$1 | La valeur est une chaîne, pas un nombre JSON. Cela permet de préserver la précision dans toutes les langues. | 
| B | \$1"B": "dGhpcyBpcyBhIHRlc3Q="\$1 | La valeur est une chaîne codée en base64. | 
| BOOL | \$1"BOOL": true\$1 | La valeur est un booléen JSON (trueoufalse), pas une chaîne. | 
| NULL | \$1"NULL": true\$1 | La valeur est le booléen JSON indiquant true la valeur nulle. | 
| M | \$1"M": \$1"Name": \$1"S": "Joe"\$1\$1\$1 | La valeur est un objet JSON composé de paires nom-valeur d'attribut. | 
| L | \$1"L": [\$1"S": "Red"\$1, \$1"N": "5"\$1]\$1 | La valeur est un tableau JSON de valeurs d'attributs. | 
| SS | \$1"SS": ["Red", "Blue"]\$1 | La valeur est un tableau JSON de chaînes. | 
| NS | \$1"NS": ["1", "2.5"]\$1 | La valeur est un tableau JSON de chaînes numériques. | 
| BS | \$1"BS": ["U3Vubnk=", "UmFpbnk="]\$1 | La valeur est un tableau JSON de chaînes codées en base64. | 

**Note**  
 Pour une description détaillée des types de données DynamoDB, consultez [Types de données](HowItWorks.NamingRulesDataTypes.md#HowItWorks.DataTypes).

## Données numériques
<a name="Programming.LowLevelAPI.Numbers"></a>

Les différents langages de programmation offrent différents niveaux de prise en charge de JSON. Dans certains cas, vous pouvez décider d’utiliser une bibliothèque tierce pour la validation et l’analyse des documents JSON.

Certaines bibliothèques tierces reposent sur le type de numéro JSON et fournissent leurs propres types, tels que `int`, `long` ou `double`. Toutefois, le type de données Number (nombre) natif dans DynamoDB ne correspondant pas exactement à ces autres types de données, ces distinctions de type peuvent entraîner des conflits. En outre, de nombreuses bibliothèques JSON ne gèrent pas les valeurs numériques de précision fixe et en déduisent automatiquement un type de données double pour les séquences numériques contenant une virgule.

Pour résoudre ces problèmes, DynamoDB propose un seul type numérique sans perte de données. Pour éviter des conversions implicites indésirables en valeur double, DynamoDB utilise des chaînes pour le transfert de données de valeurs numériques. Cette approche offre une flexibilité pour la mise à jour des valeurs d’attribut tout en assurant la sémantique de tri appropriée, comme le placement des valeurs « 01 », « 2 » et « 03 » dans le bon ordre.

Si la précision numérique est importante pour votre application, vous devez convertir les valeurs numériques en chaînes avant de les passer à DynamoDB.

## Données binaires
<a name="Programming.LowLevelAPI.Binary"></a>

DynamoDB prend en charge les attributs binaires. Cependant, JSON ne prend pas en charge en mode natif le codage binaire. Pour envoyer les données binaires dans une demande, vous devez les encoder au format base64. À la réception de la demande, DynamoDB décode les données en base 64 pour les convertir en binaires. 

Le schéma de codage en base 64 que DynamoDB utilise est décrit dans la rubrique [RFC 4648](http://tools.ietf.org/html/rfc4648) sur le site web de l’Internet Engineering Task Force (IETF).

# Programmation d’Amazon DynamoDB avec Python et Boto3
<a name="programming-with-python"></a>

Ce guide de programmation fournit une orientation aux programmeurs qui souhaitent utiliser Amazon DynamoDB avec Python. Découvrez les différentes couches d’abstraction, la gestion de la configuration, la gestion des erreurs, le contrôle des politiques de nouvelles tentatives, la gestion de keep-alive, etc.

**Topics**
+ [À propos de Boto](#programming-with-python-about)
+ [Utilisation de la documentation Boto](#programming-with-python-documentation)
+ [Comprendre les couches d’abstraction du client et des ressources](#programming-with-python-client-resource)
+ [Utilisation de la ressource de table batch\$1writer](#programming-with-python-batch-writer)
+ [Exemples supplémentaires de code qui explorent les couches client et ressources](#programming-with-python-additional-code)
+ [Compréhension de la façon dont les objets Client et Ressource interagissent avec les sessions et les threads](#programming-with-python-sessions-thread-safety)
+ [Personnalisation de l’objet Configuration](#programming-with-python-config)
+ [Gestion des erreurs](#programming-with-python-error-handling)
+ [Logging](#programming-with-python-logging)
+ [Hooks d’événement](#programming-with-python-event-hooks)
+ [Pagination et paginateur](#programming-with-python-pagination)
+ [Programmes d’attente](#programming-with-python-waiters)

## À propos de Boto
<a name="programming-with-python-about"></a>

**Vous pouvez accéder à DynamoDB depuis Python en utilisant AWS le SDK officiel pour Python, communément appelé Boto3.** Le nom Boto (prononcé boh-toh) vient d’un dauphin d’eau douce originaire du fleuve Amazon. La bibliothèque Boto3 est la troisième version majeure de la bibliothèque, publiée pour la première fois en 2015. La bibliothèque Boto3 est assez volumineuse, car elle prend en charge tous les AWS services, pas seulement DynamoDB. Cette orientation cible uniquement les parties de Boto3 pertinentes pour DynamoDB.

Boto est maintenu et publié par AWS un projet open source hébergé sur. GitHub Il est divisé en deux packages : [Botocore](https://github.com/boto/botocore) et [Boto3](https://github.com/boto/boto3).
+ **Botocore** fournit les fonctionnalités de bas niveau. Dans Botocore, vous trouverez le client, la session, les informations d’identification, la configuration et les classes d’exception. 
+ **Boto3** s’appuie sur Botocore. Il propose une interface de plus haut niveau, plus pythonique. Plus précisément, il expose une table DynamoDB en tant que ressource et propose une interface plus simple et plus élégante par rapport à l’interface client de niveau inférieur axée sur les services.

Ces projets étant hébergés sur GitHub, vous pouvez consulter le code source, suivre les problèmes en suspens ou soumettre vos propres problèmes.

## Utilisation de la documentation Boto
<a name="programming-with-python-documentation"></a>

Démarrez avec la documentation Boto grâce aux ressources suivantes :
+ Commencez par la [section Quickstart](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html) qui fournit un point de départ solide pour l’installation du package. Consultez cette page pour obtenir des instructions sur l'installation de Boto3 si ce n'est pas déjà fait (Boto3 est souvent automatiquement disponible dans des AWS services tels que). AWS Lambda
+ Ensuite, concentrez-vous sur le [Guide de DynamoDB](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/dynamodb.html) de la documentation. Il explique comment effectuer les activités de base de DynamoDB : créer et supprimer une table, manipuler des éléments, exécuter des opérations par lots, exécuter une requête et effectuer une analyse. Ses exemples utilisent l’interface de **ressources**. Lorsque vous voyez `boto3.resource('dynamodb')`, cela indique que vous utilisez l’interface de **ressources** de niveau supérieur.
+ Après le guide, vous pouvez consulter la [Référence de DynamoDB](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html). Cette page d’accueil fournit une liste exhaustive des classes et des méthodes mises à votre disposition. La classe `DynamoDB.Client` s’affiche en haut. Cela fournit un accès de bas niveau à toutes les opérations du plan de contrôle et du plan de données. En bas, vous voyez la classe `DynamoDB.ServiceResource`. Il s’agit de l’interface pythonique de niveau supérieur. Elle vous permet de créer une table, d’effectuer des opérations par lots sur des tables ou d’obtenir une instance `DynamoDB.ServiceResource.Table` pour des actions spécifiques à une table.

## Comprendre les couches d’abstraction du client et des ressources
<a name="programming-with-python-client-resource"></a>

Les deux interfaces que vous allez utiliser sont l’interface **client** et l’interface de **ressources**. 
+ L’interface **client** de bas niveau fournit un mappage 1-à-1 vers l’API de service sous-jacente. Chaque API proposée par DynamoDB est disponible via le client. Cela signifie que l’interface client peut fournir des fonctionnalités complètes, mais elle est souvent plus détaillée et complexe à utiliser.
+ L’interface de **ressources** de niveau supérieur ne fournit pas de mappage 1-à-1 de l’API de service sous-jacente. Cependant, elle fournit des méthodes qui vous permettent d’accéder plus facilement au service, telles que `batch_writer`.

Voici un exemple d’insertion d’un élément à l’aide de l’interface client. Vous remarquerez que toutes les valeurs sont transmises sous forme de carte avec la clé indiquant leur type (« S » pour chaîne, « N » pour nombre) et leur valeur sous forme de chaîne. C’est ce que l’on appelle le format JSON DynamoDB.

```
import boto3

dynamodb = boto3.client('dynamodb')

dynamodb.put_item(
    TableName='YourTableName',
    Item={
        'pk': {'S': 'id#1'},
        'sk': {'S': 'cart#123'},
        'name': {'S': 'SomeName'},
        'inventory': {'N': '500'},
        # ... more attributes ...
    }
)
```

Voici la même opération `PutItem` à l’aide de l’interface de ressources. La saisie des données est implicite :

```
import boto3

dynamodb = boto3.resource('dynamodb')

table = dynamodb.Table('YourTableName')

table.put_item(
    Item={
        'pk': 'id#1',
        'sk': 'cart#123',
        'name': 'SomeName',
        'inventory': 500,
        # ... more attributes ...
    }
)
```

Si nécessaire, vous pouvez effectuer une conversion entre le JSON normal et le JSON DynamoDB à l’aide des classes `TypeSerializer` et `TypeDeserializer` fournies avec boto3 :

```
def dynamo_to_python(dynamo_object: dict) -> dict:
    deserializer = TypeDeserializer()
    return {
        k: deserializer.deserialize(v) 
        for k, v in dynamo_object.items()
    }  
  
def python_to_dynamo(python_object: dict) -> dict:
    serializer = TypeSerializer()
    return {
        k: serializer.serialize(v)
        for k, v in python_object.items()
    }
```

Voici comment effectuer une requête à l’aide de l’interface client. Elle exprime la requête sous forme de construction JSON. Elle utilise une chaîne `KeyConditionExpression` qui nécessite une substitution de variable pour gérer tout conflit de mots clés potentiel :

```
import boto3

client = boto3.client('dynamodb')

# Construct the query
response = client.query(
    TableName='YourTableName',
    KeyConditionExpression='pk = :pk_val AND begins_with(sk, :sk_val)',
    FilterExpression='#name = :name_val',
    ExpressionAttributeValues={
        ':pk_val': {'S': 'id#1'},
        ':sk_val': {'S': 'cart#'},
        ':name_val': {'S': 'SomeName'},
    },
    ExpressionAttributeNames={
        '#name': 'name',
    }
)
```

La même opération de requête utilisant l’interface de ressources peut être raccourcie et simplifiée :

```
import boto3
from boto3.dynamodb.conditions import Key, Attr

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('YourTableName')

response = table.query(
    KeyConditionExpression=Key('pk').eq('id#1') & Key('sk').begins_with('cart#'),
    FilterExpression=Attr('name').eq('SomeName')
)
```

Enfin, imaginez que vous souhaitiez obtenir la taille approximative d’une table (c’est-à-dire les métadonnées conservées sur la table et mises à jour toutes les 6 heures environ). Avec l’interface client, vous effectuez une opération `describe_table()` et vous extrayez la réponse de la structure JSON renvoyée :

```
import boto3

dynamodb = boto3.client('dynamodb')

response = dynamodb.describe_table(TableName='YourTableName')
size = response['Table']['TableSizeBytes']
```

Avec l’interface de ressources, la table exécute implicitement l’opération de description et présente les données directement sous forme d’attribut :

```
import boto3

dynamodb = boto3.resource('dynamodb')

table = dynamodb.Table('YourTableName')
size = table.table_size_bytes
```

**Note**  
Lorsque vous envisagez de développer à l'aide de l'interface client ou de l'interface des ressources, sachez que les nouvelles fonctionnalités ne seront pas ajoutées à l'interface des ressources conformément à la [documentation des ressources](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/resources.html) : « L'équipe du SDK AWS Python n'a pas l'intention d'ajouter de nouvelles fonctionnalités à l'interface des ressources dans boto3. Les interfaces existantes continueront de fonctionner pendant le cycle de vie de boto3. Les clients peuvent accéder aux nouvelles fonctionnalités du service via l’interface client. »

## Utilisation de la ressource de table batch\$1writer
<a name="programming-with-python-batch-writer"></a>

Une commodité disponible uniquement avec la ressource de table de niveau supérieur est `batch_writer`. DynamoDB prend en charge les opérations d’écriture par lots, ce qui permet d’effectuer jusqu’à 25 opérations de saisie ou de suppression par requête réseau. Un tel traitement par lots améliore l’efficacité en minimisant les allers-retours sur le réseau.

Avec la bibliothèque client de bas niveau, vous utilisez l’opération `client.batch_write_item()` pour exécuter des lots. Vous devez diviser manuellement votre travail en lots de 25. Après chaque opération, vous devez également demander à recevoir une liste des éléments non traités (certaines opérations d’écriture peuvent réussir tandis que d’autres peuvent échouer). Vous devez ensuite retransmettre ces éléments non traités à une opération `batch_write_item()` ultérieure. Il y a une quantité importante de code standard.

La méthode [Table.batch\$1writer](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/table/batch_writer.html) crée un gestionnaire de contexte pour écrire des objets dans un lot. Elle présente une interface dans laquelle vous avez l’impression d’écrire des éléments un par un, mais en interne, elle les met en mémoire tampon et les envoie par lots. Elle gère également implicitement les nouvelles tentatives d’éléments non traités.

```
dynamodb = boto3.resource('dynamodb')

table = dynamodb.Table('YourTableName')

movies = # long list of movies in {'pk': 'val', 'sk': 'val', etc} format
with table.batch_writer() as writer:
    for movie in movies:
        writer.put_item(Item=movie)
```

## Exemples supplémentaires de code qui explorent les couches client et ressources
<a name="programming-with-python-additional-code"></a>

Vous pouvez également consulter les référentiels d’exemples de code suivants qui explorent l’utilisation des différentes fonctions, en utilisant à la fois le client et les ressources :
+ [Exemples de codes à action unique AWS officiels.](https://docs.aws.amazon.com/code-library/latest/ug/python_3_dynamodb_code_examples.html) 
+ [Exemples de AWS code officiels orientés vers des scénarios.](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/python)
+ [Exemples de code à action unique gérés par la communauté.](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/examples/SDK/python)

## Compréhension de la façon dont les objets Client et Ressource interagissent avec les sessions et les threads
<a name="programming-with-python-sessions-thread-safety"></a>

L’objet Resource n’est pas adapté aux threads et ne doit pas être partagé entre les threads ou les processus. Pour plus d’informations, reportez-vous au [Guide sur Ressource](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/resources.html#multithreading-or-multiprocessing-with-resources).

L’objet Client, en revanche, est généralement adapté aux threads, à l’exception de certaines fonctionnalités avancées. Pour plus d’informations, reportez-vous au [Guide sur Clients](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/clients.html#multithreading-or-multiprocessing-with-clients). 

L’objet Session n’est pas adapté aux threads. Ainsi, chaque fois que vous créez un objet Client ou Ressource dans un environnement multithread, vous devez d’abord créer un nouvel objet Session, puis créer l’objet Client ou Ressource à partir de Session. Pour plus d’informations, reportez-vous au [Guide sur Sessions](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/session.html#multithreading-or-multiprocessing-with-sessions). 

Lorsque vous appelez la `boto3.resource()`, vous utilisez implicitement l’objet Session par défaut. C’est pratique pour écrire du code à thread unique. Lorsque vous écrivez du code multithread, vous devez d’abord créer un nouvel objet Session pour chaque thread, puis récupérer la ressource de cet objet Session :

```
# Explicitly create a new Session for this thread 
session = boto3.Session()
dynamodb = session.resource('dynamodb')
```

## Personnalisation de l’objet Configuration
<a name="programming-with-python-config"></a>

Lorsque vous créez un objet Client ou Ressource, vous pouvez transmettre des paramètres nommés facultatifs pour personnaliser le comportement. Le paramètre nommé `config` déverrouille diverses fonctionnalités. Il s’agit d’une instance de `botocore.client.Config` et la [documentation de référence de Configuration](https://botocore.amazonaws.com/v1/documentation/api/latest/reference/config.html) montre tout ce qu’il vous expose pour que vous puissiez le contrôler. Le [Guide de Configuration](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html) fournit une bonne vue d’ensemble.

**Note**  
Vous pouvez modifier bon nombre de ces paramètres comportementaux au niveau de Session, dans le fichier de configuration AWS ou en tant que variables d’environnement.

**Configuration pour les délais d’expiration**

L’une des utilisations d’une configuration personnalisée consiste à ajuster les comportements réseau :
+ **connect\$1timeout (float ou int)** : durée en secondes avant qu’une exception de délai d’expiration ne soit déclenchée lors d’une tentative d’établissement d’une connexion. Le durée par défaut est de 60 secondes.
+ **read\$1timeout (float ou int)** : durée en secondes avant qu’une exception de délai d’expiration ne soit déclenchée lors d’une tentative de lecture à partir d’une connexion. Le durée par défaut est de 60 secondes.

Les délais d’expiration de 60 secondes sont excessifs pour DynamoDB. Cela signifie qu’un problème réseau passager retardera le client d’une minute avant qu’il ne puisse réessayer. Le code suivant réduit les délais d’expiration à une seconde :

```
import boto3
from botocore.config import Config

my_config = Config(
   connect_timeout = 1.0,
   read_timeout = 1.0
)
dynamodb = boto3.resource('dynamodb', config=my_config)
```

Pour en savoir plus sur les délais d'attente, consultez la section [Réglage des paramètres de requête HTTP du SDK AWS Java pour les applications DynamoDB sensibles à la latence.](https://aws.amazon.com/blogs/database/tuning-aws-java-sdk-http-request-settings-for-latency-aware-amazon-dynamodb-applications/) Notez que le kit Java SDK possède plus de configurations de délai d’expiration que Python.

**Configuration pour keep-alive**

Si vous utilisez botocore 1.27.84 ou version ultérieure, vous pouvez également contrôler **TCP Keep-Alive** :
+ **tcp\$1keepalive** (bool) : active l’option de socket TCP Keep-Alive utilisée lors de la création de nouvelles connexions si elle est définie sur `True` (par défaut sur `False`). Ceci n’est disponible qu’à partir de botocore 1.27.84.

La définition de TCP Keep-Alive sur `True` peut réduire les latences moyennes. Voici un exemple de code qui définit de manière conditionnelle TCP Keep-Alive sur true lorsque vous disposez de la bonne version de botocore :

```
import botocore
import boto3
from botocore.config import Config
from distutils.version import LooseVersion

required_version = "1.27.84"
current_version = botocore.__version__

my_config = Config(
   connect_timeout = 0.5,
   read_timeout = 0.5
)
if LooseVersion(current_version) > LooseVersion(required_version):
    my_config = my_config.merge(Config(tcp_keepalive = True))

dynamodb = boto3.resource('dynamodb', config=my_config)
```

**Note**  
TCP Keep-Alive est différent de HTTP Keep-Alive. Avec TCP Keep-Alive, de petits paquets sont envoyés par le système d’exploitation sous-jacent via la connexion socket afin de maintenir la connexion active et de détecter immédiatement toute perte. Avec HTTP Keep-Alive, la connexion web établie sur le socket sous-jacent est réutilisée. HTTP Keep-Alive est toujours activé avec boto3.

Il y a une limite à la durée pendant laquelle une connexion inactive peut être maintenue en vie. Envisagez d’envoyer des demandes périodiques (disons toutes les minutes) si vous avez une connexion inactive mais que vous souhaitez que la prochaine demande utilise une connexion déjà établie.

**Configuration pour les nouvelles tentatives**

La configuration accepte également un dictionnaire appelé **nouvelles tentatives** dans lequel vous pouvez spécifier le comportement de nouvelle tentative souhaité. Les nouvelles tentatives se produisent dans le kit SDK lorsque celui-ci reçoit une erreur et que l’erreur est de type passager. Si une erreur fait l’objet d’une nouvelle tentative en interne (et qu’une nouvelle tentative produit finalement une réponse de réussite), aucune erreur n’est détectée du point de vue du code appelant, juste une latence légèrement élevée. Voici les valeurs que vous pouvez spécifier :
+ **max\$1attempts** : entier représentant le nombre maximal de nouvelles tentatives qui seront effectuées sur une seule demande. Par exemple, si vous définissez cette valeur sur 2, la demande fait l’objet d’un maximum de deux nouvelles tentatives après la demande initiale. Si cette valeur est définie sur 0, aucune nouvelle tentative n’a lieu après la demande initiale. 
+ **total\$1max\$1attempts** : entier représentant le nombre maximal de nouvelles tentatives qui seront effectuées sur une seule demande. Cela inclut la demande initiale, donc une valeur de 1 indique qu’aucune demande ne fera l’objet d’une nouvelle tentative. Si `total_max_attempts` et `max_attempts` sont fournis, `total_max_attempts` a priorité. `total_max_attempts` et est préféré à `max_attempts`, car elle correspond à la variable d’environnement `AWS_MAX_ATTEMPTS` et à la valeur de fichier de configuration `max_attempts`.
+ **mode** : chaîne représentant le type de mode de nouvelle tentative que botocore doit utiliser. Les valeurs valides sont :
  + **legacy** : mode par défaut. Attend 50 ms lors de la première nouvelle tentative, puis utilise un backoff exponentiel avec un facteur de base de 2. Pour DynamoDB, il effectue jusqu’à 10 tentatives maximum au total (sauf si vous remplacez la valeur par la valeur ci-dessus).
**Note**  
Avec un backoff exponentiel, la dernière tentative attendra près de 13 secondes.
  + **standard** — Nommé standard parce qu'il est plus cohérent avec les autres AWS SDKs. Attend pendant un temps aléatoire compris entre 0 ms et 1 000 ms pour la première nouvelle tentative. Si une autre nouvelle tentative est nécessaire, il choisit un autre temps aléatoire compris entre 0 ms et 1 000 ms et le multiplie par 2. Si une nouvelle tentative supplémentaire est nécessaire, il effectue le même choix aléatoire multiplié par 4, et ainsi de suite. Chaque attente est limitée à 20 secondes. Ce mode effectue de nouvelles tentatives sur un plus grand nombre de conditions de défaillance détectées que le mode `legacy`. Pour DynamoDB, il effectue jusqu’à 3 tentatives maximum au total (sauf si vous remplacez la valeur par la valeur ci-dessus). 
  + **adaptative** : mode de nouvelle tentative expérimental qui inclut toutes les fonctionnalités du mode standard, mais ajoute une limitation automatique côté client. La limitation adaptative du débit SDKs peut ralentir le rythme d'envoi des demandes afin de mieux répondre à la capacité des AWS services. Il s’agit d’un mode provisoire dont le comportement est susceptible de changer. 

Vous trouverez une définition détaillée de ces modes de nouvelle tentative dans le [Guide des nouvelles tentatives](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/retries.html) ainsi que dans [Comportement des tentatives dans la référence du kit SDK](https://docs.aws.amazon.com/sdkref/latest/guide/feature-retry-behavior.html).

Voici un exemple qui utilise explicitement la politique de nouvelles tentatives `legacy` avec un maximum de 3 demandes au total (2 nouvelles tentatives) :

```
import boto3
from botocore.config import Config

my_config = Config(
   connect_timeout = 1.0,
   read_timeout = 1.0,
   retries = {
     'mode': 'legacy',
     'total_max_attempts': 3
   }
)
dynamodb = boto3.resource('dynamodb', config=my_config)
```

DynamoDB étant un système à haute disponibilité et à faible latence, vous souhaiterez peut-être adopter une vitesse de nouvelle tentative plus rapide que ne le permettent les politiques de nouvelles tentatives intégrées. Vous pouvez implémenter votre propre politique de nouvelles tentatives en fixant le nombre maximum de tentatives à 0, en détectant vous-même les exceptions et en réessayant le cas échéant à partir de votre propre code au lieu de compter sur boto3 pour effectuer des nouvelles tentatives implicites.

Si vous gérez votre propre stratégie de nouvelle tentative, vous devez faire la différence entre les limitations et les erreurs :
+ Une **limitation** (indiquée par une `ProvisionedThroughputExceededException` ou une `ThrottlingException`) indique un service en bonne santé qui vous informe que vous avez dépassé votre capacité de lecture ou d’écriture sur une table ou une partition DynamoDB. Chaque milliseconde qui passe, un peu plus de capacité de lecture ou d’écriture est disponible, ce qui vous permet d’effectuer rapidement une nouvelle tentative (par exemple toutes les 50 ms) pour tenter d’accéder à cette capacité nouvellement libérée. Avec les limitations, vous n’avez pas particulièrement besoin de backoff exponentiel, car les limitations sont légères pour que DynamoDB les renvoie et n’entraînent aucun frais par demande pour vous. Le backoff exponentiel affecte des délais plus longs aux threads client qui ont déjà attendu le plus longtemps, ce qui étend statistiquement les p50 et p99 vers l’extérieur.
+ Une **erreur** (indiquée par `InternalServerError` ou `ServiceUnavailable`, entre autres) indique un problème passager avec le service. Cela peut concerner l’ensemble de la table ou simplement la partition sur laquelle vous lisez ou sur laquelle vous écrivez. En cas d’erreur, vous pouvez faire une pause plus longue avant de d’effectuer de nouvelles tentatives (250 ms ou 500 ms, par exemple) et utiliser l’instabilité pour échelonner les nouvelles tentatives.

**Configuration pour le nombre maximum de connexions au groupe**

Enfin, la configuration vous permet de contrôler la taille du groupe de connexions :
+ **max\$1pool\$1connections (int)** : nombre maximum de connexions à conserver dans un groupe de connexions. Si cette valeur n’est pas spécifiée, la valeur par défaut de 10 est utilisée.

Cette option contrôle le nombre maximum de connexions HTTP à conserver en groupe en vue de leur réutilisation. Un groupe différent est conservé par session. Si vous prévoyez que plus de 10 threads vont à l’encontre de clients ou de ressources créés à partir de la même session, vous devriez envisager de l’augmenter, afin que les threads n’aient pas à attendre d’autres threads utilisant une connexion groupée.

```
import boto3
from botocore.config import Config

my_config = Config(
   max_pool_connections = 20
)

# Setup a single session holding up to 20 pooled connections
session = boto3.Session(my_config)

# Create up to 20 resources against that session for handing to threads
# Notice the single-threaded access to the Session and each Resource
resource1 = session.resource('dynamodb')
resource2 = session.resource('dynamodb')
# etc
```

## Gestion des erreurs
<a name="programming-with-python-error-handling"></a>

AWS les exceptions de service ne sont pas toutes définies de manière statique dans Boto3. Cela est dû au fait que les erreurs et les exceptions liées AWS aux services varient considérablement et sont susceptibles d'être modifiées. Boto3 enveloppe toutes les exceptions de service sous forme de `ClientError` et expose les détails en tant que JSON structuré. Par exemple, une réponse d’erreur peut être structurée comme suit :

```
{
    'Error': {
        'Code': 'SomeServiceException',
        'Message': 'Details/context around the exception or error'
    },
    'ResponseMetadata': {
        'RequestId': '1234567890ABCDEF',
        'HostId': 'host ID data will appear here as a hash',
        'HTTPStatusCode': 400,
        'HTTPHeaders': {'header metadata key/values will appear here'},
        'RetryAttempts': 0
    }
}
```

Le code suivant détecte toutes les exceptions `ClientError` et examine la valeur de chaîne de caractères du `Code` dans `Error` pour déterminer l’action à entreprendre :

```
import botocore
import boto3

dynamodb = boto3.client('dynamodb')

try:
    response = dynamodb.put_item(...)

except botocore.exceptions.ClientError as err:
    print('Error Code: {}'.format(err.response['Error']['Code']))
    print('Error Message: {}'.format(err.response['Error']['Message']))
    print('Http Code: {}'.format(err.response['ResponseMetadata']['HTTPStatusCode']))
    print('Request ID: {}'.format(err.response['ResponseMetadata']['RequestId']))

    if err.response['Error']['Code'] in ('ProvisionedThroughputExceededException', 'ThrottlingException'):
        print("Received a throttle")
    elif err.response['Error']['Code'] == 'InternalServerError':
        print("Received a server error")
    else:
        raise err
```

Certains codes d’exception (mais pas tous) ont été matérialisés sous forme de classes de premier niveau. Vous pouvez choisir de les gérer directement. Lorsque vous utilisez l’interface Client, ces exceptions sont renseignées dynamiquement sur le client et vous pouvez les intercepter à l’aide de l’instance client, comme suit :

```
except ddb_client.exceptions.ProvisionedThroughputExceededException:
```

Lorsque vous utilisez l’interface Ressource, vous devez utiliser `.meta.client` pour passer de la ressource au Client sous-jacent pour accéder aux exceptions, comme ceci :

```
except ddb_resource.meta.client.exceptions.ProvisionedThroughputExceededException:
```

Pour consulter la liste des types d’exception matérialisés, vous pouvez générer la liste de manière dynamique :

```
ddb = boto3.client("dynamodb")
print([e for e in dir(ddb.exceptions) if e.endswith('Exception') or e.endswith('Error')])
```

Lorsque vous effectuez une opération d’écriture avec une expression de condition, vous pouvez demander qu’en cas d’échec de l’expression, la valeur de l’élément soit renvoyée dans la réponse d’erreur.

```
try:
    response = table.put_item(
        Item=item,
        ConditionExpression='attribute_not_exists(pk)',
        ReturnValuesOnConditionCheckFailure='ALL_OLD'
    )
except table.meta.client.exceptions.ConditionalCheckFailedException as e:
    print('Item already exists:', e.response['Item'])
```

Pour en savoir plus sur la gestion des erreurs et les exceptions, consultez :
+ Le [guide boto3 sur la gestion des erreurs](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/error-handling.html) contient plus d’informations sur les techniques de gestion des erreurs. 
+ La [section du guide du développeur DynamoDB consacrée aux erreurs de programmation](Programming.Errors.md) répertorie les erreurs que vous pouvez rencontrer. 
+ La [section Erreurs courantes de la référence de l’API](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/CommonErrors.html).
+ La documentation de chaque opération d'API répertorie les erreurs que cet appel peut générer (par exemple [BatchWriteItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html)).

## Logging
<a name="programming-with-python-logging"></a>

La bibliothèque boto3 s’intègre au module de journalisation intégré de Python pour suivre ce qui se passe pendant une session. Pour contrôler les niveaux de journalisation, vous pouvez configurer le module de journalisation :

```
import logging

logging.basicConfig(level=logging.INFO)
```

Cela configure l’enregistreur racine pour qu’il journalise `INFO` et les messages de niveau supérieur. Les messages de journalisation moins graves que le niveau sont ignorés. Les niveaux de journalisation peuvent être `DEBUG`, `INFO`, `WARNING`, `ERROR` et `CRITICAL`. La valeur par défaut est `WARNING`.

Les enregistreurs de boto3 sont hiérarchiques. La bibliothèque utilise plusieurs enregistreurs différents, chacun correspondant à différentes parties de la bibliothèque. Vous pouvez contrôler séparément le comportement de chacun :
+ **boto3** : enregistreur principal du module boto3.
+ **botocore** : enregistreur principal du package botocore.
+ **botocore.auth** : utilisé pour enregistrer la création de signatures AWS pour les demandes.
+ **botocore.credentials** : utilisé pour journaliser le processus de récupération et d’actualisation des informations d’identification.
+ **botocore.endpoint** : utilisé pour journaliser la création de demandes avant leur envoi sur le réseau.
+ **botocore.hooks** : utilisé pour journaliser les événements déclenchés dans la bibliothèque.
+ **botocore.loaders** : utilisé pour la journalisation lorsque des parties de modèles de AWS service sont chargées.
+ **botocore.parsers** : utilisé pour journaliser les réponses du service AWS avant qu’elles ne soient analysées.
+ **botocore.retryhandler** : utilisé pour enregistrer le traitement des nouvelles tentatives de demande de AWS service (mode ancien).
+ **botocore.retries.standard** : utilisé pour enregistrer le traitement des nouvelles tentatives de demande de AWS service (mode standard ou adaptatif).
+ **botocore.utils** : utilisé pour journaliser diverses activités dans la bibliothèque.
+ **botocore.waiter** : utilisé pour enregistrer les fonctionnalités des serveurs, qui interrogent un AWS service jusqu'à ce qu'un certain état soit atteint. 

D’autres bibliothèques utilisent également les journaux. En interne, boto3 utilise le fichier tiers urllib3 pour la gestion des connexions HTTP. Lorsque la latence est importante, vous pouvez consulter ses journaux pour vous assurer que votre pool est bien utilisé en voyant quand urllib3 établit une nouvelle connexion ou ferme une connexion inactive.
+ **urllib3.connectionpool :** à utiliser pour journaliser les événements de gestion du groupe de connexions.

L’extrait de code suivant définit la plupart des connexions sur la journalisation dans `INFO` avec la journalisation `DEBUG` pour l’activité du point de terminaison et du groupe de connexions :

```
import logging

logging.getLogger('boto3').setLevel(logging.INFO)
logging.getLogger('botocore').setLevel(logging.INFO)
logging.getLogger('botocore.endpoint').setLevel(logging.DEBUG)
logging.getLogger('urllib3.connectionpool').setLevel(logging.DEBUG)
```

## Hooks d’événement
<a name="programming-with-python-event-hooks"></a>

Botocore émet des événements au cours des différentes étapes de son exécution. Vous pouvez enregistrer des gestionnaires pour ces événements afin que chaque fois qu’un événement est émis, votre gestionnaire soit appelé. Cela vous permet d’étendre le comportement du botocore sans avoir à modifier les composants internes.

Supposons, par exemple, que vous souhaitiez suivre chaque fois qu’une opération `PutItem` est appelée sur une table DynamoDB de votre application. Vous pouvez vous enregistrer sur l’événement `'provide-client-params.dynamodb.PutItem'` à capturer et journaliser chaque fois qu’une opération `PutItem` est invoquée dans la session associée. Voici un exemple :

```
import boto3
import botocore
import logging

def log_put_params(params, **kwargs):
    if 'TableName' in params and 'Item' in params:
        logging.info(f"PutItem on table {params['TableName']}: {params['Item']}")

logging.basicConfig(level=logging.INFO)

session = boto3.Session()
event_system = session.events

# Register our interest in hooking in when the parameters are provided to PutItem
event_system.register('provide-client-params.dynamodb.PutItem', log_put_params)

# Now, every time you use this session to put an item in DynamoDB,
# it will log the table name and item data.
dynamodb = session.resource('dynamodb')
table = dynamodb.Table('YourTableName')
table.put_item(
    Item={
        'pk': '123',
        'sk': 'cart#123',
        'item_data': 'YourItemData',
        # ... more attributes ...
    }
)
```

Dans le gestionnaire, vous pouvez même manipuler les paramètres par programmation pour modifier le comportement :

```
params['TableName'] = "NewTableName"
```

Pour plus d’informations sur les événements, consultez [botocore documentation on events](https://botocore.amazonaws.com/v1/documentation/api/latest/topics/events.html) et [boto3 documentation on events](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/events.html).

## Pagination et paginateur
<a name="programming-with-python-pagination"></a>

Certaines demandes, telles que Query et Scan, limitent la taille des données renvoyées lors d’une seule demande et nécessitent que vous fassiez des demandes répétées pour extraire les pages suivantes.

Vous pouvez contrôler le nombre maximum d’éléments à lire pour chaque page à l’aide du paramètre `limit`. Par exemple, si vous voulez extraire uniquement les 10 derniers éléments, vous pouvez utiliser le paramètre `limit`. Notez que la limite correspond à la quantité qui doit être lue dans la table avant qu’un filtrage ne soit appliqué. Il n’est pas possible de spécifier que vous voulez exactement 10 éléments après le filtrage ; vous ne pouvez contrôler le nombre préfiltré et vérifier côté client que lorsque vous en avez réellement extrait 10. Quelle que soit la limite, chaque réponse a toujours une taille maximale de 1 Mo.

Si la réponse inclut une `LastEvaluatedKey`, cela indique qu’elle s’est terminée parce qu’elle a atteint une limite de nombre ou de taille. La clé est la dernière clé évaluée pour la réponse. Vous pouvez extraire cette `LastEvaluatedKey` et la transmettre à un appel de suivi en tant que `ExclusiveStartKey` afin de lire le fragment suivant à partir de ce point de départ. Si aucune `LastEvaluatedKey` n’est renvoyée, cela signifie qu’il n’y a plus d’éléments correspondant à Query ou Scan.

Voici un exemple simple (utilisant l’interface Ressource, mais l’interface Client suit le même schéma) qui lit au maximum 100 éléments par page et boucle jusqu’à ce que tous les éléments aient été lus.

```
import boto3

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('YourTableName')

query_params = {
    'KeyConditionExpression': Key('pk').eq('123') & Key('sk').gt(1000),
    'Limit': 100
}

while True:
    response = table.query(**query_params)

    # Process the items however you like
    for item in response['Items']:
        print(item)

    # No LastEvaluatedKey means no more items to retrieve
    if 'LastEvaluatedKey' not in response:
        break

    # If there are possibly more items, update the start key for the next page
    query_params['ExclusiveStartKey'] = response['LastEvaluatedKey']
```

Pour plus de commodité, boto3 peut le faire pour vous avec des paginateurs. Cependant, cela ne fonctionne qu’avec l’interface Client. Voici le code réécrit pour utiliser les paginateurs :

```
import boto3

dynamodb = boto3.client('dynamodb')

paginator = dynamodb.get_paginator('query')

query_params = {
    'TableName': 'YourTableName',
    'KeyConditionExpression': 'pk = :pk_val AND sk > :sk_val',
    'ExpressionAttributeValues': {
        ':pk_val': {'S': '123'},
        ':sk_val': {'N': '1000'},
    },
    'Limit': 100
}

page_iterator = paginator.paginate(**query_params)

for page in page_iterator:
    # Process the items however you like
    for item in page['Items']:
        print(item)
```

Pour plus d’informations, consultez le [Guide on Paginators](https://botocore.amazonaws.com/v1/documentation/api/latest/topics/events.html) et l’[API reference for DynamoDB.Paginator.Query](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/paginator/Query.html).

**Note**  
Les paginateurs ont également leurs propres paramètres de configuration nommés `MaxItems`, `StartingToken` et `PageSize`. Pour la pagination avec DynamoDB, vous devez ignorer ces paramètres.

## Programmes d’attente
<a name="programming-with-python-waiters"></a>

Les programmes d’attente offrent la possibilité d’attendre que quelque chose soit terminé avant de continuer. À l’heure actuelle, ils ne prennent en charge que l’attente de la création ou de la suppression d’une table. En arrière-plan, le programme d’attente effectue une vérification pour vous toutes les 20 secondes, jusqu’à 25 fois. Vous pouvez le faire vous-même mais l’utilisation d’un programme d’attente est élégante lors de l’automatisation de l’écriture.

Ce code montre comment attendre qu’une table particulière ait été créée :

```
# Create a table, wait until it exists, and print its ARN
response = client.create_table(...)
waiter = client.get_waiter('table_exists')
waiter.wait(TableName='YourTableName')
print('Table created:', response['TableDescription']['TableArn']
```

Pour plus d’informations, consultez le [Guide to Waiters](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/clients.html#waiters) et la [Reference on Waiters](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#waiters).

# Programmation d'Amazon DynamoDB avec JavaScript
<a name="programming-with-javascript"></a>

Ce guide fournit une orientation aux programmeurs souhaitant utiliser Amazon DynamoDB avec. JavaScript Découvrez les couches d'abstraction disponibles AWS SDK pour JavaScript, la configuration des connexions, la gestion des erreurs, la définition des politiques de nouvelle tentative, la gestion du maintien en vie, etc.

**Topics**
+ [À propos AWS SDK pour JavaScript](#programming-with-javascript-about)
+ [Utilisation de la AWS SDK pour JavaScript V3](#programming-with-javascript-using-the-sdk)
+ [Accès à JavaScript la documentation](#programming-with-javascript-documentation)
+ [Couches d’abstraction](#programming-with-javascript-abstraction-layers)
+ [Utilisation de la fonction utilitaire de regroupement](#programming-with-javascript-using-marshall-utility)
+ [Lecture d’éléments](#programming-with-javascript-reading-items)
+ [Écritures conditionnelles](#programming-with-javascript-conditional-writes)
+ [Pagination](#programming-with-javascript-pagination)
+ [Spécification d’une configuration](#programming-with-javascript-config)
+ [Programmes d’attente](#programming-with-javascript-waiters)
+ [Gestion des erreurs](#programming-with-javascript-error-handling)
+ [Logging](#programming-with-javascript-logging)
+ [Considérations](#programming-with-javascript-considerations)

## À propos AWS SDK pour JavaScript
<a name="programming-with-javascript-about"></a>

 AWS SDK pour JavaScript Permet d'accéder à Services AWS l'utilisation de scripts de navigateur ou de Node.js. Cette documentation se concentre sur la dernière version du kit SDK (V3). La AWS SDK pour JavaScript V3 est maintenue par AWS un [projet open source hébergé sur](https://github.com/aws/aws-sdk-js-v3). GitHub Les problèmes et les demandes de fonctionnalités sont publics et vous pouvez y accéder sur la page des problèmes du GitHub référentiel.

JavaScript La V2 est similaire à la V3, mais contient des différences de syntaxe. La version 3 est plus modulaire, ce qui facilite l'expédition de petites dépendances, et offre un support de premier ordre TypeScript . Nous vous recommandons d’utiliser la dernière version du kit SDK.

## Utilisation de la AWS SDK pour JavaScript V3
<a name="programming-with-javascript-using-the-sdk"></a>

Vous pouvez ajouter le kit SDK à votre application Node.js à l’aide de Node Package Manager. Les exemples ci-dessous montrent comment ajouter les packages SDK les plus courants à utiliser avec DynamoDB.
+ `npm install @aws-sdk/client-dynamodb`
+ `npm install @aws-sdk/lib-dynamodb`
+ `npm install @aws-sdk/util-dynamodb`

L’installation de packages ajoute des références à la section de dépendance de votre fichier de projet package.json. Vous avez la possibilité d'utiliser la nouvelle syntaxe du ECMAScript module. Pour plus de détails sur ces deux approches, consultez la section Considérations.

## Accès à JavaScript la documentation
<a name="programming-with-javascript-documentation"></a>

Commencez par consulter la JavaScript documentation à l'aide des ressources suivantes :
+ Accédez au [guide du développeur](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/welcome.html) pour accéder à la JavaScript documentation de base. Les instructions d’installation se trouvent dans la section **Configuration**.
+ Accédez à la documentation de [référence de l’API](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/introduction/) pour explorer toutes les classes et méthodes disponibles.
+ Le SDK pour JavaScript prend en charge de nombreuses Services AWS autres solutions que DynamoDB. Utilisez la procédure suivante pour localiser la couverture d’API spécifique pour DynamoDB :

  1. Dans **Services**, sélectionnez **DynamoDB and Libraries**. Il s’agit de la documentation pour le client de bas niveau.

  1. Choisissez **lib-dynamodb**. Il s’agit de la documentation pour le client de haut niveau. Les deux clients représentent deux couches d’abstraction différentes que vous avez le choix d’utiliser. Consultez la section ci-dessous pour plus d’informations sur les couches d’abstraction.

## Couches d’abstraction
<a name="programming-with-javascript-abstraction-layers"></a>

Le SDK pour JavaScript V3 possède un client de bas niveau (`DynamoDBClient`) et un client de haut niveau (). `DynamoDBDocumentClient`

**Topics**
+ [Client de bas niveau (`DynamoDBClient`)](#programming-with-javascript-low-level-client)
+ [Client de haut niveau (`DynamoDBDocumentClient`)](#programming-with-javascript-high-level-client)

### Client de bas niveau (`DynamoDBClient`)
<a name="programming-with-javascript-low-level-client"></a>

Le client de bas niveau ne fournit aucune abstraction supplémentaire par rapport au protocole filaire sous-jacent. Cela vous donne un contrôle total sur tous les aspects de la communication, mais comme il n’y a pas d’abstractions, vous devez notamment fournir des définitions d’éléments à l’aide du format JSON DynamoDB. 

Comme le montre l’exemple ci-dessous, avec ce format, les types de données doivent être indiqués explicitement. Un *S* indique une valeur de chaîne et un *N* une valeur numérique. Les numéros sur la transmission sont toujours envoyés sous forme de chaînes balisées sous forme de types numériques pour éviter toute perte de précision. Les appels d’API de bas niveau ont un modèle d’affectation tel que `PutItemCommand` et `GetItemCommand`.

L’exemple suivant utilise un client de bas niveau `Item` défini à l’aide d’un fichier JSON DynamoDB :

```
const { DynamoDBClient, PutItemCommand } = require("@aws-sdk/client-dynamodb");

const client = new DynamoDBClient({});

async function addProduct() {
  const params = {
    TableName: "products",
    Item: {
      "id": { S: "Product01" },
      "description": { S: "Hiking Boots" },
      "category": { S: "footwear" },
      "sku": { S: "hiking-sku-01" },
      "size": { N: "9" }
    }
  };

  try {
    const data = await client.send(new PutItemCommand(params));
    console.log('result : ' + JSON.stringify(data));
  } catch (error) {
    console.error("Error:", error);
  }
}
addProduct();
```

### Client de haut niveau (`DynamoDBDocumentClient`)
<a name="programming-with-javascript-high-level-client"></a>

Le client de documents DynamoDB de haut niveau offre des fonctionnalités pratiques intégrées, telles que l'élimination de la nécessité de rassembler manuellement les données et l'autorisation de lectures et d'écritures directes à l'aide d'objets standard. JavaScript La [documentation de `lib-dynamodb`](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-lib-dynamodb/) fournit la liste des avantages.

Pour instancier le `DynamoDBDocumentClient`, construisez un `DynamoDBClient` de bas niveau ; puis encapsulez-le avec un `DynamoDBDocumentClient`. La convention de dénomination des fonctions diffère légèrement entre les deux packages. Par exemple, le bas niveau utilise `PutItemCommand` tandis que le haut niveau utilise `PutCommand`. Les noms distincts permettent aux deux ensembles de fonctions de coexister dans le même contexte, ce qui vous permet de combiner les deux dans le même script.

```
const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const { DynamoDBDocumentClient, PutCommand } = require("@aws-sdk/lib-dynamodb");

const client = new DynamoDBClient({});

const docClient = DynamoDBDocumentClient.from(client);

async function addProduct() {
  const params = {
    TableName: "products",
    Item: {
      id: "Product01",
      description: "Hiking Boots",
      category: "footwear",
      sku: "hiking-sku-01",
      size: 9,
    },
  };

  try {
    const data = await docClient.send(new PutCommand(params));
    console.log('result : ' + JSON.stringify(data));
  } catch (error) {
    console.error("Error:", error);
  }
}

addProduct();
```

Le modèle d’utilisation est cohérent lorsque vous lisez des éléments à l’aide d’opérations d’API telles que `GetItem`, `Query` ou `Scan`.

## Utilisation de la fonction utilitaire de regroupement
<a name="programming-with-javascript-using-marshall-utility"></a>

Vous pouvez utiliser le client de bas niveau et regrouper ou désorganiser vous-même les types de données. Le package d’utilitaires, [util-dynamodb](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-util-dynamodb/), possède une fonction utilitaire `marshall()` qui accepte le JSON et produit DynamoDB JSON, ainsi qu’une fonction `unmarshall()` qui effectue l’inverse. L’exemple suivant utilise le client de bas niveau avec la désorganisation des données gérée par l’appel `marshall()`.

```
const { DynamoDBClient, PutItemCommand } = require("@aws-sdk/client-dynamodb");
const { marshall } = require("@aws-sdk/util-dynamodb");

const client = new DynamoDBClient({});

async function addProduct() {
  const params = {
    TableName: "products",
    Item: marshall({
      id: "Product01",
      description: "Hiking Boots",
      category: "footwear",
      sku: "hiking-sku-01",
      size: 9,
    }),
  };

  try {
    const data = await client.send(new PutItemCommand(params));
  } catch (error) {
    console.error("Error:", error);
  }
}
addProduct();
```

## Lecture d’éléments
<a name="programming-with-javascript-reading-items"></a>

Pour lire un seul élément à partir de DynamoDB, utilisez l’opération d’API `GetItem`. Comme pour la commande `PutItem`, vous avez le choix d’utiliser le client de bas niveau ou le client Document de haut niveau. L’exemple ci-dessous montre comment utiliser le client Document de haut niveau pour extraire un élément.

```
const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const { DynamoDBDocumentClient, GetCommand } = require("@aws-sdk/lib-dynamodb");

const client = new DynamoDBClient({});

const docClient = DynamoDBDocumentClient.from(client);

async function getProduct() {
  const params = {
    TableName: "products",
    Key: {
      id: "Product01",
    },
  };

  try {
    const data = await docClient.send(new GetCommand(params));
    console.log('result : ' + JSON.stringify(data));
  } catch (error) {
    console.error("Error:", error);
  }
}

getProduct();
```

Utilisez l’opération d’API `Query` pour lire plusieurs éléments. Vous pouvez utiliser le client de bas niveau ou le client Document. L’exemple ci-dessous utilise le client Document de haut niveau.

```
const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const {
  DynamoDBDocumentClient,
  QueryCommand,
} = require("@aws-sdk/lib-dynamodb");

const client = new DynamoDBClient({});

const docClient = DynamoDBDocumentClient.from(client);

async function productSearch() {
  const params = {
    TableName: "products",
    IndexName: "GSI1",
    KeyConditionExpression: "#category = :category and begins_with(#sku, :sku)",
    ExpressionAttributeNames: {
      "#category": "category",
      "#sku": "sku",
    },
    ExpressionAttributeValues: {
      ":category": "footwear",
      ":sku": "hiking",
    },
  };

  try {
    const data = await docClient.send(new QueryCommand(params));
    console.log('result : ' + JSON.stringify(data));
  } catch (error) {
    console.error("Error:", error);
  }
}

productSearch();
```

## Écritures conditionnelles
<a name="programming-with-javascript-conditional-writes"></a>

Les opérations d’écriture DynamoDB peuvent spécifier une expression de condition logique qui doit être définie sur true pour que l’écriture puisse se poursuivre. Si la condition n’est pas définie sur true, l’opération d’écriture génère une exception. L’expression de condition peut vérifier si l’élément existe déjà ou si ses attributs correspondent à certaines contraintes.

`ConditionExpression = "version = :ver AND size(VideoClip) < :maxsize" `

Lorsque l’expression conditionnelle échoue, vous pouvez utiliser `ReturnValuesOnConditionCheckFailure` pour demander que la réponse d’erreur inclue l’élément qui ne satisfaisait pas aux conditions afin de déduire l’origine du problème. Pour plus de détails, consultez [Handle conditional write errors in high concurrency scenarios with Amazon DynamoDB](https://aws.amazon.com/blogs/database/handle-conditional-write-errors-in-high-concurrency-scenarios-with-amazon-dynamodb/).

```
try {
      const response = await client.send(new PutCommand({
          TableName: "YourTableName",
          Item: item,
          ConditionExpression: "attribute_not_exists(pk)",
          ReturnValuesOnConditionCheckFailure: "ALL_OLD"
      }));
  } catch (e) {
      if (e.name === 'ConditionalCheckFailedException') {
          console.log('Item already exists:', e.Item);
      } else {
          throw e;
      }
  }
```

[Des exemples de code supplémentaires illustrant d'autres aspects de l'utilisation du JavsScript SDK V3 sont disponibles dans la [documentation du JavaScript SDK V3](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/javascript_dynamodb_code_examples.html) et dans le référentiel. DynamoDB-SDK-Examples GitHub ](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/examples/SDK/node.js)

## Pagination
<a name="programming-with-javascript-pagination"></a>

**Topics**
+ [Utilisation de la méthode pratique `paginateScan`](#using-the-paginatescan-convenience-method)

Les demandes de lecture telles que `Scan` ou `Query` renverront probablement plusieurs éléments dans un jeu de données. Si vous effectuez une `Scan` ou une `Query` avec un paramètre `Limit`, une fois que le système aura lu autant d’éléments, une réponse partielle sera envoyée et vous devrez paginer pour récupérer des éléments supplémentaires.

Le système ne lira qu’un maximum de 1 mégaoctet de données par demande. Si vous incluez une expression `Filter`, le système lira toujours un mégaoctet, au maximum, de données sur le disque, mais renverra les éléments de ce mégaoctet qui correspondent au filtre. L’opération de filtrage peut renvoyer 0 élément pour une page, mais nécessite tout de même une pagination supplémentaire avant que la recherche ne soit épuisée.

Vous devez rechercher `LastEvaluatedKey` dans la réponse et l’utiliser comme paramètre `ExclusiveStartKey` dans une demande ultérieure pour poursuivre l’extraction des données. Cela sert de signet, comme indiqué dans l’exemple suivant.

**Note**  
L’exemple transmet une valeur nulle `lastEvaluatedKey` comme `ExclusiveStartKey` lors de la première itération, ce qui est autorisé.

Exemple d’utilisation de `LastEvaluatedKey` :

```
const { DynamoDBClient, ScanCommand } = require("@aws-sdk/client-dynamodb");

const client = new DynamoDBClient({});

async function paginatedScan() {
  let lastEvaluatedKey;
  let pageCount = 0;

  do {
    const params = {
      TableName: "products",
      ExclusiveStartKey: lastEvaluatedKey,
    };

    const response = await client.send(new ScanCommand(params));
    pageCount++;
    console.log(`Page ${pageCount}, Items:`, response.Items);
    lastEvaluatedKey = response.LastEvaluatedKey;
  } while (lastEvaluatedKey);
}

paginatedScan().catch((err) => {
  console.error(err);
});
```

### Utilisation de la méthode pratique `paginateScan`
<a name="using-the-paginatescan-convenience-method"></a>



Le kit SDK fournit des méthodes pratiques appelées `paginateScan` et `paginateQuery` qui font cela à votre place et qui font les demandes répétées en arrière-plan. Spécifiez le nombre maximum d’éléments à lire par demande à l’aide du paramètre standard `Limit`.

```
const { DynamoDBClient, paginateScan } = require("@aws-sdk/client-dynamodb");

const client = new DynamoDBClient({});

async function paginatedScanUsingPaginator() {
  const params = {
    TableName: "products",
    Limit: 100
  };

  const paginator = paginateScan({client}, params);

  let pageCount = 0;

  for await (const page of paginator) {
    pageCount++;
    console.log(`Page ${pageCount}, Items:`, page.Items);
  }
}

paginatedScanUsingPaginator().catch((err) => {
  console.error(err);
});
```

**Note**  
Il n’est pas recommandé d’effectuer régulièrement des analyses complètes de la table, sauf si celle-ci est petite.

## Spécification d’une configuration
<a name="programming-with-javascript-config"></a>

**Topics**
+ [Configuration pour les délais d’expiration](#programming-with-javascript-config-timeouts)
+ [Configuration pour keep-alive](#programming-with-javascript-config-keep-alive)
+ [Configuration pour les nouvelles tentatives](#programming-with-javascript-config-retries)

Lors de la configuration de `DynamoDBClient`, vous pouvez spécifier différentes remplacements de configuration en transmettant un objet de configuration au constructeur. Par exemple, vous pouvez spécifier la région à laquelle vous connecter si le contexte d’appel ne la connaît pas déjà ou si l’URL du point de terminaison à utiliser ne la connaît pas déjà. Cela est utile si vous souhaitez cibler une instance DynamoDB local à des fins de développement.

```
const client = new DynamoDBClient({
  region: "eu-west-1",
  endpoint: "http://localhost:8000",
});
```

### Configuration pour les délais d’expiration
<a name="programming-with-javascript-config-timeouts"></a>

DynamoDB utilise HTTPS pour les communications client-serveur. Vous pouvez contrôler certains aspects de la couche HTTP en fournissant un objet `NodeHttpHandler`. Par exemple, vous pouvez ajuster les principales valeurs de délai d’expiration `connectionTimeout` et `requestTimeout`. `connectionTimeout` représente la durée maximale, en millisecondes, pendant laquelle le client doit attendre lorsqu’il essaie d’établir une connexion avant d’abandonner.

`requestTimeout` définit le temps pendant lequel le client doit attendre une réponse après l’envoi d’une demande, également en millisecondes. La valeur par défaut pour les deux est zéro, ce qui signifie que le délai d’attente est désactivé et qu’il n’y a aucune limite quant au temps d’attente du client si la réponse n’arrive pas. Vous devez définir les délais d’expiration à un niveau raisonnable afin qu’en cas de problème réseau, la demande soit en erreur et qu’une nouvelle demande puisse être initiée. Par exemple :

```
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { NodeHttpHandler } from "@smithy/node-http-handler";

const requestHandler = new NodeHttpHandler({
  connectionTimeout: 2000,
  requestTimeout: 2000,
});

const client = new DynamoDBClient({
  requestHandler
});
```

**Note**  
L’exemple fourni utilise l’importation [Smithy](https://smithy.io/2.0/index.html). Smithy est un langage de définition des services et SDKs, open source et maintenu par. AWS

Outre la configuration des valeurs de délai d’expiration, vous pouvez définir le nombre maximum de sockets, ce qui permet d’augmenter le nombre de connexions simultanées par origine. Le guide du développeur contient des [informations détaillées sur la configuration du paramètre `maxSockets`](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-configuring-maxsockets.html).

### Configuration pour keep-alive
<a name="programming-with-javascript-config-keep-alive"></a>

Lorsque vous utilisez le protocole HTTPS, la première demande nécessite toujours une certaine back-and-forth communication pour établir une connexion sécurisée. HTTP Keep-Alive permet aux requêtes suivantes de réutiliser la connexion déjà établie, ce qui les rend plus efficaces et réduit le temps de latence. HTTP Keep-Alive est activé par défaut avec JavaScript la version 3. 

Il y a une limite à la durée pendant laquelle une connexion inactive peut être maintenue en vie. Envisagez d’envoyer des demandes périodiques, par exemple toutes les minutes, si vous avez une connexion inactive mais que vous souhaitez que la prochaine demande utilise une connexion déjà établie.

**Note**  
Notez que dans l’ancienne version 2 du kit SDK, keep-alive était désactivé par défaut, ce qui signifie que chaque connexion était fermée immédiatement après utilisation. Si vous utilisez la version 2, vous pouvez annuler ce paramètre.

### Configuration pour les nouvelles tentatives
<a name="programming-with-javascript-config-retries"></a>

Lorsque le kit SDK reçoit une réponse d’erreur et que l’erreur peut être reprise comme indiqué par le kit SDK, par exemple une exception de limitation ou une exception de service temporaire, il réessaie. Cela se produit de manière invisible pour vous en tant qu’appelant, sauf que vous remarquerez peut-être que la demande a mis plus de temps à aboutir.

Le SDK pour JavaScript V3 effectuera 3 requêtes au total, par défaut, avant d'abandonner et de transmettre l'erreur au contexte d'appel. Vous pouvez ajuster le nombre et la fréquence de ces nouvelles tentatives.

Le constructeur `DynamoDBClient` accepte un paramètre `maxAttempts` qui limite le nombre de tentatives possibles. L’exemple ci-dessous augmente la valeur de 3 par défaut à 5 au total. Si vous le définissez sur 0 ou 1, cela indique que vous ne souhaitez pas de nouvelles tentatives automatiques et que vous souhaitez gérer vous-même les erreurs reprenant dans votre bloc catch.

```
const client = new DynamoDBClient({
  maxAttempts: 5,
});
```

Vous pouvez également contrôler le calendrier des nouvelles tentatives à l’aide d’une stratégie de nouvelle tentative personnalisée. Pour ce faire, importez le package d’utilitaires `util-retry` et créez une fonction de sauvegarde personnalisée qui calcule le temps d’attente entre les tentatives en fonction du nombre de tentatives actuel.

L’exemple ci-dessous indique d’effectuer un maximum de 5 tentatives avec des délais de 15, 30, 90 et 360 millisecondes en cas d’échec de la première tentative. La fonction d’annulation personnalisée, ` calculateRetryBackoff`, calcule les délais en acceptant le nombre de nouvelles tentatives (commence par 1 pour la première nouvelle tentative) et renvoie le nombre de millisecondes à attendre pour cette demande.

```
const { ConfiguredRetryStrategy } = require("@aws-sdk/util-retry");

const calculateRetryBackoff = (attempt) => {
  const backoffTimes = [15, 30, 90, 360];
  return backoffTimes[attempt - 1] || 0;
};

const client = new DynamoDBClient({
  retryStrategy: new ConfiguredRetryStrategy(
    5, // max attempts.
    calculateRetryBackoff // backoff function.
  ),
});
```

## Programmes d’attente
<a name="programming-with-javascript-waiters"></a>

Le client DynamoDB inclut deux [fonctions de programmes d’attente](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/dynamodb/wait/index.html#cli-aws-dynamodb-wait) qui peuvent être utilisées lors de la création, de la modification ou de la suppression de tables lorsque vous souhaitez que votre code attende jusqu’à ce que la modification des tables soit terminée. Par exemple, vous pouvez déployer une table, appeler la fonction `waitUntilTableExists`, et le code bloquera jusqu’à ce que la table soit **ACTIVE**. Le serveur interroge en interne le service DynamoDB avec un `describe-table` toutes les 20 secondes. 

```
import {waitUntilTableExists, waitUntilTableNotExists} from "@aws-sdk/client-dynamodb";

… <create table details>

const results = await waitUntilTableExists({client: client, maxWaitTime: 180}, {TableName: "products"});
if (results.state == 'SUCCESS') {
  return results.reason.Table
}
console.error(`${results.state} ${results.reason}`);
```

La fonctionnalité `waitUntilTableExists` ne rend le contrôle que lorsqu’elle peut exécuter une commande `describe-table` indiquant le statut de table **ACTIF**. Cela garantit que vous pouvez utiliser `waitUntilTableExists` pour attendre la fin de la création, ainsi que des modifications telles que l’ajout d’un index GSI, dont l’application peut prendre un certain temps avant que la table ne revienne au statut **ACTIF**.

## Gestion des erreurs
<a name="programming-with-javascript-error-handling"></a>

Dans les premiers exemples présentés ici, nous avons identifié toutes les erreurs de manière générale. Cependant, dans les applications pratiques, il est important de distinguer les différents types d’erreurs et de mettre en œuvre une gestion plus précise de celles-ci.

Les réponses aux erreurs DynamoDB contiennent des métadonnées, notamment le nom de l’erreur. Vous pouvez détecter les erreurs puis les comparer aux noms de chaîne possibles des conditions d’erreur afin de déterminer la marche à suivre. Pour les erreurs côté serveur, vous pouvez optimiser l’opérateur `instanceof` avec les types d’erreur exportés par le package `@aws-sdk/client-dynamodb` pour gérer efficacement la gestion des erreurs.

Il est important de noter que ces erreurs ne se manifestent qu’une fois toutes les nouvelles tentatives épuisées. Si une erreur fait l’objet d’une nouvelle tentative, suivi d’un appel qui aboutit, du point de vue du code, aucune erreur n’est détectée, juste une latence légèrement élevée. Les nouvelles tentatives apparaîtront dans les CloudWatch graphiques Amazon sous forme de demandes infructueuses, telles que les demandes d'accélération ou d'erreur. Si le client atteint le nombre maximal de nouvelles tentatives, il abandonne et génère une exception. Il s’agit de la façon dont le client dit qu’il ne va pas réessayer.

Vous trouverez ci-dessous un extrait permettant de détecter l’erreur et de prendre des mesures en fonction du type d’erreur renvoyé.

```
import {
  ResourceNotFoundException
  ProvisionedThroughputExceededException,
  DynamoDBServiceException,
} from "@aws-sdk/client-dynamodb";

try {
  await client.send(someCommand);
} catch (e) {
    if (e instanceof ResourceNotFoundException) {
      // Handle ResourceNotFoundException
    } else if (e instanceof ProvisionedThroughputExceededException) {
      // Handle ProvisionedThroughputExceededException
    } else if (e instanceof DynamoDBServiceException) {
      // Handle DynamoDBServiceException
    } else {
      // Other errors such as those from the SDK
      if (e.name === "TimeoutError") {
        // Handle SDK TimeoutError.
      } else {
        // Handle other errors.
      }
    }
}
```

Pour plus d’informations sur les chaînes d’erreur les plus courantes, consultez [Gestion des erreurs avec DynamoDB](Programming.Errors.md) dans le *guide du développeur DynamoDB*. Les erreurs exactes possibles avec un appel d’API particulier peuvent être trouvées dans la documentation de cet appel d’API, telle que la [documentation de l’API de requête](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html).

Les métadonnées des erreurs incluent des propriétés supplémentaires, en fonction de l’erreur. Pour un ` TimeoutError`, les métadonnées incluent le nombre de tentatives effectuées et le `totalRetryDelay`, comme indiqué ci-dessous.

```
{
  "name": "TimeoutError",
  "$metadata": {
    "attempts": 3,
    "totalRetryDelay": 199
  }
}
```

Si vous gérez votre propre stratégie de nouvelle tentative, vous devez faire la différence entre les limitations et les erreurs :
+ Une **limitation** (indiquée par une ` ProvisionedThroughputExceededException` ou une `ThrottlingException`) indique un service en bonne santé qui vous informe que vous avez dépassé votre capacité de lecture ou d’écriture sur une table ou une partition DynamoDB. Chaque milliseconde qui passe, un peu plus de capacité de lecture ou d’écriture est disponible, ce qui vous permet d’effectuer rapidement une nouvelle tentative (par exemple toutes les 50 ms) pour tenter d’accéder à cette capacité nouvellement libérée.

   Avec les limitations, vous n’avez pas particulièrement besoin de backoff exponentiel, car les limitations sont légères pour que DynamoDB les renvoie et n’entraînent aucun frais par demande pour vous. Le backoff exponentiel affecte des délais plus longs aux threads client qui ont déjà attendu le plus longtemps, ce qui étend statistiquement les p50 et p99 vers l’extérieur.
+ Une **erreur** (indiquée par ` InternalServerError` ou `ServiceUnavailable`, entre autres) indique un problème transitoire avec le service, peut-être avec la table entière ou simplement avec la partition sur laquelle vous lisez ou sur laquelle vous écrivez. En cas d’erreur, vous pouvez faire une pause plus longue avant de d’effectuer de nouvelles tentatives (250 ms ou 500 ms, par exemple) et utiliser l’instabilité pour échelonner les nouvelles tentatives.

## Logging
<a name="programming-with-javascript-logging"></a>

Activez la journalisation pour obtenir plus de détails sur le fonctionnement du kit SDK. Vous pouvez définir un paramètre sur le`DynamoDBClient`, comme indiqué dans l’exemple ci-dessous. D’autres informations de journal apparaîtront dans la console et incluent des métadonnées telles que le code d’état et la capacité consommée. Si vous exécutez le code localement dans une fenêtre de terminal, les journaux y apparaissent. Si vous exécutez le code et que vous avez configuré Amazon CloudWatch Logs, la sortie de la console y sera écrite. AWS Lambda

```
const client = new DynamoDBClient({
  logger: console
});
```

Vous pouvez également vous connecter aux activités internes du kit SDK et effectuer une journalisation personnalisée lorsque certains événements se produisent. L’exemple ci-dessous utilise le `middlewareStack` du client pour intercepter chaque demande au fur et à mesure qu’elle est envoyée par le kit SDK et l’enregistre au fur et à mesure qu’elle se produit.

```
const client = new DynamoDBClient({});

client.middlewareStack.add(
  (next) => async (args) => {
    console.log("Sending request from AWS SDK", { request: args.request });
    return next(args);
  },
  {
    step: "build",
    name: "log-ddb-calls",
  }
);
```

Le `MiddlewareStack` constitue un hook puissant pour observer et contrôler le comportement du kit SDK. Consultez le blog [Présentation de Middleware Stack in Modular AWS SDK pour JavaScript](https://aws.amazon.com/blogs/developer/middleware-stack-modular-aws-sdk-js/) pour plus d'informations.

## Considérations
<a name="programming-with-javascript-considerations"></a>

Lorsque vous l' AWS SDK pour JavaScript implémentez dans votre projet, voici d'autres facteurs à prendre en compte.

**Systèmes de modules**  
Le SDK prend en charge deux systèmes de modules, CommonJS et ES ()ECMAScript. CommonJS utilise la fonction `require`, tandis que ES utilise le mot clé `import`.  

1. **Common JS** – `const { DynamoDBClient, PutItemCommand } = require("@aws-sdk/client-dynamodb");`

1. **OUI (ECMAScript**— `import { DynamoDBClient, PutItemCommand } from "@aws-sdk/client-dynamodb";`
Le type de projet dicte le système de modules à utiliser et est spécifié dans la section type de votre fichier package.json. Le type par défaut est CommonJS. Utilisez `"type": "module"` pour indiquer un projet ES. Si vous avez un projet Node.JS existant qui utilise le format de package CommonJS, vous pouvez toujours ajouter des fonctions avec la syntaxe d’importation plus moderne du kit SDK V3 en nommant vos fichiers de fonctions avec l’extension .mjs. Cela permettra au fichier de code d'être traité comme ES (ECMAScript).

**Opérations asynchrones**  
Vous verrez de nombreux exemples de code utilisant des rappels et des promesses pour gérer le résultat des opérations DynamoDB. Avec la modernité, JavaScript cette complexité n'est plus nécessaire et les développeurs peuvent tirer parti de la async/await syntaxe plus succincte et lisible pour les opérations asynchrones.

**Exécution du navigateur Web**  
Les développeurs Web et mobiles qui créent avec React ou React Native peuvent utiliser le SDK JavaScript dans leurs projets. Avec la version V2 antérieure du SDK, les développeurs Web devaient charger le SDK complet dans le navigateur, en faisant référence à une image du SDK hébergée sur. https://sdk.amazonaws.com/js/   
Avec la V3, il est possible de regrouper uniquement les modules clients V3 requis et toutes les JavaScript fonctions requises dans un seul JavaScript fichier à l'aide de Webpack, et de l'ajouter dans une balise `<head>` de script dans vos pages HTML, comme expliqué dans la section [Commencer à utiliser un script de navigateur](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/getting-started-browser.html) de la documentation du SDK.

**Opérations de plan de données DAX**  
Les opérations du plan de données Amazon DynamoDB Streams Accelerator (DAX) sont prises en charge par le SDK pour V3. JavaScript 

# Programmation de DynamoDB avec AWS SDK for Java 2.x
<a name="ProgrammingWithJava"></a>

Ce guide de programmation fournit une orientation aux programmeurs qui souhaitent utiliser Amazon DynamoDB avec Java. Le guide couvre différents concepts, notamment les couches d’abstraction, la gestion de la configuration, la gestion des erreurs, le contrôle des politiques de nouvelles tentatives et la gestion de keep-alive.

**Topics**
+ [À propos de AWS SDK for Java 2.x](#AboutProgrammingWithJavaSDK)
+ [Prise en main](#GetStartedProgrammingWithJavaSDK)
+ [Documentation du Kit SDK pour Java 2.x](#ProgrammingWithJavaUseDoc)
+ [Interfaces prises en charge](#JavaInterfaces)
+ [Exemples supplémentaires de code](#AdditionalCodeEx)
+ [Programmation synchrone et asynchrone](#SyncAsyncProgramming)
+ [Clients HTTP](#HttpClients)
+ [Config](#ConfigHttpClient)
+ [Gestion des erreurs](#JavaErrorHandling)
+ [AWS ID de demande](#JavaRequestID)
+ [Logging](#JavaLogging)
+ [Pagination](#JavaPagination)
+ [Annotations de classes de données](#JavaDataClassAnnotation)

## À propos de AWS SDK for Java 2.x
<a name="AboutProgrammingWithJavaSDK"></a>

Vous pouvez accéder à DynamoDB depuis Java en utilisant le logiciel officiel. AWS SDK pour Java Le kit SDK pour Java est disponible en deux versions : 1.x et 2.x. Le end-of-support for 1.x a été [annoncé](https://aws.amazon.com/blogs/developer/announcing-end-of-support-for-aws-sdk-for-java-v1-x-on-december-31-2025/) le 12 janvier 2024. Il entrera en mode maintenance le 31 juillet 2024 et sa date d'échéance end-of-support est fixée au 31 décembre 2025. Pour les nouveaux développements, nous vous recommandons vivement d’utiliser la version 2.x, qui a été publiée pour la première fois en 2018. Ce guide cible exclusivement la version 2.x et se concentre uniquement sur les parties du kit SDK pertinentes pour DynamoDB.

Pour plus d'informations sur la maintenance et le support du AWS SDKs, consultez la [politique de maintenance du AWS SDK et des outils et](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html) la [matrice de prise en charge des versions des outils](https://docs.aws.amazon.com/sdkref/latest/guide/version-support-matrix.html) dans le *guide de référence des outils AWS SDKs et des outils*.AWS SDKs 

 AWS SDK for Java 2.x Il s'agit d'une réécriture majeure de la base de code 1.x. Le SDK pour Java 2.x prend en charge les fonctionnalités Java modernes, telles que le système I/O non bloquant introduit dans Java 8. Le kit SDK pour Java 2.x prend également en charge les implémentations de clients HTTP enfichables afin de fournir une plus grande flexibilité de connexion réseau et des options de configuration supplémentaires.

Un changement notable entre le kit SDK pour Java 1.x et le kit SDK pour Java 2.x est l’utilisation d’un nouveau nom de package. Le kit Java 1.x SDK utilise le nom du package `com.amazonaws`, tandis que le kit Java 2.x SDK utilise `software.amazon.awssdk`. De même, les artefacts Maven du kit SDK Java 1.x utilisent le `groupId` `com.amazonaws`, tandis que les artefacts du kit SDK Java 2.x utilisent le `groupId` `software.amazon.awssdk`.

**Important**  
La version AWS SDK pour Java 1.x possède un package DynamoDB nommé. `com.amazonaws.dynamodbv2` Le « v2 » dans le nom du package n’indique pas qu’il s’agit de Java 2 (J2SE). « v2 » indique plutôt que le package prend en charge la [seconde version](CurrentAPI.md) de l’API de bas niveau DynamoDB au lieu de la [version d’origine](Appendix.APIv20111205.md) de l’API de bas niveau.

### Support pour les versions de Java
<a name="SupportedJavaVersions"></a>

 AWS SDK for Java 2.x Il fournit un support complet pour les [versions Java](https://github.com/aws/aws-sdk-java-v2?tab=readme-ov-file#maintenance-and-support-for-java-versions) de support à long terme (LTS).

## Commencer à utiliser le AWS SDK for Java 2.x
<a name="GetStartedProgrammingWithJavaSDK"></a>

Le didacticiel suivant montre comment utiliser [Apache Maven](https://maven.apache.org/) pour définir des dépendances pour le kit SDK pour Java 2.x. Ce didacticiel explique également comment écrire le code qui se connecte à DynamoDB pour répertorier les tables DynamoDB disponibles. Le didacticiel de ce guide est basé sur le didacticiel [Démarrer avec le kit AWS SDK for Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html) du *Guide du développeur du kit AWS SDK for Java 2.x *. Nous avons modifié ce didacticiel pour appeler DynamoDB au lieu d’Amazon S3.

**Topics**
+ [Étape 1 : Configuration pour ce didacticiel](#GetStartedJavaSetup)
+ [Étape 2 : Création du projet](#GetStartedJavaProjectSetup)
+ [Étape 3 : Écriture du code](#GetStartedJavaCode)
+ [Étape 4 : Création et exécution de l’application](#GetStartedRunJava)

### Étape 1 : Configuration pour ce didacticiel
<a name="GetStartedJavaSetup"></a>

Avant de commencer ce didacticiel, vous aurez besoin des éléments suivants :
+ Autorisation d’accès à DynamoDB.
+ Un environnement de développement Java configuré avec un accès par authentification unique à Services AWS l'aide du Portail d'accès AWS.

Pour procéder à la configuration pour ce didacticiel, suivez les instructions de [Présentation de la configuration](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-overview) dans le *Guide du développeur du kit AWS SDK for Java 2.x *. Une fois que vous avez [configuré votre environnement de développement avec un accès par authentification unique](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-credentials) pour le kit Java SDK et que vous disposez d’une [session de portail d’accès AWS active](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-login-sso), passez à l’[étape 2](#GetStartedJavaProjectSetup) de ce didacticiel.

### Étape 2 : Création du projet
<a name="GetStartedJavaProjectSetup"></a>

Pour créer le projet pour ce didacticiel, vous devez exécuter une commande Maven qui vous invite à saisir des informations sur la configuration du projet. Une fois toutes les entrées saisies et confirmées, Maven termine la création du projet en créant un fichier `pom.xml` et des fichiers Java stub.

1. Ouvrez un terminal ou une fenêtre d’invite de commande et naviguez jusqu’au répertoire de votre choix, par exemple, le dossier `Desktop` ou `Home`.

1. Saisissez la commande suivante sur le terminal et appuyez sur **Entrée**.

   ```
   mvn archetype:generate \
      -DarchetypeGroupId=software.amazon.awssdk \
      -DarchetypeArtifactId=archetype-app-quickstart \
      -DarchetypeVersion=2.22.0
   ```

1. Pour chaque invite, saisissez la valeur indiquée dans la deuxième colonne.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/ProgrammingWithJava.html)

1. Une fois que vous avez saisi la dernière valeur, Maven répertorie les choix que vous avez effectués. Pour confirmer, saisissez **O.** Vous pouvez également saisir **N**, puis saisir à nouveau vos choix.

Maven crée un dossier de projet nommé `getstarted` en fonction de la valeur `artifactId` que vous avez saisie. Dans le dossier `getstarted`, recherchez un fichier nommé `README.md` que vous pouvez consulter, un fichier `pom.xml` et un répertoire `src`.

Maven crée l’arborescence de répertoires suivante.

```
getstarted
 ├── README.md
 ├── pom.xml
 └── src
     ├── main
     │   ├── java
     │   │   └── org
     │   │       └── example
     │   │           ├── App.java
     │   │           ├── DependencyFactory.java
     │   │           └── Handler.java
     │   └── resources
     │       └── simplelogger.properties
     └── test
         └── java
             └── org
                 └── example
                     └── HandlerTest.java
 
 10 directories, 7 files
```

L’exemple suivant affiche le contenu du fichier du projet `pom.xml`.

#### `pom.xml`
<a name="ProjectSetupCollapse2"></a>

La section `dependencyManagement` contient une dépendance vis-à-vis du kit AWS SDK for Java 2.x, et la section `dependencies` possède une dépendance pour DynamoDB. La spécification de ces dépendances oblige Maven à inclure les fichiers `.jar` appropriés dans le chemin de la classe Java. Par défaut, le AWS SDK n'inclut pas toutes les classes pour tous Services AWS. Pour DynamoDB, si vous utilisez l’interface de bas niveau, vous devez avoir une dépendance à l’égard de l’artefact `dynamodb`. Ou, si vous utilisez l’interface de haut niveau, sur l’artefact `dynamodb-enhanced`. Si vous n’incluez pas les dépendances pertinentes, le code ne peut pas être compilé. Le projet utilise Java 1.8 en raison de la valeur `1.8` des propriétés `maven.compiler.source` et `maven.compiler.target`.

```
<?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
     <groupId>org.example</groupId>
     <artifactId>getstarted</artifactId>
     <version>1.0-SNAPSHOT</version>
     <packaging>jar</packaging>
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <maven.compiler.source>1.8</maven.compiler.source>
         <maven.compiler.target>1.8</maven.compiler.target>
         <maven.shade.plugin.version>3.2.1</maven.shade.plugin.version>
         <maven.compiler.plugin.version>3.6.1</maven.compiler.plugin.version>
         <exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>
         <aws.java.sdk.version>2.22.0</aws.java.sdk.version> <-------- SDK version picked up from archetype version.
         <slf4j.version>1.7.28</slf4j.version>
         <junit5.version>5.8.1</junit5.version>
     </properties>
 
     <dependencyManagement>
         <dependencies>
             <dependency>
                 <groupId>software.amazon.awssdk</groupId>
                 <artifactId>bom</artifactId>
                 <version>${aws.java.sdk.version}</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
         </dependencies>
     </dependencyManagement>
 
     <dependencies>
         <dependency>
             <groupId>software.amazon.awssdk</groupId>
             <artifactId>dynamodb</artifactId>  <-------- DynamoDB dependency
             <exclusions>
                 <exclusion>
                     <groupId>software.amazon.awssdk</groupId>
                     <artifactId>netty-nio-client</artifactId>
                 </exclusion>
                 <exclusion>
                     <groupId>software.amazon.awssdk</groupId>
                     <artifactId>apache-client</artifactId>
                 </exclusion>
             </exclusions>
         </dependency>
 
         <dependency>
             <groupId>software.amazon.awssdk</groupId>
             <artifactId>sso</artifactId> <-------- Required for identity center authentication.
         </dependency>
 
         <dependency>
             <groupId>software.amazon.awssdk</groupId>
             <artifactId>ssooidc</artifactId> <-------- Required for identity center authentication.
         </dependency>
 
         <dependency>
             <groupId>software.amazon.awssdk</groupId>
             <artifactId>apache-client</artifactId> <-------- HTTP client specified.
             <exclusions>
                 <exclusion>
                     <groupId>commons-logging</groupId>
                     <artifactId>commons-logging</artifactId>
                 </exclusion>
             </exclusions>
         </dependency>
 
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
             <version>${slf4j.version}</version>
         </dependency>
 
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-simple</artifactId>
             <version>${slf4j.version}</version>
         </dependency>
 
         <!-- Needed to adapt Apache Commons Logging used by Apache HTTP Client to Slf4j to avoid
         ClassNotFoundException: org.apache.commons.logging.impl.LogFactoryImpl during runtime -->
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>jcl-over-slf4j</artifactId>
             <version>${slf4j.version}</version>
         </dependency>
 
         <!-- Test Dependencies -->
         <dependency>
             <groupId>org.junit.jupiter</groupId>
             <artifactId>junit-jupiter</artifactId>
             <version>${junit5.version}</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
 
     <build>
         <plugins>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-compiler-plugin</artifactId>
                 <version>${maven.compiler.plugin.version}</version>
             </plugin>
         </plugins>
     </build>
 
 </project>
```

### Étape 3 : Écriture du code
<a name="GetStartedJavaCode"></a>

Le code suivant présente la classe `App` créée par Maven. La méthode `main` est le point d’entrée dans l’application, qui crée une instance de la classe `Handler` puis appelle sa méthode `sendRequest`.

#### classe `App`
<a name="projectsetup-collapse2"></a>

```
package org.example;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class App {
     private static final Logger logger = LoggerFactory.getLogger(App.class);
 
     public static void main(String... args) {
         logger.info("Application starts");
 
         Handler handler = new Handler();
         handler.sendRequest();
 
         logger.info("Application ends");
     }
 }
```

La classe `DependencyFactory` créée par Maven contient la méthode d’usine `dynamoDbClient` qui construit et renvoie une instance [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html). L’instance `DynamoDbClient` utilise une instance du client HTTP basé sur Apache. Cela est dû au fait que vous avez spécifié `apache-client` quand Maven vous a invité à spécifier le client HTTP à utiliser.

Le code suivant présente la classe `DependencyFactory`.

#### DependencyFactory classe
<a name="code-collapse2"></a>

```
package org.example;
 
 import software.amazon.awssdk.http.apache.ApacheHttpClient;
 import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
 
 /**
  * The module containing all dependencies required by the {@link Handler}.
  */
 public class DependencyFactory {
 
     private DependencyFactory() {}
 
     /**
      * @return an instance of DynamoDbClient
      */
     public static DynamoDbClient dynamoDbClient() {
         return DynamoDbClient.builder()
                        .httpClientBuilder(ApacheHttpClient.builder())
                        .build();
     }
 }
```

La classe `Handler` contient la logique principale de votre programme. Lorsqu’une instance de `Handler` est créée dans la classe `App`, la `DependencyFactory` fournit le client de service `DynamoDbClient`. Votre code utilise l’instance de `DynamoDbClient` pour appeler DynamoDB.

Maven génère la classe `Handler` suivante avec un commentaire `TODO`. L’étape suivante du didacticiel consiste à remplacer le commentaire *`TODO`* par du code.

#### Classe `Handler`, générée par Maven
<a name="code-collapsible3"></a>

```
package org.example;
 
 import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
 
 
 public class Handler {
     private final DynamoDbClient dynamoDbClient;
 
     public Handler() {
         dynamoDbClient = DependencyFactory.dynamoDbClient();
     }
 
     public void sendRequest() {
         // TODO: invoking the API calls using dynamoDbClient.
     }
 }
```

Pour renseigner la logique, remplacez l’ensemble du contenu de la classe `Handler` par le code suivant. La méthode `sendRequest` est renseignée et les importations nécessaires sont ajoutées.

#### Classe `Handler`, implémentée
<a name="code-collapse4"></a>

Le code suivant utilise l’instance [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html) pour extraire la liste des tables existantes. Si des tables existent pour un compte et une Région AWS donnés, le code utilise l’instance `Logger` pour enregistrer les noms de ces tables.

```
package org.example;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
 import software.amazon.awssdk.services.dynamodb.model.ListTablesResponse;
 
 
 public class Handler {
     private final DynamoDbClient dynamoDbClient;
 
     public Handler() {
         dynamoDbClient = DependencyFactory.dynamoDbClient();
     }
 
     public void sendRequest() {
         Logger logger = LoggerFactory.getLogger(Handler.class);
 
         logger.info("calling the DynamoDB API to get a list of existing tables");
         ListTablesResponse response = dynamoDbClient.listTables();
 
         if (!response.hasTableNames()) {
             logger.info("No existing tables found for the configured account & region");
         } else {
             response.tableNames().forEach(tableName -> logger.info("Table: " + tableName));
         }
     }
 }
```

### Étape 4 : Création et exécution de l’application
<a name="GetStartedRunJava"></a>

Une fois que vous avez créé le projet et qu’il contient la classe `Handler` complète, créez et exécutez l’application.

1. Assurez-vous d'avoir une AWS IAM Identity Center session active. Pour confirmer, exécutez la commande de l’ AWS Command Line Interface (AWS CLI) `aws sts get-caller-identity` et vérifiez la réponse. Si vous n’avez pas de session active, consultez [Connexion à l’aide de l’ AWS CLI](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-login-sso) pour obtenir des instructions.

1. Ouvrez un terminal ou une fenêtre d’invite de commande et accédez au répertoire de votre projet `getstarted`.

1. Pour créer votre projet, utilisez la commande suivante :

   ```
   mvn clean package
   ```

1. Pour exécuter l’application, exécutez la commande suivante :

   ```
   mvn exec:java -Dexec.mainClass="org.example.App"
   ```

Après avoir consulté le fichier, supprimez l’objet, puis le compartiment.

#### Réussite
<a name="GetStartedSuccessJava"></a>

Si votre projet Maven a été créé et exécuté sans erreur, félicitations \$1 Vous avez créé avec succès votre première application Java à l’aide du kit SDK pour Java 2.x.

#### Nettoyage
<a name="GetStartedCleanupJava"></a>

Pour nettoyer les ressources que vous avez créées au cours de ce didacticiel, supprimez le dossier du projet`getstarted`.

## Révision de la AWS SDK for Java 2.x documentation
<a name="ProgrammingWithJavaUseDoc"></a>

Le [Guide du développeur du kit AWS SDK for Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/home.html) couvre tous les aspects du kit SDK dans tous les Services AWS. Nous vous recommandons de consulter les rubriques suivantes :
+ [Migration de la version 1.x vers la version 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration.html) : inclut une explication détaillée des différences entre les versions 1.x et 2.x. Cette rubrique contient également des instructions sur l'utilisation des deux versions principales side-by-side.
+ [Guide DynamoDB pour le kit Java 2.x SDK](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/examples-dynamodb.html) : explique comment effectuer des opérations DynamoDB de base : créer une table, manipuler des éléments et extraire des éléments. Ces exemples utilisent l’interface de bas niveau. Java possède plusieurs interfaces, comme expliqué dans la section suivante : [Interfaces prises en charge](#JavaInterfaces).

**Astuce**  
Après avoir consulté ces rubriques, ajoutez la [Référence d’API du kit AWS SDK for Java 2.x](https://sdk.amazonaws.com/java/api/latest/) à vos favoris. Il couvre tout Services AWS, et nous vous recommandons de l'utiliser comme référence d'API principale.

## Interfaces prises en charge
<a name="JavaInterfaces"></a>

Il AWS SDK for Java 2.x prend en charge les interfaces suivantes, en fonction du niveau d'abstraction souhaité.

**Topics**
+ [Interface de bas niveau](#LowLevelInterface)
+ [Interface de haut niveau](#HighLevelInterface)
+ [Interface de document](#DocumentInterface)
+ [Comparaison d’interfaces avec un exemple de `Query`](#CompareJavaInterfacesQueryEx)

### Interface de bas niveau
<a name="LowLevelInterface"></a>

L'interface de bas niveau fournit un one-to-one mappage vers l'API de service sous-jacente. Chaque API DynamoDB est disponible via cette interface. Cela signifie que l’interface de bas niveau peut fournir des fonctionnalités complètes, mais elle est souvent plus détaillée et complexe à utiliser. Par exemple, vous devez utiliser les fonctions `.s()` pour contenir des chaînes et les fonctions `.n()` pour contenir des nombres. L'exemple suivant montre [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)comment insérer un élément à l'aide de l'interface de bas niveau.

```
import org.slf4j.*;
import software.amazon.awssdk.http.crt.AwsCrtHttpClient;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.*;

import java.util.Map;

public class PutItem {

    // Create a DynamoDB client with the default settings connected to the DynamoDB
    // endpoint in the default region based on the default credentials provider chain.
    private static final DynamoDbClient DYNAMODB_CLIENT = DynamoDbClient.create();
    private static final Logger LOGGER = LoggerFactory.getLogger(PutItem.class);

    private void putItem() {
        PutItemResponse response = DYNAMODB_CLIENT.putItem(PutItemRequest.builder()
                .item(Map.of(
                        "pk", AttributeValue.builder().s("123").build(),
                        "sk", AttributeValue.builder().s("cart#123").build(),
                        "item_data", AttributeValue.builder().s("YourItemData").build(),
                        "inventory", AttributeValue.builder().n("500").build()
                        // ... more attributes ...
                ))
                .returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
                .tableName("YourTableName")
                .build());
        LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)");
    }
}
```

### Interface de haut niveau
<a name="HighLevelInterface"></a>

L'interface de haut niveau du s' AWS SDK for Java 2.x appelle le client amélioré DynamoDB. Cette interface fournit une expérience de création de code plus idiomatique.

Le client amélioré permet de mapper les classes de données côté client et les tables DynamoDB conçues pour stocker ces données. Vous définissez les relations entre des tables et leurs classes de modèle correspondantes dans votre code. Vous pouvez ensuite compter sur le kit SDK pour gérer la manipulation des types de données. Pour plus d’informations sur le client amélioré, consultez [DynamoDB enhanced client API](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html) dans le *Guide du développeur du kit AWS SDK for Java 2.x *.

L'exemple suivant [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)utilise l'interface de haut niveau. Dans cet exemple, le `DynamoDbBean` nommé `YourItem` crée un `TableSchema` qui permet son utilisation directe comme entrée pour l’appel de `putItem()`.

```
import org.slf4j.*;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.*;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity;

public class DynamoDbEnhancedClientPutItem {
    private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
    private static final DynamoDbTable<YourItem> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.fromBean(YourItem.class));
    private static final Logger LOGGER = LoggerFactory.getLogger(PutItem.class);

    private void putItem() {
        PutItemEnhancedResponse<YourItem> response = DYNAMODB_TABLE.putItemWithResponse(PutItemEnhancedRequest.builder(YourItem.class)
                .item(new YourItem("123", "cart#123", "YourItemData", 500))
                .returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
                .build());
        LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)");
    }

    @DynamoDbBean
    public static class YourItem {

        public YourItem() {}

        public YourItem(String pk, String sk, String itemData, int inventory) {
            this.pk = pk;
            this.sk = sk;
            this.itemData = itemData;
            this.inventory = inventory;
        }

        private String pk;
        private String sk;
        private String itemData;

        private int inventory;

        @DynamoDbPartitionKey
        public void setPk(String pk) {
            this.pk = pk;
        }

        public String getPk() {
            return pk;
        }

        @DynamoDbSortKey
        public void setSk(String sk) {
            this.sk = sk;
        }

        public String getSk() {
            return sk;
        }

        public void setItemData(String itemData) {
            this.itemData = itemData;
        }

        public String getItemData() {
            return itemData;
        }

        public void setInventory(int inventory) {
            this.inventory = inventory;
        }

        public int getInventory() {
            return inventory;
        }
    }
}
```

La AWS SDK pour Java version 1.x possède sa propre interface de haut niveau, souvent désignée par sa classe `DynamoDBMapper` principale. AWS SDK for Java 2.x Il est publié dans un package distinct (et un artefact Maven) nommé. `software.amazon.awssdk.enhanced.dynamodb` Le kit Java 2.x SDK est souvent désigné par sa classe principale `DynamoDbEnhancedClient`.

#### Interface de haut niveau utilisant des classes de données immuables
<a name="HighLevelInterfaceImmutableDataClasses"></a>

La fonctionnalité de mappage de l’API client améliorée DynamoDB fonctionne également avec des classes de données immuables. Une classe immuable ne possède que des méthodes getter et nécessite une classe de générateur que le kit SDK utilise pour créer des instances de la classe. L’immuabilité en Java est un style couramment utilisé que les développeurs peuvent utiliser pour créer des classes sans effets secondaires. Le comportement de ces classes est plus prévisible dans les applications multithread complexes. Au lieu d’utiliser l’annotation `@DynamoDbBean` comme indiqué dans l’[High-level interface example](#highleveleg), les classes immuables utilisent l’annotation `@DynamoDbImmutable`, qui prend la classe de générateur comme entrée.

L’exemple suivant utilise la classe de générateur `DynamoDbEnhancedClientImmutablePutItem` comme entrée pour créer un schéma de table. L'exemple fournit ensuite le schéma comme entrée pour l'appel d'[PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)API.

```
import org.slf4j.*;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity;

public class DynamoDbEnhancedClientImmutablePutItem {
    private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
    private static final DynamoDbTable<YourImmutableItem> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.fromImmutableClass(YourImmutableItem.class));
    private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedClientImmutablePutItem.class);

    private void putItem() {
        PutItemEnhancedResponse<YourImmutableItem> response = DYNAMODB_TABLE.putItemWithResponse(PutItemEnhancedRequest.builder(YourImmutableItem.class)
                .item(YourImmutableItem.builder()
                                        .pk("123")
                                        .sk("cart#123")
                                        .itemData("YourItemData")
                                        .inventory(500)
                                        .build())
                .returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
                .build());
        LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)");
    }
}
```

L’exemple suivant illustre la classe de données immuables.

```
@DynamoDbImmutable(builder = YourImmutableItem.YourImmutableItemBuilder.class)
class YourImmutableItem {
    private final String pk;
    private final String sk;
    private final String itemData;
    private final int inventory;
    public YourImmutableItem(YourImmutableItemBuilder builder) {
        this.pk = builder.pk;
        this.sk = builder.sk;
        this.itemData = builder.itemData;
        this.inventory = builder.inventory;
    }

    public static YourImmutableItemBuilder builder() { return new YourImmutableItemBuilder(); }

    @DynamoDbPartitionKey
    public String getPk() {
        return pk;
    }

    @DynamoDbSortKey
    public String getSk() {
        return sk;
    }

    public String getItemData() {
        return itemData;
    }

    public int getInventory() {
        return inventory;
    }

    static final class YourImmutableItemBuilder {
        private String pk;
        private String sk;
        private String itemData;
        private int inventory;

        private YourImmutableItemBuilder() {}

        public YourImmutableItemBuilder pk(String pk) { this.pk = pk; return this; }
        public YourImmutableItemBuilder sk(String sk) { this.sk = sk; return this; }
        public YourImmutableItemBuilder itemData(String itemData) { this.itemData = itemData; return this; }
        public YourImmutableItemBuilder inventory(int inventory) { this.inventory = inventory; return this; }

        public YourImmutableItem build() { return new YourImmutableItem(this); }
    }
}
```

#### Interface de haut niveau utilisant des classes de données immuables et des bibliothèques de génération standard tierces
<a name="ImmutableDataClassesThirdPartyBoilerplateGenLib"></a>

Les classes de données immuables (illustrées dans l’exemple précédent) nécessitent un code standard. Par exemple, la logique getter et setter appliquée aux classes de données, en plus des classes `Builder`. Les bibliothèques tierces, telles que [Project Lombok](https://projectlombok.org/), peuvent vous aider à générer ce type de code standard. La réduction de la majeure partie du code standard vous permet de limiter la quantité de code nécessaire pour travailler avec les classes de données immuables et le SDK. AWS Cela se traduit également par une amélioration de la productivité et de la lisibilité du code. Pour plus d’informations, consultez [Use third-party libraries, such as Lombok](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-use-immut.html#ddb-en-client-use-immut-lombok), dans le *Guide du développeur du kit AWS SDK for Java 2.x *.

L’exemple suivant montre comment Project Lombok simplifie le code nécessaire à l’utilisation de l’API client améliorée DynamoDB.

```
import org.slf4j.*;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity;

public class DynamoDbEnhancedClientImmutableLombokPutItem {

    private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
    private static final DynamoDbTable<YourImmutableLombokItem> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.fromImmutableClass(YourImmutableLombokItem.class));
    private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedClientImmutableLombokPutItem.class);

    private void putItem() {
        PutItemEnhancedResponse<YourImmutableLombokItem> response = DYNAMODB_TABLE.putItemWithResponse(PutItemEnhancedRequest.builder(YourImmutableLombokItem.class)
                .item(YourImmutableLombokItem.builder()
                        .pk("123")
                        .sk("cart#123")
                        .itemData("YourItemData")
                        .inventory(500)
                        .build())
                .returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
                .build());
        LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)");
    }
}
```

L’exemple suivant illustre l’objet de données immuables de la classe de données immuables.

```
import lombok.*;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.*;

@Builder
@DynamoDbImmutable(builder = YourImmutableLombokItem.YourImmutableLombokItemBuilder.class)
@Value
public class YourImmutableLombokItem {

    @Getter(onMethod_=@DynamoDbPartitionKey)
    String pk;
    @Getter(onMethod_=@DynamoDbSortKey)
    String sk;
    String itemData;
    int inventory;
}
```

La `YourImmutableLombokItem` classe utilise les annotations suivantes fournies par Project Lombok et le AWS SDK :
+ [@Builder](https://projectlombok.org/features/Builder) — Produit un générateur complexe APIs pour les classes de données fourni par Project Lombok.
+ [@ DynamoDbImmutable](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/mapper/annotations/DynamoDbImmutable.html) — Identifie la `DynamoDbImmutable` classe en tant qu'annotation d'entité mappable DynamoDB fournie par le SDK. AWS 
+ [@Value](https://projectlombok.org/features/Value) : variante immuable de `@Data`. Par défaut, tous les champs sont définis comme privés et définitifs, et les méthodes setter ne sont pas générées. Project Lombok fournit cette annotation.

### Interface de document
<a name="DocumentInterface"></a>

L'interface AWS SDK for Java 2.x Document évite d'avoir à spécifier des descripteurs de type de données. Les types de données découlent de la sémantique des données proprement dites. Cette interface de document est similaire à l'interface de document AWS SDK pour Java 1.x, mais avec une interface repensée.

L’[Document interface example](#DocInterfaceEg) suivant montre l’appel de `PutItem` exprimé à l’aide de l’interface de document. L'exemple utilise également EnhancedDocument. Pour exécuter des commandes sur une table DynamoDB à l’aide de l’API de document améliorée, vous devez d’abord associer la table au schéma de votre table de documents pour créer un objet de ressource `DynamoDBTable`. Le générateur de schéma de table de documents nécessite les principaux fournisseurs de clés d’index et de convertisseurs d’attributs.

Vous pouvez utiliser `AttributeConverterProvider.defaultProvider()` pour convertir les attributs de document des types par défaut. Vous pouvez modifier le comportement général par défaut à l’aide d’une implémentation de `AttributeConverterProvider` personnalisée. Vous pouvez également modifier le convertisseur pour un seul attribut. Le [guide de référence AWS SDKs and Tools](https://docs.aws.amazon.com/sdkref/latest/guide/version-support-matrix.html) fournit plus de détails et des exemples sur l'utilisation de convertisseurs personnalisés. Ils sont principalement utilisés pour les attributs des classes de domaine pour lesquels aucun convertisseur par défaut n’est disponible. À l’aide d’un convertisseur personnalisé, vous pouvez fournir au kit SDK les informations nécessaires pour écrire ou lire dans DynamoDB.

```
import org.slf4j.*;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.document.EnhancedDocument;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity;

public class DynamoDbEnhancedDocumentClientPutItem {
    private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
    private static final DynamoDbTable<EnhancedDocument> DYNAMODB_TABLE =
            ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.documentSchemaBuilder()
                            .addIndexPartitionKey(TableMetadata.primaryIndexName(),"pk", AttributeValueType.S)
                            .addIndexSortKey(TableMetadata.primaryIndexName(), "sk", AttributeValueType.S)
                            .attributeConverterProviders(AttributeConverterProvider.defaultProvider())
                            .build());

    private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedDocumentClientPutItem.class);

    private void putItem() {
        PutItemEnhancedResponse<EnhancedDocument> response = DYNAMODB_TABLE.putItemWithResponse(
                        PutItemEnhancedRequest.builder(EnhancedDocument.class)
                                .item(
                                    EnhancedDocument.builder()
                                            .attributeConverterProviders(AttributeConverterProvider.defaultProvider())
                                            .putString("pk", "123")
                                            .putString("sk", "cart#123")
                                            .putString("item_data", "YourItemData")
                                            .putNumber("inventory", 500)
                                            .build())
                                .returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
                                .build());
        LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)");
    }

}
```

Pour convertir des documents JSON en types de données Amazon DynamoDB natifs, vous pouvez utiliser les méthodes utilitaires suivantes :
+ [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html#fromJson(java.lang.String)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html#fromJson(java.lang.String))— Crée une nouvelle EnhancedDocument instance à partir d'une chaîne JSON.
+ [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html#toJson()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html#toJson()) : crée une représentation sous forme de chaîne JSON du document que vous pouvez utiliser dans votre application comme n’importe quel autre objet JSON.

### Comparaison d’interfaces avec un exemple de `Query`
<a name="CompareJavaInterfacesQueryEx"></a>

Cette section montre le même appel de [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html) exprimé à l’aide des différentes interfaces. Pour optimiser les résultats de ces requêtes, notez ce qui suit :
+ DynamoDB cible une valeur de clé de partition spécifique. Vous devez donc spécifier la clé de partition dans son intégralité.
+ Pour que la requête cible uniquement les articles du panier, la clé de tri possède une expression de condition clé qui utilise `begins_with`.
+ Nous utilisons `limit()` pour limiter la requête à un maximum de 100 articles renvoyés.
+ Nous avons défini `scanIndexForward` sur false. Les résultats sont renvoyés dans l’ordre des octets UTF-8, ce qui signifie généralement que l’article du panier avec le numéro le plus bas est renvoyé en premier. En définissant `scanIndexForward` sur false, nous annulons la commande et l’article du panier avec le numéro le plus élevé est renvoyé en premier.
+ Nous appliquons un filtre pour supprimer tout résultat ne correspondant pas aux critères. Les données filtrées consomment de la capacité de lecture, que l’élément corresponde au filtre ou non.

**Example `Query` avec l’interface de bas niveau**  
L’exemple suivant interroge un élément à partir de la table nommée `YourTableName` à l’aide d’une `keyConditionExpression`. Cela limite la requête à une valeur de clé de partition spécifique et à une valeur de clé de tri commençant par une valeur de préfixe spécifique. Ces conditions clés limitent la quantité de données lues depuis DynamoDB. Enfin, la requête applique un filtre sur les données extraites de DynamoDB à l’aide d’une `filterExpression`.  

```
import org.slf4j.*;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.*;

import java.util.Map;

public class Query {

    // Create a DynamoDB client with the default settings connected to the DynamoDB 
    // endpoint in the default region based on the default credentials provider chain.
    private static final DynamoDbClient DYNAMODB_CLIENT = DynamoDbClient.builder().build();
    private static final Logger LOGGER = LoggerFactory.getLogger(Query.class);

    private static void query() {
        QueryResponse response = DYNAMODB_CLIENT.query(QueryRequest.builder()
                .expressionAttributeNames(Map.of("#name", "name"))
                .expressionAttributeValues(Map.of(
                    ":pk_val", AttributeValue.fromS("id#1"),
                    ":sk_val", AttributeValue.fromS("cart#"),
                    ":name_val", AttributeValue.fromS("SomeName")))
                .filterExpression("#name = :name_val")
                .keyConditionExpression("pk = :pk_val AND begins_with(sk, :sk_val)")
                .limit(100)
                .scanIndexForward(false)
                .tableName("YourTableName")
                .build());

        LOGGER.info("nr of items: " + response.count());
        LOGGER.info("First item pk: " + response.items().get(0).get("pk"));
        LOGGER.info("First item sk: " + response.items().get(0).get("sk"));
    }
}
```

**Example `Query` avec l’interface de document**  
L’exemple suivant interroge une table nommée `YourTableName` à l’aide de l’interface de document.  

```
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.document.EnhancedDocument;
import software.amazon.awssdk.enhanced.dynamodb.model.*;

import java.util.Map;

public class DynamoDbEnhancedDocumentClientQuery {

    // Create a DynamoDB client with the default settings connected to the DynamoDB 
    // endpoint in the default region based on the default credentials provider chain.
    private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
    private static final DynamoDbTable<EnhancedDocument> DYNAMODB_TABLE =
            ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.documentSchemaBuilder()
                    .addIndexPartitionKey(TableMetadata.primaryIndexName(),"pk", AttributeValueType.S)
                    .addIndexSortKey(TableMetadata.primaryIndexName(), "sk", AttributeValueType.S)
                    .attributeConverterProviders(AttributeConverterProvider.defaultProvider())
                    .build());
    private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedDocumentClientQuery.class);

    private void query() {
        PageIterable<EnhancedDocument> response = DYNAMODB_TABLE.query(QueryEnhancedRequest.builder()
                .filterExpression(Expression.builder()
                        .expression("#name = :name_val")
                        .expressionNames(Map.of("#name", "name"))
                        .expressionValues(Map.of(":name_val", AttributeValue.fromS("SomeName")))
                        .build())
                .limit(100)
                .queryConditional(QueryConditional.sortBeginsWith(Key.builder()
                        .partitionValue("id#1")
                        .sortValue("cart#")
                        .build()))
                .scanIndexForward(false)
                .build());

        LOGGER.info("nr of items: " + response.items().stream().count());
        LOGGER.info("First item pk: " + response.items().iterator().next().getString("pk"));
        LOGGER.info("First item sk: " + response.items().iterator().next().getString("sk"));

    }
}
```

**Example `Query` avec l’interface de haut niveau**  
L’exemple suivant interroge une table nommée `YourTableName` à l’aide de l’API client améliorée DynamoDB.  

```
import org.slf4j.*;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.*;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;

import java.util.Map;

public class DynamoDbEnhancedClientQuery {

    private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
    private static final DynamoDbTable<YourItem> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.fromBean(DynamoDbEnhancedClientQuery.YourItem.class));
    private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedClientQuery.class);

    private void query() {
        PageIterable<YourItem> response = DYNAMODB_TABLE.query(QueryEnhancedRequest.builder()
                .filterExpression(Expression.builder()
                        .expression("#name = :name_val")
                        .expressionNames(Map.of("#name", "name"))
                        .expressionValues(Map.of(":name_val", AttributeValue.fromS("SomeName")))
                        .build())
                .limit(100)
                .queryConditional(QueryConditional.sortBeginsWith(Key.builder()
                        .partitionValue("id#1")
                        .sortValue("cart#")
                        .build()))
                .scanIndexForward(false)
                .build());

        LOGGER.info("nr of items: " + response.items().stream().count());
        LOGGER.info("First item pk: " + response.items().iterator().next().getPk());
        LOGGER.info("First item sk: " + response.items().iterator().next().getSk());
    }

    @DynamoDbBean
    public static class YourItem {

        public YourItem() {}

        public YourItem(String pk, String sk, String name) {
            this.pk = pk;
            this.sk = sk;
            this.name = name;
        }

        private String pk;
        private String sk;
        private String name;

        @DynamoDbPartitionKey
        public void setPk(String pk) {
            this.pk = pk;
        }

        public String getPk() {
            return pk;
        }

        @DynamoDbSortKey
        public void setSk(String sk) {
            this.sk = sk;
        }

        public String getSk() {
            return sk;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
    }
}
```
**Interface de haut niveau utilisant des classes de données immuables**  
Lorsque vous effectuez une opération `Query` avec les classes de données immuables de haut niveau, le code est le même que celui de l’exemple d’interface de haut niveau, à l’exception de la construction de la classe d’entité `YourItem` ou `YourImmutableItem`. Pour plus d'informations, consultez l'[PutItem](#HighLevelImmutableDataClassEg)exemple.
**Interface de haut niveau utilisant des classes de données immuables et des bibliothèques de génération standard tierces**  
Lorsque vous effectuez une opération `Query` avec les classes de données immuables de haut niveau, le code est le même que celui de l’exemple d’interface de haut niveau, à l’exception de la construction de la classe d’entité `YourItem` ou `YourImmutableLombokItem`. Pour plus d'informations, consultez l'[PutItem](#HighLevelImmutableDataClassEg)exemple.

## Exemples supplémentaires de code
<a name="AdditionalCodeEx"></a>

Pour des exemples supplémentaires d’utilisation de DynamoDB avec le kit SDK pour Java 2.x, reportez-vous aux référentiels d’exemples de code suivants :
+ [Exemples de codes à action unique AWS officiels](https://docs.aws.amazon.com/code-library/latest/ug/java_2_dynamodb_code_examples.html)
+ [Exemples de code à action unique gérés par la communauté](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/examples/SDK/java)
+ [Exemples de code officiels AWS orientés vers des scénarios](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/examples/SDK/java)

## Programmation synchrone et asynchrone
<a name="SyncAsyncProgramming"></a>

 AWS SDK for Java 2.x fournit à la fois des clients *synchrones* *et asynchrones* pour Services AWS, tels que DynamoDB.

Les classes `DynamoDbClient` et `DynamoDbEnhancedClient` fournissent des méthodes synchrones qui bloquent l’exécution du thread jusqu’à ce que le client reçoive une réponse du service. Ce client est le moyen le plus simple d’interagir avec DynamoDB si vous n’avez pas besoin d’opérations asynchrones.

Les classes `DynamoDbAsyncClient` et `DynamoDbEnhancedAsyncClient` fournissent des méthodes asynchrones qui renvoient immédiatement, en rendant le contrôle au thread appelant sans attendre de réponse. Le client non bloquant présente l’avantage d’une simultanéité élevée sur quelques threads, ce qui permet de traiter efficacement les demandes d’E/S avec un minimum de ressources de calcul. Cela améliore le débit et la réactivité.

Il AWS SDK for Java 2.x utilise le support natif pour les E/S non bloquantes. La version AWS SDK pour Java 1.x devait simuler des E/S non bloquantes.

Dans la mesure où une méthode synchrone renvoie avant qu’une réponse ne soit disponible, vous avez besoin d’une solution pour obtenir la réponse quand elle est prête. Les méthodes asynchrones AWS SDK pour Java renvoient un [https://docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/CompletableFuture.html](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/CompletableFuture.html)objet contenant les résultats de l'opération asynchrone à venir. Lorsque vous appelez `get()` ou utilisez `join()` sur ces objets `CompletableFuture`, le code se bloque jusqu’à ce que le résultat soit disponible. Si vous les appelez en même temps que vous faites la demande, le comportement est similaire à celui d’un simple appel synchrone.

Pour plus d’informations sur la programmation asynchrone, consultez [Use asynchronous programming](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/asynchronous.html) dans le *Guide du développeur du kit AWS SDK for Java 2.x *.

## Clients HTTP
<a name="HttpClients"></a>

Pour prendre en charge chaque client, il existe un client HTTP qui gère les communications avec les Services AWS. Vous pouvez connecter d’autres clients HTTP en choisissant celui qui présente les caractéristiques les mieux adaptées à votre application. Certains sont plus légers ; d’autres offrent davantage d’options de configuration.

Certains clients HTTP ne prennent en charge que l’utilisation synchrone, tandis que d’autres prennent uniquement en charge l’utilisation asynchrone. Pour un organigramme qui peut vous aider à sélectionner le client HTTP optimal pour votre charge de travail, consultez [HTTP client recommendations](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration.html#http-clients-recommend) dans le *Guide du développeur du kit AWS SDK for Java 2.x *.

La liste suivante présente certains des clients HTTP possibles :

**Topics**
+ [Client HTTP basé sur Apache](#ApacheHttpClient)
+ [Client HTTP basé sur `URLConnection`](#URLConnHttpClient)
+ [Client HTTP basé sur Netty](#NettyHttpClient)
+ [AWS Client HTTP basé sur CRT](#AWSCRTHttpClient)

### Client HTTP basé sur Apache
<a name="ApacheHttpClient"></a>

La classe [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/apache/ApacheHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/apache/ApacheHttpClient.html) prend en charge les clients de service synchrones. Il s’agit du client HTTP par défaut pour une utilisation synchrone. Pour en savoir plus sur la configuration de la classe `ApacheHttpClient`, consultez [Configuration du client HTTP basé sur Apache](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-apache.html) dans le *Guide du développeur du kit AWS SDK for Java 2.x *.

### Client HTTP basé sur `URLConnection`
<a name="URLConnHttpClient"></a>

La classe [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClient.html) est une autre option pour les clients synchrones. Elle se charge plus rapidement que le client HTTP basé sur Apache, mais possède moins de fonctionnalités. Pour plus d'informations sur la configuration `UrlConnectionHttpClient` de la classe, voir [Configurer le client HTTP URLConnection basé](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-url.html) dans le *Guide du AWS SDK for Java 2.x développeur*.

### Client HTTP basé sur Netty
<a name="NettyHttpClient"></a>

La classe `NettyNioAsyncHttpClient` prend en charge les clients asynchrones. C’est le choix par défaut pour une utilisation asynchrone. Pour en savoir plus sur la configuration de la classe `NettyNioAsyncHttpClient`, consultez [Configure the Netty-based HTTP client](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-netty.html) dans le *Guide du développeur du kit AWS SDK for Java 2.x *.

### AWS Client HTTP basé sur CRT
<a name="AWSCRTHttpClient"></a>

Les nouvelles `AwsCrtAsyncHttpClient` classes `AwsCrtHttpClient` et les classes des bibliothèques AWS Common Runtime (CRT) sont davantage des options qui prennent en charge les clients synchrones et asynchrones. Comparé aux autres clients HTTP, AWS CRT propose :
+ Temps de démarrage plus rapide du kit SDK
+ Empreinte mémoire réduite
+ Temps de latence réduit
+ Gestion de l’état des connexions
+ Équilibrage de charge DNS

Pour plus d'informations sur la configuration `AwsCrtAsyncHttpClient` des classes `AwsCrtHttpClient` et, voir [Configurer les clients HTTP AWS basés sur CRT](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-crt.html) dans le Guide du *AWS SDK for Java 2.x développeur*.

Le client HTTP AWS CRT n'est pas le client par défaut car cela romprait la rétrocompatibilité des applications existantes. Toutefois, pour DynamoDB, nous vous recommandons d'utiliser AWS le client HTTP CRT pour les utilisations synchronisées et asynchrones.

Pour une présentation du client HTTP AWS CRT, voir [Annonce de la disponibilité du client HTTP AWS CRT AWS SDK for Java 2.x sur le blog consacré](https://aws.amazon.com/blogs/developer/announcing-availability-of-the-aws-crt-http-client-in-the-aws-sdk-for-java-2-x/) aux outils de *AWS développement*.

## Configuration d’un client HTTP
<a name="ConfigHttpClient"></a>

Lorsque vous configurez un client, vous pouvez proposer différentes options de configuration, notamment :
+ Définition de délais d’expiration pour différents aspects des appels d’API.
+ Activation de TCP Keep-Alive.
+ Contrôle de la politique de nouvelles tentatives en cas d’erreur.
+ Spécification des attributs d’exécution que les instances d’[intercepteur d’exécution](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/interceptors.html) peuvent modifier. Les intercepteurs d’exécution peuvent écrire du code qui intercepte l’exécution des demandes et réponses d’API. Cela vous permet d’effectuer des tâches telles que la publication de métriques et la modification des demandes en cours de route.
+ Ajout ou manipulation des en-têtes HTTP.
+ Activation du suivi des [métriques de performance côté client](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/metrics.html). L'utilisation de cette fonctionnalité vous permet de collecter des statistiques sur les clients du service dans votre application et d'analyser les résultats sur Amazon CloudWatch.
+ Spécification d’un autre service d’exécuteur à utiliser pour planifier les tâches, telles que les nouvelles tentatives asynchrones et les tâches de délai d’expiration.

Vous contrôlez la configuration en fournissant un objet [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/ClientOverrideConfiguration.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/ClientOverrideConfiguration.html) à la classe `Builder` du client de service. Vous le verrez dans certains exemples de code dans les sections suivantes.

La `ClientOverrideConfiguration` fournit des choix de configuration standard. Les différents clients HTTP enfichables offrent également des possibilités de configuration spécifiques à l’implémentation.

**Topics**
+ [Configuration du délai d’attente](#TimeoutConfig)
+ [RetryMode](#RetryMode)
+ [DefaultsMode](#DefaultsMode)
+ [Configuration de Keep-Alive](#KeepAliveConfig)

### Configuration du délai d’attente
<a name="TimeoutConfig"></a>

Vous pouvez ajuster la configuration du client pour contrôler les différents délais d’expiration liés aux appels de service. DynamoDB fournit des latences plus faibles que les autres Services AWS. Par conséquent, vous souhaiterez peut-être ajuster ces propriétés pour réduire les valeurs de délai d’expiration afin de pouvoir procéder à une interruption immédiate en cas de problème réseau.

Vous pouvez personnaliser le comportement lié à la latence à l’aide de la `ClientOverrideConfiguration` du client DynamoDB ou en modifiant les options de configuration détaillées sur l’implémentation du client HTTP sous-jacent.

Vous pouvez configurer les propriétés percutantes suivantes à l’aide de la `ClientOverrideConfiguration` :
+ `apiCallAttemptTimeout` : temps d’attente d’une seule tentative pour qu’une demande HTTP soit terminée avant d’abandonner et de dépasser le délai imparti.
+ `apiCallTimeout` : durée dont dispose le client pour exécuter complètement un appel d’API. Cela inclut l’exécution du gestionnaire de demandes qui comprend toutes les demandes HTTP, y compris les nouvelles tentatives.

 AWS SDK for Java 2.x fournit des [valeurs par défaut](https://github.com/aws/aws-sdk-java-v2/blob/a0c8a0af1fa572b16b5bd78f310594d642324156/http-client-spi/src/main/java/software/amazon/awssdk/http/SdkHttpConfigurationOption.java#L134) pour certaines options de temporisation, telles que le délai de connexion et le délai d'expiration du socket. Le kit SDK ne fournit pas de valeurs par défaut pour les délais d’expiration d’appel d’API ou les délais d’expiration individuels des tentatives d’appel d’API. Si ces délais d’expiration ne sont pas définis dans la `ClientOverrideConfiguration`, le kit SDK utilise plutôt la valeur du délai d’expiration du socket pour le délai d’expiration global d’appel d’API. La délai d’expiration du socket a une valeur par défaut de 30 secondes.

### RetryMode
<a name="RetryMode"></a>

Une autre configuration liée à la configuration du délai d’expiration que vous devez prendre en compte est l’objet de configuration `RetryMode`. Cet objet de configuration contient un ensemble de comportements de nouvelle tentative.

Le kit SDK pour Java 2.x est compatible avec les modes de nouvelle tentative suivants :
+ `legacy` : mode de nouvelle tentative par défaut si vous ne le modifiez pas explicitement. Ce mode de nouvelle tentative est spécifique au kit Java SDK. Il se caractérise par un maximum de trois nouvelles tentatives, voire plus pour des services tels que DynamoDB, qui compte jusqu’à huit nouvelles tentatives.
+ `standard`— Nommé « standard » parce qu'il est plus cohérent avec les autres AWS SDKs. Ce mode attend une durée aléatoire comprise entre 0 ms et 1 000 ms pour la première nouvelle tentative. Si une autre nouvelle tentative est nécessaire, ce mode choisit un autre temps aléatoire compris entre 0 ms et 1 000 ms et le multiplie par deux. Si une nouvelle tentative supplémentaire est nécessaire, il effectue le même choix aléatoire multiplié par quatre, et ainsi de suite. Chaque attente est limitée à 20 secondes. Ce mode effectue de nouvelles tentatives sur un plus grand nombre de conditions de défaillance détectées que le mode `legacy` lui-même. Pour DynamoDB, il effectue jusqu’à trois tentatives maximum au total, sauf si vous remplacez la valeur par [numRetries](#numRetries).
+ `adaptive` : s’appuie sur le mode `standard` et limite dynamiquement le taux de demandes AWS afin de maximiser le taux de réussite. Cela peut se produire au détriment de la latence de demande. Nous ne recommandons pas le mode de nouvelle tentative adaptatif lorsqu’une latence prévisible est importante.

Vous trouverez une définition détaillée de ces modes de nouvelle tentative dans la rubrique [Comportement des nouvelles tentatives](https://docs.aws.amazon.com/sdkref/latest/guide/feature-retry-behavior.html) du Guide de *référence sur les outils AWS SDKs and*.

#### Politiques de nouvelles tentatives
<a name="RetryPolicies"></a>

Toutes les configurations de `RetryMode` ont une [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/RetryPolicy.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/RetryPolicy.html), qui est construite sur la base d’une ou plusieurs configurations de [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/RetryCondition.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/RetryCondition.html). Cette [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/TokenBucketRetryCondition.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/TokenBucketRetryCondition.html) est particulièrement importante pour le comportement de nouvelle tentative de l’implémentation du client de kit SDK DynamoDB. Cette condition limite le nombre de nouvelles tentatives effectuées par le kit SDK à l’aide d’un algorithme de compartiment de jetons. Selon le mode de nouvelle tentative sélectionné, les exceptions de limitation peuvent ou non soustraire des jetons au `TokenBucket`.

Lorsqu’un client rencontre une erreur pouvant faire l’objet d’une nouvelle tentative, telle qu’une exception de limitation ou une erreur temporaire du serveur, le kit SDK fait automatiquement une nouvelle tentative de demande. Vous pouvez contrôler le nombre de nouvelles tentatives et la rapidité avec lesquelles elles ont lieu.

Lorsque vous configurez un client, vous pouvez fournir une `RetryPolicy` qui prend en charge les paramètres suivants :
+ `numRetries` : nombre maximum de nouvelles tentatives qui doivent être appliquées avant qu’une demande ne soit considérée comme ayant échoué. La valeur par défaut est 8 quel que soit le mode de nouvelle tentative que vous utilisez.
**Avertissement**  
Assurez-vous de modifier cette valeur par défaut après mûre réflexion.
+ `backoffStrategy` : la [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/backoff/BackoffStrategy.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/backoff/BackoffStrategy.html) à appliquer aux nouvelles tentatives, [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/backoff/FullJitterBackoffStrategy.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/backoff/FullJitterBackoffStrategy.html) étant la stratégie par défaut. Cette stratégie applique un délai exponentiel entre les nouvelles tentatives supplémentaires en fonction du nombre actuel de nouvelles tentatives, d’un délai de base et d’un temps de backoff maximal. Cela ajoute ensuite de la nervosité pour créer un peu de hasard. Le délai de base utilisé dans le délai exponentiel est de 25 ms quel que soit le mode de nouvelle tentative.
+ `retryCondition` : la [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/RetryCondition.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/RetryCondition.html) détermine si une demande doit faire l’objet d’une nouvelle tentative. Par défaut, elle effectue de nouvelles tentatives pour un ensemble spécifique de codes de statut HTTP et d’exceptions pour lesquels juge qu’il est possible d’effectuer de nouvelles tentatives. Dans la plupart des cas, la configuration par défaut devrait être suffisante.

Le code suivant fournit une politique de nouvelles tentatives alternative. Il indique un total de cinq nouvelles tentatives (six demandes au total). La première nouvelle tentative doit avoir lieu après un délai d’environ 100 ms, chaque nouvelle tentative doublant ce temps de façon exponentielle, jusqu’à un délai maximum d’une seconde.

```
DynamoDbClient client = DynamoDbClient.builder()
    .overrideConfiguration(ClientOverrideConfiguration.builder()
        .retryPolicy(RetryPolicy.builder()
            .backoffStrategy(FullJitterBackoffStrategy.builder()
                .baseDelay(Duration.ofMillis(100))
                .maxBackoffTime(Duration.ofSeconds(1))
                .build())
            .numRetries(5)
            .build())
        .build())
    .build();
```

### DefaultsMode
<a name="DefaultsMode"></a>

Les propriétés de délai d’expiration que la `ClientOverrideConfiguration` et le `RetryMode` ne gèrent pas sont généralement configurées implicitement en spécifiant un `DefaultsMode`.

La AWS SDK for Java 2.x (version 2.17.102 ou ultérieure) a introduit la prise en charge de. `DefaultsMode` Cette fonctionnalité fournit un ensemble de valeurs par défaut pour les paramètres configurables courants, tels que les paramètres de communication HTTP, le comportement des nouvelles tentatives, les paramètres de point de terminaison régionaux du service et potentiellement toute configuration liée au kit SDK. Lorsque vous utilisez cette fonctionnalité, vous pouvez obtenir de nouvelles valeurs de configuration par défaut adaptées aux scénarios d’utilisation courants.

Les modes par défaut sont normalisés pour tous les AWS SDKs. Le kit SDK pour Java 2.x est compatible avec les modes par défaut suivants :
+ `legacy` : fournit des paramètres par défaut qui varient selon le kit AWS SDK et qui existaient avant la création du `DefaultsMode`.
+ `standard` : fournit des paramètres non optimisés par défaut pour la plupart des scénarios.
+ `in-region`— S'appuie sur le mode standard et inclut des paramètres adaptés aux applications qui appellent Services AWS depuis le même mode Région AWS.
+ `cross-region` : s’appuie sur le mode standard et inclut des paramètres avec des délais d’expiration élevés pour les applications qui appellent les Services AWS dans une région différente.
+ `mobile` : s’appuie sur le mode standard et inclut des paramètres avec des délais d’expiration élevés adaptés aux applications mobiles présentant des latences plus élevées.
+ `auto` : s’appuie sur le mode standard et inclut des fonctionnalités expérimentales. Le kit SDK tente de découvrir l’environnement d’exécution afin de déterminer automatiquement les paramètres appropriés. La détection automatique est basée sur l’heuristique et ne fournit pas une précision de 100 %. Si l’environnement d’exécution ne peut pas être déterminé, le mode standard est utilisé. La détection automatique peut interroger les [métadonnées de l’instance et les données utilisateur](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html), ce qui peut introduire de la latence. Si la latence de démarrage est essentielle pour votre application, nous vous recommandons de choisir plutôt un `DefaultsMode` explicite.

Vous pouvez configurer le mode de valeurs par défaut des manières suivantes :
+ Directement sur un client, par le biais de `AwsClientBuilder.Builder#defaultsMode(DefaultsMode)`.
+ Sur un profil de configuration, par le biais de la propriété du fichier de profil `defaults_mode`.
+ Globalement, par le biais de la propriété système `aws.defaultsMode`.
+ Globalement, par le biais de la variable d’environnement `AWS_DEFAULTS_MODE`.

**Note**  
Pour tout mode autre que `legacy`, les valeurs par défaut fournies peuvent changer à mesure que les bonnes pratiques évoluent. Par conséquent, si vous utilisez un mode autre que `legacy`, nous vous encourageons à effectuer des tests lors de la mise à niveau du kit SDK.

La [section Paramètres de configuration intelligente](https://docs.aws.amazon.com/sdkref/latest/guide/feature-smart-config-defaults.html) du *guide de référence AWS SDKs and Tools* fournit une liste des propriétés de configuration et de leurs valeurs par défaut dans les différents modes par défaut.

Vous choisissez la valeur du mode par défaut en fonction des caractéristiques de votre application et du mode avec Service AWS lequel l'application interagit.

Ces valeurs sont configurées en tenant compte d'une large sélection Services AWS de valeurs. Pour un déploiement de DynamoDB classique dans lequel les tables DynamoDB et l’application sont déployées dans une seule région, le mode par défaut `in-region` est le plus pertinent parmi les modes par défaut `standard`.

**Example Configuration du client du kit SDK DynamoDB optimisée pour les appels à faible latence**  
L’exemple suivant ajuste les délais d’expiration afin de réduire les valeurs d’un appel DynamoDB à faible latence attendu.  

```
DynamoDbAsyncClient asyncClient = DynamoDbAsyncClient.builder()
    .defaultsMode(DefaultsMode.IN_REGION)
    .httpClientBuilder(AwsCrtAsyncHttpClient.builder())
    .overrideConfiguration(ClientOverrideConfiguration.builder()
        .apiCallTimeout(Duration.ofSeconds(3))
        .apiCallAttemptTimeout(Duration.ofMillis(500))
        .build())
    .build();
```
L’implémentation individuelle du client HTTP peut vous permettre de contrôler encore plus précisément le délai d’expiration et le comportement d’utilisation de la connexion. Par exemple, pour le client AWS basé sur CRT, vous pouvez l'activer`ConnectionHealthConfiguration`, ce qui permet au client de surveiller activement l'état des connexions utilisées. Pour plus d'informations, consultez la section [Configuration avancée des clients HTTP AWS CRT](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-crt.html#configuring-the-crt-based-http-client) dans le Guide du *AWS SDK for Java 2.x développeur*.

### Configuration de Keep-Alive
<a name="KeepAliveConfig"></a>

L’activation du mode keep-alive permet de réduire les latences en réutilisant les connexions. Il existe deux types de keep-alive : HTTP Keep-Alive et TCP Keep-Alive.
+ HTTP Keep-Alive tente de maintenir la connexion HTTPS entre le client et le serveur afin que les demandes ultérieures puissent réutiliser cette connexion. Cela permet d’éviter l’authentification HTTPS lourde lors des demandes ultérieures. HTTP Keep-Alive est activé par défaut sur tous les clients.
+ TCP Keep-Alive demande au système d’exploitation sous-jacent d’envoyer de petits paquets via la connexion socket afin de garantir que le socket est maintenu en vie et de détecter immédiatement tout abandon. Cela garantit qu’une demande ultérieure ne perdra pas de temps à essayer d’utiliser un socket abandonné. Par défaut, TCP Keep-Alive est désactivé sur tous les clients. Les exemples de code suivants montrent comment l’activer sur chaque client HTTP. Lorsqu’il est activé pour tous les clients HTTP non basés sur CRT, le mécanisme Keep-Alive réel dépend du système d’exploitation. Par conséquent, vous devez configurer des valeurs TCP Keep-Alive supplémentaires, telles que le délai d’expiration et le nombre de paquets, via le système d’exploitation. Vous pouvez le faire avec `sysctl` sous Linux ou macOS, ou en utilisant les valeurs de registre sous Windows.

**Example pour activer TCP Keep-Alive sur un client HTTP basé sur Apache**  

```
DynamoDbClient client = DynamoDbClient.builder()
    .httpClientBuilder(ApacheHttpClient.builder().tcpKeepAlive(true))
    .build();
```

**Client HTTP basé sur `URLConnection`**  
Tout client synchrone qui utilise le client HTTP basé sur `URLConnection`, [https://docs.oracle.com/javase/8/docs/api/java/net/HttpURLConnection.html](https://docs.oracle.com/javase/8/docs/api/java/net/HttpURLConnection.html), ne dispose pas d’un [mécanisme](https://docs.oracle.com/javase/8/docs/api/java/net/doc-files/net-properties.html) permettant d’activer le mode keep-alive.

**Example pour activer TCP Keep-Alive sur un client HTTP basé sur Netty**  

```
DynamoDbAsyncClient client = DynamoDbAsyncClient.builder()
    .httpClientBuilder(NettyNioAsyncHttpClient.builder().tcpKeepAlive(true))
    .build();
```

**Example pour activer TCP Keep-Alive sur un AWS client HTTP CRT**  
Avec le client HTTP AWS basé sur CRT, vous pouvez activer le maintien en vie du protocole TCP et contrôler la durée.  

```
DynamoDbClient client = DynamoDbClient.builder()
    .httpClientBuilder(AwsCrtHttpClient.builder()
    .tcpKeepAliveConfiguration(TcpKeepAliveConfiguration.builder()
        .keepAliveInterval(Duration.ofSeconds(50))
        .keepAliveTimeout(Duration.ofSeconds(5))
        .build()))
    .build();
```
Lorsque vous utilisez le client DynamoDB asynchrone, vous pouvez activer TCP Keep-Alive comme indiqué dans le code suivant.  

```
DynamoDbAsyncClient client = DynamoDbAsyncClient.builder()
    .httpClientBuilder(AwsCrtAsyncHttpClient.builder()
    .tcpKeepAliveConfiguration(TcpKeepAliveConfiguration.builder()
        .keepAliveInterval(Duration.ofSeconds(50))
        .keepAliveTimeout(Duration.ofSeconds(5))
        .build()))
    .build();
```

## Gestion des erreurs
<a name="JavaErrorHandling"></a>

En ce qui concerne la gestion des exceptions, il AWS SDK for Java 2.x utilise des exceptions d'exécution (non vérifiées).

L’exception de base, qui couvre toutes les exceptions du kit SDK, est [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html), qui s’étend à partir de l’`RuntimeException` Java non coché. Si vous détectez cela, vous détecterez toutes les exceptions générées par le kit SDK.

`SdkServiceException` possède une sous-classe appelée [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/exception/AwsServiceException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/exception/AwsServiceException.html). Cette sous-classe indique tout problème de communication avec le Service AWS. Il possède une sous-classe appelée [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/DynamoDbException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/DynamoDbException.html), qui indique un problème de communication avec DynamoDB. Si vous détectez ce problème, vous détecterez toutes les exceptions liées à DynamoDB, mais aucune autre exception du kit SDK.

Vous trouverez des [types d’exception](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/DynamoDbException.html) plus spécifiques sous `DynamoDbException`. Certains de ces types d’exception s’appliquent aux opérations du plan de contrôle, telles que [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/TableAlreadyExistsException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/TableAlreadyExistsException.html). D’autres s’appliquent aux opérations du plan de données. Voici un exemple d’exception courante au plan de données :
+ [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ConditionalCheckFailedException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ConditionalCheckFailedException.html) : vous avez spécifié une condition dans la demande, qui a été analysée comme false. Par exemple, il se peut que vous avez essayé d’effectuer une mise à jour conditionnelle sur un élément, mais que la valeur réelle de l’attribut ne corresponde pas à la valeur attendue de la condition. Une demande qui échoue de cette manière ne fait pas l’objet d’une nouvelle tentative.

Dans d’autres situations, aucune exception spécifique n’est définie. Par exemple, lorsque vos demandes font l’objet d’une limitation, les `ProvisionedThroughputExceededException` spécifiques peuvent être générées, tandis que dans d’autres cas, les `DynamoDbException` plus génériques sont générées. Dans les deux cas, vous pouvez déterminer si la limitation est à l’origine de l’exception en vérifiant si `isThrottlingException()` renvoie `true`.

En fonction des besoins de votre application, vous pouvez détecter toute `AwsServiceException` ou instance `DynamoDbException`. Cependant, vous avez souvent besoin d’un comportement différent selon les situations. La logique utilisée pour faire face à un échec de vérification d’état est différente de celle utilisée pour gérer la limitation. Définissez les chemins exceptionnels que vous souhaitez traiter et assurez-vous de tester les chemins alternatifs. Cela vous permet de vous assurer que vous pouvez faire face à tous les scénarios pertinents.

Pour obtenir la liste des erreurs courantes que vous pouvez rencontrer, consultez [Gestion des erreurs avec DynamoDB](Programming.Errors.md). Consultez également [Erreurs courantes](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/CommonErrors.html) dans la *Référence de l’API Amazon DynamoDB*. La référence d’API fournit également les erreurs exactes possibles pour chaque opération d’API, par exemple pour l’opération [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html). Pour en savoir plus sur la gestion des exceptions, consultez [Exception handling for the AWS SDK for Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/handling-exceptions.html) dans le *Guide du développeur du kit AWS SDK for Java 2.x *.

## AWS ID de demande
<a name="JavaRequestID"></a>

Chaque demande inclut un ID de demande, qu’il peut être utile d’extraire si vous utilisez AWS Support pour diagnostiquer un problème. Chaque exception dérivée de `SdkServiceException` dispose d’une méthode [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html#requestId()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html#requestId()) permettant d’extraire l’ID de demande.

## Logging
<a name="JavaLogging"></a>

L’utilisation de la journalisation fournie par le kit SDK peut être utile à la fois pour détecter les messages importants provenant des bibliothèques clientes et à des fins de débogage plus approfondies. Les enregistreurs sont hiérarchiques et le kit SDK utilise `software.amazon.awssdk` comme enregistreur racine. Vous pouvez configurer le niveau avec `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, `ALL` ou `OFF`. Le niveau configuré s’applique à cet enregistreur et à la hiérarchie des enregistreurs.

Pour sa journalisation, il AWS SDK for Java 2.x utilise la façade de journalisation simple pour Java (SLF4J). Cela agit comme une couche d’abstraction autour des autres enregistreurs, et vous pouvez l’utiliser pour connecter l’enregistreur que vous préférez. Pour obtenir des instructions sur le branchement des enregistreurs, consultez le manuel [d'utilisation de SLF4 J.](https://www.slf4j.org/manual.html)

Chaque enregistreur a un comportement particulier. Par défaut, l’enregistreur Log4j 2.x crée un `ConsoleAppender`, qui ajoute les événements du journal à `System.out` et les valeurs par défaut au niveau du journal `ERROR`.

L' SimpleLogger enregistreur inclus dans SLF4 J affiche par défaut `System.err` et par défaut le niveau du `INFO` journal.

Nous vous recommandons de définir le niveau sur `WARN` pour `software.amazon.awssdk` pour tous les déploiements de production afin de récupérer les messages importants provenant des bibliothèques clientes du kit SDK tout en limitant la quantité de sortie.

Si SLF4 je ne trouve pas d'enregistreur compatible sur le chemin de classe (aucune liaison SLF4 J), alors l'implémentation par défaut est [sans opération](https://www.slf4j.org/codes.html#noProviders). Cette implémentation entraîne des messages de journalisation `System.err` expliquant que SLF4 je n'ai pas trouvé d'implémentation d'enregistreur sur le chemin de classe. Pour éviter cette situation, vous devez ajouter une implémentation d’enregistreur. Pour ce faire, vous pouvez ajouter une dépendance dans votre `pom.xml` Apache Maven sur des artefacts, tels que `org.slf4j.slf4j-simple` ou `org.apache.logging.log4j.log4j-slf4j2-imp`.

Pour plus d’informations sur la configuration de la journalisation dans le kit SDK, notamment sur l’ajout de dépendances de journalisation à la configuration de votre application, consultez [Logging with the SDK for Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/logging-slf4j.html) dans le *Guide du développeur du kit AWS SDK pour Java *.

La configuration suivante du fichier `Log4j2.xml` montre comment ajuster le comportement de journalisation si vous utilisez l’enregistreur Apache Log4j 2. Cette configuration définit le niveau de l’enregistreur racine sur `WARN`. Tous les enregistreurs de la hiérarchie héritent de ce niveau de journalisation, y compris l’enregistreur `software.amazon.awssdk`.

Par défaut, la sortie passe à `System.out`. Dans l’exemple suivant, nous remplaçons toujours l’appender Log4j de sortie par défaut pour appliquer un `PatternLayout` Log4j adapté.

**Exemple de fichier de configuration `Log4j2.xml`**  
La configuration suivante enregistre les messages sur la console aux niveaux `ERROR` et `WARN` pour toutes les hiérarchies d’enregistreurs.

```
<Configuration status="WARN">
  <Appenders>
    <Console name="ConsoleAppender" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" />
    </Console>
  </Appenders>

  <Loggers>
    <Root level="WARN">
      <AppenderRef ref="ConsoleAppender"/>
    </Root>
  </Loggers>
</Configuration>
```

### AWS journalisation de l'ID de demande
<a name="JavaReqIDLogging"></a>

En cas de problème, vous pouvez trouver une demande IDs dans certaines exceptions. Toutefois, si vous souhaitez que la demande IDs concerne des demandes qui ne génèrent pas d'exceptions, vous pouvez utiliser la journalisation.

L'`software.amazon.awssdk.request`enregistreur produit la demande IDs au `DEBUG` niveau. L’exemple suivant étend l’[configuration example](#Log4j2ConfigEg) précédent pour maintenir le niveau d’enregistreur racine sur `ERROR`, sur `software.amazon.awssdk` au niveau `WARN`, et sur `software.amazon.awssdk.request` au niveau `DEBUG`. La définition de ces niveaux permet de récupérer la demande IDs et d'autres détails liés à la demande, tels que le point de terminaison et le code d'état.

```
<Configuration status="WARN">
  <Appenders>
    <Console name="ConsoleAppender" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" />
    </Console>
  </Appenders>

  <Loggers>
    <Root level="ERROR">
      <AppenderRef ref="ConsoleAppender"/>
    </Root>
    <Logger name="software.amazon.awssdk" level="WARN" />
    <Logger name="software.amazon.awssdk.request" level="DEBUG" />
  </Loggers>
</Configuration>
```

Voici un exemple de la sortie du journal:

```
2022-09-23 16:02:08 [main] DEBUG software.amazon.awssdk.request:85 - Sending Request: DefaultSdkHttpFullRequest(httpMethod=POST, protocol=https, host=dynamodb.us-east-1.amazonaws.com, encodedPath=/, headers=[amz-sdk-invocation-id, Content-Length, Content-Type, User-Agent, X-Amz-Target], queryParameters=[])
 2022-09-23 16:02:08 [main] DEBUG software.amazon.awssdk.request:85 - Received successful response: 200, Request ID: QS9DUMME2NHEDH8TGT9N5V53OJVV4KQNSO5AEMVJF66Q9ASUAAJG, Extended Request ID: not available
```

## Pagination
<a name="JavaPagination"></a>

Certaines demandes, telles que [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html) et [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html), limitent la taille des données renvoyées lors d’une seule demande et nécessitent que vous fassiez des demandes répétées pour extraire les pages suivantes.

Vous pouvez contrôler le nombre maximum d’éléments à lire pour chaque page à l’aide du paramètre `Limit`. Par exemple, vous pouvez utiliser le paramètre `Limit` pour récupérer uniquement les 10 derniers éléments. Cette limite indique le nombre d’éléments à lire dans la table avant qu’un filtrage ne soit appliqué. Si vous voulez exactement 10 éléments après le filtrage, il n’y a aucun moyen de le spécifier. Vous ne pouvez contrôler que le nombre préfiltré et vérifier côté client lorsque vous avez effectivement extrait 10 éléments. Quelle que soit la limite, les réponse ont toujours une taille maximale de 1 Mo.

Une `LastEvaluatedKey` peut être incluse dans la réponse de l’API. Cela indique que la réponse s’est terminée parce qu’elle a atteint une limite de nombre ou de taille. La clé est la dernière clé évaluée pour la réponse. En interagissant directement avec l’API, vous pouvez le extraire cette `LastEvaluatedKey` et la transmettre à un appel de suivi en tant que `ExclusiveStartKey` afin de lire le fragment suivant à partir de ce point de départ. Si aucune `LastEvaluatedKey` n’est renvoyée, cela signifie qu’il n’y a plus d’éléments correspondant à l’appel d’API `Query` ou `Scan`.

L’exemple suivant utilise l’interface de bas niveau pour limiter les éléments à 100 en fonction du paramètre `keyConditionExpression`.

```
QueryRequest.Builder queryRequestBuilder = QueryRequest.builder()
        .expressionAttributeValues(Map.of(
                ":pk_val", AttributeValue.fromS("123"),
                ":sk_val", AttributeValue.fromN("1000")))
        .keyConditionExpression("pk = :pk_val AND sk > :sk_val")
        .limit(100)
        .tableName(TABLE_NAME);

while (true) {
    QueryResponse queryResponse = DYNAMODB_CLIENT.query(queryRequestBuilder.build());

    queryResponse.items().forEach(item -> {
        LOGGER.info("item PK: [" + item.get("pk") + "] and SK: [" + item.get("sk") + "]");
    });

    if (!queryResponse.hasLastEvaluatedKey()) {
        break;
    }
    queryRequestBuilder.exclusiveStartKey(queryResponse.lastEvaluatedKey());
}
```

Ils AWS SDK for Java 2.x peuvent simplifier cette interaction avec DynamoDB en fournissant des méthodes de pagination automatique qui effectuent plusieurs appels de service pour obtenir automatiquement les pages de résultats suivantes pour vous. Cela simplifie le code, mais vous prive d’un certain contrôle de l’utilisation des ressources que vous pourriez conserver en lisant les pages manuellement.

En utilisant les méthodes `Iterable` disponibles dans le client DynamoDB, telles que [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html#queryPaginator(software.amazon.awssdk.services.dynamodb.model.QueryRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html#queryPaginator(software.amazon.awssdk.services.dynamodb.model.QueryRequest)) et [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html#scanPaginator(software.amazon.awssdk.services.dynamodb.model.ScanRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html#scanPaginator(software.amazon.awssdk.services.dynamodb.model.ScanRequest)), le kit SDK prend en charge la pagination. Le type de retour de ces méthodes est un itérable personnalisé que vous pouvez utiliser pour itérer sur toutes les pages. Le kit SDK gère les appels de service en interne pour vous. À l’aide de l’API Java Stream, vous pouvez gérer le résultat de `QueryPaginator` comme illustré dans l’exemple suivant.

```
QueryPublisher queryPublisher =
    DYNAMODB_CLIENT.queryPaginator(QueryRequest.builder()
        .expressionAttributeValues(Map.of(
            ":pk_val", AttributeValue.fromS("123"),
            ":sk_val", AttributeValue.fromN("1000")))
        .keyConditionExpression("pk = :pk_val AND sk > :sk_val")
        .limit(100)
        .tableName("YourTableName")
        .build());

queryPublisher.items().subscribe(item ->
    System.out.println(item.get("itemData"))).join();
```

## Annotations de classes de données
<a name="JavaDataClassAnnotation"></a>

Le kit SDK Java fournit plusieurs annotations que vous pouvez ajouter aux attributs de la classe de données. Ces annotations influencent la manière dont le kit SDK interagit avec les attributs. En ajoutant une annotation, vous pouvez faire en sorte qu’un attribut se comporte comme un compteur atomique implicite, conserver une valeur d’horodatage générée automatiquement ou suivre le numéro de version d’un article. Pour plus d’informations, consultez [Annotations de classes de données](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-anno-index.html).

# Gestion des erreurs avec DynamoDB
<a name="Programming.Errors"></a>

 Cette section décrit les erreurs d’exécution et la façon de les traiter. Elle décrit également les messages d’erreur et les codes spécifiques d’Amazon DynamoDB. Pour obtenir la liste des erreurs courantes qui s'appliquent à tous les AWS services, voir [Gestion des accès](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/CommonErrors.html)

**Topics**
+ [Composants erreur](#Programming.Errors.Components)
+ [Erreurs transactionnelles](#Programming.Errors.TransactionalErrors)
+ [Codes et messages d’erreur](#Programming.Errors.MessagesAndCodes)
+ [Gestion des erreurs dans votre application](#Programming.Errors.Handling)
+ [Nouvelles tentatives après erreur et backoff exponentiel](#Programming.Errors.RetryAndBackoff)
+ [Opérations par lot et gestion des erreurs](#Programming.Errors.BatchOperations)

## Composants erreur
<a name="Programming.Errors.Components"></a>

Quand votre programme envoie une demande, DynamoDB tente de la traiter. Si la demande aboutit, DynamoDB renvoie un code d’état HTTP de succès (`200 OK`), ainsi que les résultats de l’opération demandée.

Si la demande échoue, DynamoDB renvoie une erreur. Chaque erreur possède trois composants : 
+ Un code d’état HTTP (`400`, par exemple).
+ Un nom d’exception (`ResourceNotFoundException`, par exemple).
+ Un message d’erreur (`Requested resource not found: Table: tablename not found`, par exemple).

 AWS SDKs Prenez soin de propager les erreurs dans votre application afin que vous puissiez prendre les mesures appropriées. Par exemple, dans un programme Java, vous pouvez écrire une logique `try-catch` de façon à gérer un `ResourceNotFoundException`.

Si vous n'utilisez pas de AWS SDK, vous devez analyser le contenu de la réponse de bas niveau de DynamoDB. Voici un exemple de réponse.

```
HTTP/1.1 400 Bad Request
x-amzn-RequestId: LDM6CJP8RMQ1FHKSC1RBVJFPNVV4KQNSO5AEMF66Q9ASUAAJG
Content-Type: application/x-amz-json-1.0
Content-Length: 240
Date: Thu, 15 Mar 2012 23:56:23 GMT

{"__type":"com.amazonaws.dynamodb.v20120810#ResourceNotFoundException",
"message":"Requested resource not found: Table: tablename not found"}
```

## Erreurs transactionnelles
<a name="Programming.Errors.TransactionalErrors"></a>

Pour plus d’informations sur les erreurs transactionnelles, veuillez consulter [Gestion des conflits de transactions dans DynamoDB](transaction-apis.md#transaction-conflict-handling)

## Codes et messages d’erreur
<a name="Programming.Errors.MessagesAndCodes"></a>

Voici la liste des exceptions renvoyées par DynamoDB, regroupées par code d’état HTTP. Si *OK to retry?* a pour réponse *Yes*, vous pouvez soumettre à nouveau la même demande. Si *OK to retry?* a pour réponse *No*, vous devez résoudre le problème côté client avant de soumettre une nouvelle demande.

### Code d’état HTTP 400
<a name="Programming.Errors.MessagesAndCodes.http400"></a>

Un code d’état HTTP `400` indique un problème avec votre demande, tel qu’un échec d’authentification, l’absence de paramètres requis ou le dépassement du débit provisionné d’une table. Vous devez corriger le problème dans votre application avant de soumettre à nouveau la demande.

**AccessDeniedException **  
Message : *Accès refusé.*  
Le client n’a pas signé correctement la demande. Si vous utilisez un kit AWS SDK, les demandes sont signées automatiquement ; sinon, accédez au [Processus de signature Signature Version 4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) dans le *Références générales AWS*.  
OK pour réessayer ? Non

**ConditionalCheckFailedException**  
Message : *Échec de la demande conditionnelle. *  
Vous avez spécifié une condition qui a été analysée comme false. Par exemple, il se peut que vous avez essayé d’effectuer une mise à jour conditionnelle sur un élément, mais que la valeur réelle de l’attribut ne corresponde pas à la valeur attendue de la condition.  
OK pour réessayer ? Non

**IncompleteSignatureException**  
Message : *La signature de la demande n’est pas conforme aux normes AWS .*   
La signature de la demande ne comprenait pas tous les composants requis. Si vous utilisez un AWS SDK, les demandes sont signées automatiquement ; sinon, passez au [processus de signature Signature version 4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) dans le *Références générales AWS*.  
OK pour réessayer ? Non

**ItemCollectionSizeLimitExceededException**  
Message : *Dépassement de taille de la collection.*  
Pour une table avec un index secondaire local, un groupe d’éléments avec la même valeur de clé de partition a dépassé la limite de taille maximum de 10 Go. Pour plus d’informations sur les collections d’éléments, consultez [Collections d’articles dans les index secondaires locaux](LSI.md#LSI.ItemCollections).  
OK pour réessayer ? Oui

**LimitExceededException**  
Message : *Beaucoup trop d’opérations pour un abonné donné.*  
Il y a beaucoup trop d’opérations de contrôle simultanées. Le nombre cumulé de tables et d’index à l’état `CREATING`, `DELETING` ou `UPDATING` ne peut pas dépasser 500.  
OK pour réessayer ? Oui

**MissingAuthenticationTokenException**  
Message : *La demande doit comporter un ID de clé d’accès AWS valide (inscrit).*  
La demande n’incluait pas l’en-tête d’autorisation obligatoire ou n’était pas correctement formée. Consultez [API de bas niveau de DynamoDB](Programming.LowLevelAPI.md).  
OK pour réessayer ? Non

**ProvisionedThroughputExceededException**  
Message : *Vous avez dépassé le débit provisionné autorisé maximal pour une table ou pour un ou plusieurs index secondaires globaux. [Pour consulter les indicateurs de performance relatifs au débit provisionné par rapport au débit consommé, ouvrez la console Amazon. CloudWatch](https://console.aws.amazon.com/cloudwatch/home)*  
L’erreur inclut une liste de champs `ThrottlingReason` fournissant un contexte spécifique expliquant pourquoi la limitation s’est produite, en fonction du format `ResourceType+OperationType+LimitType` (par exemple, `TableReadProvisionedThroughputExceeded`) et de l’ARN de la ressource affectée. Cela vous permet d’identifier la ressource limitée (table ou index), le type d’opération qui a déclenché la limitation (lecture ou écriture) et la limite spécifique qui a été dépassée (dans ce cas, la capacité allouée). Pour plus d’informations sur le diagnostic et la résolution des problèmes de limitation, consultez [Diagnostic des problèmes de limitation](throttling-diagnosing-workflow.md).  
Exemple : votre taux de demandes est trop élevé. AWS SDKs Pour DynamoDB, réessayez automatiquement les demandes qui reçoivent cette exception. Votre demande finit par aboutir, à moins que la file d’attente des nouvelles tentatives soit trop grande pour être terminée. Réduisez la fréquence des demandes avec [Nouvelles tentatives après erreur et backoff exponentiel](#Programming.Errors.RetryAndBackoff).   
OK pour réessayer ? Oui

**ReplicatedWriteConflictException**  
Message : *Un ou plusieurs éléments de cette demande sont modifiés par une demande dans une autre région.*  
Exemple : Une opération d’écriture a été demandée pour un élément d’une table globale multirégionale fortement cohérente (MRSC) qui est actuellement modifiée par une demande dans une autre région.   
OK pour réessayer ? Oui

**RequestLimitExceeded**  
Message : *Throughput exceeds the current throughput limit for your account (le débit dépasse la limite de débit actuelle de votre compte). Pour demander une augmentation de limite, contactez le AWS Support à l'adresse [https://aws.amazon.com/support.](https://aws.amazon.com/support)*  
L’erreur inclut une liste de champs `ThrottlingReason` fournissant un contexte spécifique expliquant pourquoi la limitation s’est produite, en fonction du format `ResourceType+OperationType+LimitType` (par exemple, `TableWriteAccountLimitExceeded` ou `IndexReadAccountLimitExceeded`) et de l’ARN de la ressource affectée. Cela vous permet d’identifier quelle ressource est limitée (table ou index), quel type d’opération a déclenché la limitation (lecture ou écriture) et si vous avez dépassé les quotas de service au niveau du compte. Pour plus d’informations sur le diagnostic et la résolution des problèmes de limitation, consultez [Diagnostic des problèmes de limitation](throttling-diagnosing-workflow.md).   
Exemple : Le taux de demandes à la demande dépasse le débit autorisé du compte et la table ne peut pas être davantage mise à l’échelle.  
OK pour réessayer ? Oui

**ResourceInUseException**  
Message : *La ressource que vous essayez de modifier est en cours d’utilisation. *  
Exemple : vous avez essayé de recréer une table existante ou de supprimer une table dont l’état est `CREATING`.   
OK pour réessayer ? Non

**ResourceNotFoundException **  
Message : *La ressource demandée est introuvable.*  
Exemple : la table demandée n’existe pas ou se trouve trop tôt dans l’état `CREATING`.  
OK pour réessayer ? Non

**ThrottlingException**  
Message : *Le taux de demandes dépasse le débit autorisé.*  
Cette exception est renvoyée sous forme de AmazonServiceException réponse avec un code d'état THROTTLING\$1EXCEPTION. Cette exception peut être renvoyée si vous effectuez des opérations d’API de [plan de contrôle](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.API.html#HowItWorks.API.ControlPlane) trop rapidement.  
Pour les tables utilisant le mode à la demande, cette exception peut être renvoyée pour toute opération d’API de [plan de données](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.API.html#HowItWorks.API.DataPlane) si votre taux de demandes est trop élevé. Pour en savoir plus sur la mise à l’échelle à la demande, consultez [Débit initial et propriétés de mise à l’échelle](on-demand-capacity-mode.md#on-demand-capacity-mode-initial).   
L’erreur inclut une liste de champs `ThrottlingReason` fournissant un contexte spécifique expliquant pourquoi la limitation s’est produite, en fonction du format `ResourceType+OperationType+LimitType` (par exemple, `TableReadKeyRangeThroughputExceeded` ou `IndexWriteMaxOnDemandThroughputExceeded`) et de l’ARN de la ressource affectée. Ces informations vous permettent d’identifier la ressource limitée (table ou index), le type d’opération qui a déclenché la limitation (lecture ou écriture) et la limite spécifique qui a été dépassée (limites de partition ou débit maximum à la demande). Pour plus d’informations sur le diagnostic et la résolution des problèmes de limitation, consultez [Diagnostic des problèmes de limitation](throttling-diagnosing-workflow.md).  
OK pour réessayer ? Oui

**UnrecognizedClientException**  
Message : *L’ID de clé d’accès ou le jeton de sécurité n’est pas valide.*  
La signature de la demande est incorrecte. La cause la plus probable est un identifiant de clé AWS d'accès ou une clé secrète non valide.  
OK pour réessayer ? Oui

**ValidationException**  
Message : variable selon les erreurs spécifiques rencontrées  
Cette erreur peut se produire pour différentes raisons, telles qu’un paramètre obligatoire absent, une valeur en dehors des limites ou une incompatibilité des données. Le message d’erreur contient des détails sur la partie spécifique de la demande qui a provoqué l’erreur.  
OK pour réessayer ? Non

### Code d’état HTTP 5xx
<a name="Programming.Errors.MessagesAndCodes.http5xx"></a>

Un code d’état HTTP `5xx` indique un problème qui doit être résolu par AWS. Il peut s’agir d’une erreur temporaire, auquel cas vous pouvez retenter votre demande jusqu’à ce qu’elle aboutisse. Sinon, accédez à l’[AWS Service Health Dashboard](https://status.aws.amazon.com/) pour voir si le service rencontre des problèmes opérationnels.

Pour plus d’informations, consultez l’article [Comment résoudre les erreurs HTTP 5xx dans Amazon DynamoDB ?](https://aws.amazon.com/premiumsupport/knowledge-center/dynamodb-http-5xx-errors/)

**InternalServerError (HTTP 500)**  
DynamoDB n’a pas pu traiter votre demande.  
OK pour réessayer ? Oui  
Vous pouvez rencontrer des erreurs de serveur internes lorsque vous travaillez avec des éléments. Celles-ci sont attendues pendant la durée de vie d’une table. Toute demande en échec peut être relancée immédiatement.  
Lorsque vous recevez un code d’état 500 lors d’une opération d’écriture, l’opération peut avoir réussi ou échoué. Si l’opération d’écriture est une demande `TransactWriteItem`, il convient de réessayer l’opération. Si l'opération d'écriture est une demande d'écriture à élément unique`PutItem`, telle que`UpdateItem`, ou`DeleteItem`, alors votre application doit lire l'état de l'élément avant de recommencer l'opération, and/or [Exemple de commande CLI d’expression de condition DynamoDB](Expressions.ConditionExpressions.md) afin de s'assurer que l'élément reste dans un état correct après une nouvelle tentative, que l'opération précédente ait réussi ou échoué. Si l’idempotence est une exigence pour l’opération d’écriture, veuillez utiliser [`TransactWriteItem`](transaction-apis.md#transaction-apis-txwriteitems), qui prend en charge les demandes idempotentes en spécifiant automatiquement un `ClientRequestToken` pour désambiguïser plusieurs tentatives d’exécution de la même action.

**ServiceUnavailable (HTTP 503)**  
DynamoDB est actuellement indisponible. (Il doit s’agir d’un état temporaire.)  
OK pour réessayer ? Oui

## Gestion des erreurs dans votre application
<a name="Programming.Errors.Handling"></a>

Pour que votre application fonctionne correctement, vous devez ajouter une logique destinée à récupérer les erreurs et à y répondre. Les approches classiques incluent l’utilisation de blocs `try-catch` ou d’instructions `if-then`.

Ils AWS SDKs effectuent leurs propres tentatives et vérifient les erreurs. Si vous rencontrez une erreur lors de l'utilisation de l'un d'entre eux AWS SDKs, le code d'erreur et sa description peuvent vous aider à résoudre le problème.

Vous devez également voir un `Request ID` dans la réponse. Cela `Request ID` peut être utile si vous devez contacter le AWS Support pour diagnostiquer un problème.

## Nouvelles tentatives après erreur et backoff exponentiel
<a name="Programming.Errors.RetryAndBackoff"></a>

Un grand nombre de composants d’un réseau, tels que serveurs DNS, commutateurs, équilibreurs de charge ou autres, peuvent générer des erreurs à n’importe quel moment de la vie d’une requête donnée. La technique habituelle pour traiter ces réponses erronées dans un environnement réseau consiste à implémenter les nouvelles tentatives dans l’application cliente. Cette technique augmente la fiabilité de l’application.

Chaque AWS SDK implémente automatiquement une logique de nouvelle tentative. Vous pouvez modifier les paramètres de nouvelle tentative en fonction de vos besoins. Par exemple, imaginons une application Java nécessitant une politique d’interruption immédiate, sans autorisation de nouvelle tentative en cas d’erreur. Avec le AWS SDK pour Java, vous pouvez utiliser la `ClientConfiguration` classe et fournir une `maxErrorRetry` valeur de `0` pour désactiver les nouvelles tentatives. Pour plus d'informations, consultez la documentation du AWS SDK correspondant à votre langage de programmation.

Si vous n'utilisez pas de AWS SDK, vous devez réessayer les demandes d'origine qui ont généré des erreurs de serveur (5xx). Cependant, les erreurs client (4xx, autres qu’une exception `ThrottlingException` ou `ProvisionedThroughputExceededException`) indiquent que vous avez besoin de réviser la demande elle-même pour résoudre le problème avant de recommencer. Pour obtenir des recommandations détaillées concernant des scénarios de limitation spécifiques, reportez-vous à la section de résolution des problèmes de limitation de [DynamoDB](TroubleshootingThrottling.md).

Outre de simples tentatives, chaque AWS SDK implémente un algorithme de ralentissement exponentiel pour un meilleur contrôle du flux. Le concept sous-jacent vise à utiliser des temps d’attente progressivement plus longs entre les tentatives en cas de réponses d’erreur consécutives. Par exemple, jusqu’à 50 millisecondes avant la première nouvelle tentative, jusqu’à 100 millisecondes avant la deuxième, jusqu’à 200 millisecondes avant la troisième, et ainsi de suite. Cependant, après une minute, si la demande a échoué, le problème peut être que la taille de la demande entraîne un dépassement du débit provisionné, et ne pas être lié au taux de demandes. Définir le nombre maximal de nouvelles tentatives pour qu’elles s’arrêtent au bout d’une minute environ. Si la demande n’aboutit pas, examinez vos options de débit provisionné. 

**Note**  
Ils AWS SDKs implémentent une logique de nouvelle tentative automatique et un ralentissement exponentiel.

La plupart des algorithmes de backoff exponentiel utilisent l’instabilité (retard aléatoire) pour éviter les conflits successifs. Comme vous ne cherchez pas à éviter de tels conflits dans ces cas-là, vous n’avez pas besoin d’utiliser ce nombre aléatoire. Cependant, si vous utilisez les clients simultanés, l’instabilité peut aider à ce que vos demandes réussissent plus rapidement. Pour plus d’informations, consultez le billet de blog sur [Exponential backoff and jitter](http://www.awsarchitectureblog.com/2015/03/backoff.html).

## Opérations par lot et gestion des erreurs
<a name="Programming.Errors.BatchOperations"></a>

L’API de bas niveau DynamoDB prend en charge les opérations par lot pour les lectures et les écritures. `BatchGetItem` lit les éléments d’une ou de plusieurs tables, et `BatchWriteItem` insère ou supprime des éléments dans une ou plusieurs tables. Ces opérations par lot sont implémentées sous la forme d’encapsuleurs autour des opérations DynamoDB autres que par lot. En d’autres termes, `BatchGetItem` appelle `GetItem` une fois pour chaque élément du lot. De même, `BatchWriteItem` invoque `DeleteItem` ou `PutItem`, le cas échéant, pour chaque élément du lot.

Une opération par lot peut supporter la défaillance de requêtes individuelles dans le lot. Par exemple, imaginons une demande `BatchGetItem` de lecture de cinq éléments. Même si certaines demandes `GetItem` sous-jacentes échouent, il ne s’ensuit pas que l’ensemble de l’opération `BatchGetItem` échoue. Cependant, si les cinq opérations de lecture échouent, alors `BatchGetItem` échoue dans son intégralité.

Les opérations par lot renvoient des informations sur les demandes individuelles qui échouent pour vous permettre de diagnostiquer le problème et de réessayer l’opération. Pour `BatchGetItem`, les tables et les clés primaires en question sont retournées dans la valeur `UnprocessedKeys` de la réponse. Pour `BatchWriteItem`, les informations similaires sont retournées dans `UnprocessedItems`. 

La cause la plus probable d’un échec en lecture ou en écriture est la *limitation*. Pour `BatchGetItem`, une ou plusieurs tables de la demande par lot n’ont pas une capacité en lecture suffisamment provisionnée pour prendre en charge l’opération. Pour `BatchWriteItem`, une ou plusieurs des tables n’ont pas une capacité en écriture suffisamment provisionnée.

Si DynamoDB renvoie des éléments non traités, vous devez relancer l’opération par lot sur ces éléments. Cependant, *nous vous recommandons vivement d’utiliser un algorithme d’interruption exponentielle*. Si vous recommencez immédiatement l’opération par lot, les demandes en lecture ou en écriture sous-jacentes peuvent continuer à échouer en raison de la limitation sur les tables individuelles. Si vous retardez l’opération par lot à l’aide d’une interruption exponentielle, il est très vraisemblable que les demandes du lot réussiront.

**Note**  
Certains AWS SDKs proposent des clients de niveau supérieur qui gèrent automatiquement les nouvelles tentatives d'articles non traités. Vous n'avez donc pas besoin d'implémenter vous-même cette logique de nouvelle tentative. Par exemple :  
**Java** [— Le client [DynamoDB amélioré](DynamoDBEnhanced.md) dans la version v2 et le DBMapper Dynamo dans AWS SDK pour Java la version v1 réessayent automatiquement les éléments non traités lors des opérations par lots.](DynamoDBMapper.md)
**Python** — La ressource de table boto3 `batch_writer` gère implicitement les tentatives d'éléments non traités pour les opérations d'écriture par lots. Pour de plus amples informations, veuillez consulter [Utilisation de la ressource de table batch\$1writer](programming-with-python.md#programming-with-python-batch-writer).
Si vous utilisez un client de bas niveau ou un SDK qui ne fournit pas ce comportement, vous devez implémenter vous-même la logique de nouvelle tentative, comme décrit ci-dessus.

# Utilisation de DynamoDB avec un SDK AWS
<a name="sdk-general-information-section"></a>

AWS des kits de développement logiciel (SDKs) sont disponibles pour de nombreux langages de programmation courants. Chaque kit SDK fournit une API, des exemples de code et de la documentation qui facilitent la création d’applications par les développeurs dans leur langage préféré.


| Documentation SDK | Exemples de code | 
| --- | --- | 
| [AWS SDK pour C\$1\$1](https://docs.aws.amazon.com/sdk-for-cpp) | [AWS SDK pour C\$1\$1 exemples de code](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp) | 
| [AWS CLI](https://docs.aws.amazon.com/cli) | [AWS CLI exemples de code](https://docs.aws.amazon.com/code-library/latest/ug/cli_2_code_examples.html) | 
| [AWS SDK pour Go](https://docs.aws.amazon.com/sdk-for-go) | [AWS SDK pour Go exemples de code](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/gov2) | 
| [AWS SDK pour Java](https://docs.aws.amazon.com/sdk-for-java) | [AWS SDK pour Java exemples de code](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2) | 
| [AWS SDK pour JavaScript](https://docs.aws.amazon.com/sdk-for-javascript) | [AWS SDK pour JavaScript exemples de code](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javascriptv3) | 
| [AWS SDK pour Kotlin](https://docs.aws.amazon.com/sdk-for-kotlin) | [AWS SDK pour Kotlin exemples de code](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin) | 
| [AWS SDK pour .NET](https://docs.aws.amazon.com/sdk-for-net) | [AWS SDK pour .NET exemples de code](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3) | 
| [AWS SDK pour PHP](https://docs.aws.amazon.com/sdk-for-php) | [AWS SDK pour PHP exemples de code](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/php) | 
| [Outils AWS pour PowerShell](https://docs.aws.amazon.com/powershell) | [Outils AWS pour PowerShell exemples de code](https://docs.aws.amazon.com/code-library/latest/ug/powershell_5_code_examples.html) | 
| [AWS SDK pour Python (Boto3)](https://docs.aws.amazon.com/pythonsdk) | [AWS SDK pour Python (Boto3) exemples de code](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/python) | 
| [AWS SDK pour Ruby](https://docs.aws.amazon.com/sdk-for-ruby) | [AWS SDK pour Ruby exemples de code](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/ruby) | 
| [AWS SDK pour Rust](https://docs.aws.amazon.com/sdk-for-rust) | [AWS SDK pour Rust exemples de code](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/rustv1) | 
| [AWS SDK pour SAP ABAP](https://docs.aws.amazon.com/sdk-for-sapabap) | [AWS SDK pour SAP ABAP exemples de code](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/sap-abap) | 
| [AWS SDK pour Swift](https://docs.aws.amazon.com/sdk-for-swift) | [AWS SDK pour Swift exemples de code](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/swift) | 

Pour accéder à des exemples spécifiques à DynamoDB, consultez [Exemples de code pour DynamoDB utilisant AWS SDKs](service_code_examples.md).

**Exemple de disponibilité**  
Vous n’avez pas trouvé ce dont vous avez besoin ? Demandez un exemple de code en utilisant le lien **Provide feedback (Fournir un commentaire)** en bas de cette page.