> ## Documentation Index
> Fetch the complete documentation index at: https://translations.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Gardez une base de données externe ou un entrepôt de données synchronisé avec les changements d’identité dans Auth0 à l’aide d’Event Streams.

# Synchroniser les données entre les systèmes

Avec Event Streams, vous pouvez conserver une copie de vos données d’identité d’Auth0 dans un système externe, comme une base de données relationnelle, un entrepôt de données ou un index de recherche. Lorsqu’un profil utilisateur est créé, mis à jour ou supprimé dans Auth0, un événement est envoyé à la destination de votre stream afin que votre système externe puisse apporter la même modification.

<div id="why-synchronize-identity-data">
  ## Pourquoi synchroniser les données d’identité
</div>

Conserver une copie locale des données d’identité est utile lorsque vous devez :

* Exécuter des analyses, produire des rapports ou effectuer des requêtes de conformité sans appeler la Management API.
* Offrir des fonctions de recherche qui nécessitent des recherches à faible latence dans les attributs des utilisateurs.
* Alimenter des pipelines de données qui croisent des enregistrements d’identité avec d’autres données d’affaires.
* Conserver une sauvegarde de l’état du profil utilisateur pour la reprise après sinistre.

<div id="how-it-works">
  ## Fonctionnement
</div>

1. Auth0 publie un événement chaque fois qu’un profil utilisateur est modifié.
2. Votre Event Stream transmet cet événement à une destination (webhook, AWS EventBridge ou Auth0 Action).
3. Votre gestionnaire examine le type d’événement et applique l’opération d’écriture correspondante dans le système externe.

Les types d’événements suivants sont pertinents pour la synchronisation des données :

| Type d’événement | Quand il se déclenche                              |
| ---------------- | -------------------------------------------------- |
| `user.created`   | Un nouveau profil utilisateur est créé dans Auth0. |
| `user.updated`   | Un profil utilisateur existant est modifié.        |
| `user.deleted`   | Un profil utilisateur est supprimé d’Auth0.        |

<div id="prerequisites">
  ## Prérequis
</div>

Avant de commencer, assurez-vous d’avoir :

* Un tenant Auth0 où Events est activé. Pour en savoir plus sur la disponibilité selon le forfait, consultez [Créer un Event Stream](/docs/fr-ca/customize/events/create-an-event-stream).
* Un Event Stream actif abonné à `user.created`, `user.updated` et `user.deleted`. Pour en savoir plus, consultez [Créer un Event Stream](/docs/fr-ca/customize/events/create-an-event-stream).
* Un stockage de données externe (par exemple, PostgreSQL, MySQL ou un entrepôt de données) dans lequel votre handler peut écrire.

<div id="implement-data-synchronization">
  ## Synchronisation des données avec Implement
</div>

Les sections ci-dessous montrent comment traiter chaque type d’événement. Les fonctions handler sont les mêmes, quelle que soit la destination de votre Event Stream. La section [Acheminer les événements par type](#route-events-by-type) montre comment acheminer les événements pour les destinations webhook et Auth0 Action.

<div id="handle-usercreated">
  ### Traiter user.created
</div>

Lorsqu’Auth0 publie un événement `user.created`, insérez un nouvel enregistrement dans votre base de données.

```javascript wrap lines theme={null}
async function handleUserCreated(user, time) {
    const { user_id, email, name, nickname, created_at, updated_at } = user;

    const query = `
        INSERT INTO users (user_id, email, name, nickname, created_at, updated_at, last_event_processed)
        VALUES ($1, $2, $3, $4, $5, $6, $7)
    `;
    const values = [user_id, email, name, nickname, created_at, updated_at, time];

    await pool.query(query, values);
}
```

<div id="handle-userupdated">
  ### Traiter user.updated
</div>

Lorsque Auth0 émet un événement `user.updated`, mettez à jour la ligne correspondante. Comparez l’horodatage de l’événement avec la colonne `last_event_processed` pour éviter d’écraser des données obsolètes.

```javascript wrap lines theme={null}
async function handleUserUpdated(user, time) {
    const { user_id, email, name, nickname, updated_at } = user;

    const query = `
        UPDATE users
        SET email = $1, name = $2, nickname = $3, updated_at = $4, last_event_processed = $5
        WHERE user_id = $6 AND last_event_processed < $5
    `;
    const values = [email, name, nickname, updated_at, time, user_id];

    await pool.query(query, values);
}
```

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Les Events peuvent ne pas arriver dans l’ordre. Comparez toujours les horodatages avant d’appliquer les mises à jour afin d’éviter que des données périmées n’écrasent des enregistrements plus récents. Pour en savoir plus, consultez [Events Best Practices](/docs/fr-ca/customize/events/events-best-practices).
</Callout>

<div id="handle-userdeleted">
  ### Traiter user.deleted
</div>

Quand Auth0 publie un événement `user.deleted`, supprimez la ligne correspondante ou effectuez une suppression logique.

```javascript wrap lines theme={null}
async function handleUserDeleted(user) {
    const { user_id } = user;

    const query = `DELETE FROM users WHERE user_id = $1`;

    await pool.query(query, [user_id]);
}
```

<div id="route-events-by-type">
  ### Acheminer les événements par type
</div>

Utilisez un routeur principal pour acheminer chaque événement vers le handler approprié. Les exemples ci-dessous montrent comment acheminer les événements vers des destinations webhook et Auth0 Action.

<Tabs>
  <Tab title="Webhook">
    ```javascript wrap lines theme={null}
    app.post("/webhook", async (req, res) => {
        const { type, time, data } = req.body;
        const user = data.object;

        try {
            switch (type) {
                case "user.created":
                    await handleUserCreated(user, time);
                    break;
                case "user.updated":
                    await handleUserUpdated(user, time);
                    break;
                case "user.deleted":
                    await handleUserDeleted(user);
                    break;
                default:
                    console.log(`Unhandled event type: ${type}`);
            }

            res.sendStatus(204);
        } catch (err) {
            console.error("Error processing event:", err);
            res.status(500).json({ error: "Internal server error" });
        }
    });
    ```

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      Retournez une réponse HTTP `2XX` le plus rapidement possible. Si votre handler doit effectuer des opérations lentes, placez l’événement dans une file d’attente interne et traitez-le de façon asynchrone. Pour en savoir plus, consultez [Events Best Practices](/docs/fr-ca/customize/events/events-best-practices).
    </Callout>
  </Tab>

  <Tab title="Auth0 Action">
    ```javascript wrap lines theme={null}
    exports.onExecuteEventStream = async (event, api) => {
        const eventType = event.message.type;
        const user = event.message.data.object;
        const time = event.message.time;

        switch (eventType) {
            case "user.created":
                await handleUserCreated(user, time);
                break;
            case "user.updated":
                await handleUserUpdated(user, time);
                break;
            case "user.deleted":
                await handleUserDeleted(user);
                break;
            default:
                console.log(`Unhandled event type: ${eventType}`);
        }
    };
    ```
  </Tab>
</Tabs>

<div id="guard-against-duplicates-and-ordering-issues">
  ## Se prémunir contre les doublons et les problèmes d’ordre
</div>

Event Streams offrent une livraison au moins une fois, ce qui signifie que votre handler peut recevoir le même événement plus d’une fois. Pour gérer cela de façon sécuritaire :

* **Faites le suivi des ID d’événement.** Stockez l’`id` de chaque événement traité et ignorez tout événement que vous avez déjà traité.
* **Comparez les horodatages.** Chaque payload d’événement comprend les champs `created_at` et `updated_at` dans `data.object`. Utilisez ces champs pour déterminer si un événement entrant est plus récent que ce que votre système a déjà enregistré.
* **Utilisez des écritures idempotentes.** Structurez vos opérations de base de données de sorte que l’application du même événement deux fois produise le même résultat. Par exemple, utilisez `INSERT ... ON CONFLICT DO UPDATE` dans PostgreSQL.

```sql wrap lines theme={null}
INSERT INTO users (user_id, email, name, nickname, created_at, updated_at, last_event_processed)
VALUES ($1, $2, $3, $4, $5, $6, $7)
ON CONFLICT (user_id) DO UPDATE
SET email = EXCLUDED.email,
    name = EXCLUDED.name,
    nickname = EXCLUDED.nickname,
    updated_at = EXCLUDED.updated_at,
    last_event_processed = EXCLUDED.last_event_processed
WHERE users.last_event_processed < EXCLUDED.last_event_processed;
```

<div id="verify-synchronization">
  ## Vérifiez la synchronisation
</div>

Après avoir déployé votre handler, créez un utilisateur test dans Auth0 et confirmez ce qui suit :

1. Un nouvel enregistrement apparaît dans votre base de données externe avec les bonnes données de profil.
2. Mettez à jour le nom ou l’adresse courriel de l’utilisateur dans Auth0. Confirmez que l’enregistrement dans la base de données reflète ce changement.
3. Supprimez l’utilisateur dans Auth0. Confirmez que l’enregistrement est supprimé (ou marqué comme supprimé) dans votre base de données.

Pour en savoir plus sur la mise à l’essai des Event Streams, consultez [Tests des événements, observabilité et reprise après échec](/docs/fr-ca/customize/events/event-testing-observability-and-failure-recovery).

<div id="learn-more">
  ## En savoir plus
</div>

* [Catalogue des événements](/docs/fr-ca/events)
* [Créer un Event Stream](/docs/fr-ca/customize/events/create-an-event-stream)
* [Events Best Practices](/docs/fr-ca/customize/events/events-best-practices)
