Étendre Datastore avec Cloud Functions (2nd gen)

Avec les fonctions Cloud Run et Eventarc, vous pouvez déployer du code gérer les événements déclenchés par des modifications dans votre base de données Firestore en mode Datastore. Ce vous permet d'ajouter des fonctionnalités côté serveur sans exécuter vos propres serveurs.

Déclencheurs du mode Datastore

Eventarc accepte l'événement Firestore en mode Datastore suivant qui vous permettent de créer des gestionnaires de fonctions Cloud Run (2e génération) liés à Événements Firestore en mode Datastore:

Event Type Déclencheur
google.cloud.datastore.entity.v1.created Déclenché lorsqu'une entité est écrite pour la première fois.
google.cloud.datastore.entity.v1.updated Déclenché lorsqu'une entité existe déjà et qu'une valeur est modifiée.
google.cloud.datastore.entity.v1.deleted Déclenché lorsqu'une entité est supprimée.
google.cloud.datastore.entity.v1.written Déclenché lorsque created, updated ou deleted est déclenché.
google.cloud.datastore.entity.v1.created.withAuthContext Identique à created, mais ajoute des informations d'authentification.
google.cloud.datastore.entity.v1.updated.withAuthContext Identique à updated, mais ajoute des informations d'authentification.
google.cloud.datastore.entity.v1.deleted.withAuthContext Identique à deleted, mais ajoute des informations d'authentification.
google.cloud.datastore.entity.v1.written.withAuthContext Identique à written, mais ajoute des informations d'authentification.

Les déclencheurs d'événements du mode Datastore ne répondent que aux changements d'entités. Mise à jour d'une entité en mode Datastore dans laquelle des données reste inchangé (écriture no-op) ne génère pas d'événement de mise à jour ou d'écriture. Toi ne peuvent pas générer d'événements uniquement pour des propriétés spécifiques.

Inclure le contexte d'authentification dans l'événement

Pour inclure des informations d'authentification supplémentaires concernant l'événement, utilisez un événement avec l'extension withAuthContext. Cette extension permet d'ajouter des informations sur le compte principal qui a déclenché l'événement. Elle ajoute le paramètre les attributs authtype et authid, en plus des informations renvoyées dans l'événement de base. Consultez le Consultez la documentation de référence sur authcontext pour en savoir plus sur les valeurs d'attribut.

Écrire une fonction déclenchée par une entité

Pour écrire une fonction qui répond aux événements Firestore en mode Datastore, préparez-vous à spécifier les éléments suivants lors du déploiement:

  • un type d'événement déclencheur
  • Un filtre d'événement déclencheur pour sélectionner les entités associées à la fonction
  • le code de la fonction à exécuter

Filtres pour les événements déclencheurs

Lorsque vous spécifiez un filtre d'événement, vous pouvez spécifier une entité exacte ou un modèle de chemin d'accès. Utiliser un format de chemin d'accès pour mettre en correspondance plusieurs entités les caractères génériques * ou **.

Par exemple, vous pouvez spécifier une correspondance d'entité exacte pour répondre à des modifications apportées au l'entité suivante:

users/marie

Utilisez des caractères génériques, * ou **, pour répondre aux modifications des entités. qui correspondent à un modèle. Le caractère générique * correspond à un seul segment, et le caractère générique multi-segment ** correspond à zéro, un ou plusieurs segments du modèle.

Pour les correspondances de segment unique (*), vous pouvez également utiliser un groupe de capture nommé, tel que en tant que users/{userId}.

Le tableau suivant illustre les formats de chemin d'accès valides:

Modèle Description
users/* ou users/{userId} Correspond à toutes les entités du genre users. Ne correspond pas au niveau des entités descendantes comme /users/marie/messages/33e2IxYBD9enzS50SJ68
users/** Correspond à toutes les entités de genre users et à toutes les entités descendantes telles que /users/marie/messages/33e2IxYBD9enzS50SJ68

Pour en savoir plus sur les modèles de chemin, consultez Modèles de chemin Eventarc.

Votre déclencheur doit toujours pointer vers une entité, même si vous utilisez un caractère générique. Consultez les exemples suivants :

  • users/{userId=*}/{messages=*} n'est pas valide, car {messages=*} est un ID de genre.

  • users/{userId=*}/{messages}/{messageId=*} est valide, car {messageId=*} pointe toujours vers une entité.

Échappement des caractères

Cette section décrit les situations dans lesquelles vous devez échapper des caractères dans de genre et d'entité. Échapper un caractère permet de filtrer correctement l'événement interpréter l'ID.

  • Si un ID de genre ou d'entité comprend un caractère ~ ou /, vous devez échappez l'ID dans votre filtre d'événement. Pour échapper un ID, utilisez le format __escENCODED_ID__ Remplacez ENCODED_ID par un ID de genre ou d'entité contenant tous les ~ et Les caractères / ont été remplacés par leur ID d'encodage, qui est le suivant:

    • ~ : ~0
    • / : ~1

    Par exemple, l'ID de genre user/profile devient __escusers~1profile__. Une L'exemple de format de chemin d'accès associé à cet ID de genre est __escusers~1profile__/{userId}

  • Si vous utilisez l'ID de genre ou d'entité de . ou .. dans votre filtre d'événement, vous devez échapper l'ID comme suit:

    • . : __esc~2__
    • .. : __esc~2~2__

    Vous ne devez échapper le caractère . que si l'ID est exactement . ou ... Par exemple, l'ID de genre customers.info ne nécessite pas d'échappement.

  • Si votre genre ou ID d'entité est une valeur numérique et non une valeur de chaîne, vous devez échapper l'ID avec __idNUMERIC_VALUE__. Par exemple, le format de chemin d'une entité de genre 111 et d'ID d'entité 222 est __id111__/__id222__.

  • Si vous avez effectué la migration depuis l'ancien Cloud Datastore à Firestore en mode Datastore, votre base de données peut contenir d'anciens ID dans un encodage autre que UTF8. Vous devez échapper ces identifiants avec __bytesBASE64_ENCODING__. Remplacez BASE64_ENCODING par l'encodage en base64 de l'ID. Pour Exemple de format de chemin d'accès Task/{task} avec échappement pour l'ID de genre non UTF8 Task devient __bytesVGFzaw==__/{task}.

Exemples de fonctions

L'exemple suivant montre comment recevoir des événements en mode Datastore. Pour utiliser les données associées à un événement, examinez les value et old_value.

  • value: objet EntityResult qui contient un instantané d'entité post-opération. Ce champ n'est pas renseigné pour les événements de suppression.
  • old_value: objet EntityResult qui contient une entité de pré-opération. instantané. Ce champ n'est renseigné que pour les événements de mise à jour et de suppression.

Java

Pour savoir comment installer et utiliser la bibliothèque cliente pour le mode Datastore, consultez Bibliothèques clientes en mode Datastore. Pour en savoir plus, consultez les API Java du mode Datastore documentation de référence.

Pour vous authentifier auprès du mode Datastore, configurez les identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

import com.google.cloud.functions.CloudEventsFunction;
import com.google.events.cloud.datastore.v1.EntityEventData;
import com.google.protobuf.InvalidProtocolBufferException;
import io.cloudevents.CloudEvent;
import java.util.logging.Logger;

public class Datastore implements CloudEventsFunction {
  private static final Logger logger = Logger.getLogger(Datastore.class.getName());

  @Override
  public void accept(CloudEvent event) throws InvalidProtocolBufferException {
    EntityEventData datastoreEventData = EntityEventData.parseFrom(event.getData().toBytes());

    logger.info("Function triggered by event on: " + event.getSource());
    logger.info("Event type: " + event.getType());

    logger.info("Old value:");
    logger.info(datastoreEventData.getOldValue().toString());

    logger.info("New value:");
    logger.info(datastoreEventData.getValue().toString());
  }
}

Inclure les dépendances proto dans votre source

Vous devez inclure le mode Datastore data.proto dans le répertoire source de votre fonction. Ce fichier importe les éléments suivants : que vous devez également inclure dans votre répertoire source:

Utilisez la même structure de répertoires pour les dépendances. Par exemple, placez struct.proto dans google/protobuf.

Ces fichiers sont nécessaires pour décoder les données d'événement. Si la source de votre fonction ne pas inclure ces fichiers, il renvoie une erreur lors de son exécution.

Attributs d'événement

Chaque événement inclut des attributs de données qui incluent des informations sur l'événement, telles que l'heure à laquelle il a été déclenché. Firestore en mode Datastore ajoute des données supplémentaires sur la base de données et l'entité impliqués dans l’événement. Pour accéder à ces attributs, procédez comme suit:

Java
logger.info("Event time " + event.getTime());
logger.info("Event project: " + event.getExtension("project"));
logger.info("Event location: " + event.getExtension("location"));
logger.info("Database name: " + event.getExtension("database"));
logger.info("Database namespace: " + event.getExtension("namespace"));
logger.info("Database entity: " + event.getExtension("entity"));
// For withAuthContext events
logger.info("Auth information: " + event.getExtension("authid"));
logger.info("Auth information: " + event.getExtension("authtype"));

Déployer une fonction

Les utilisateurs qui déploient des fonctions Cloud Run doivent disposer Développeur de fonctions Cloud Run IAM ou un rôle qui inclut les mêmes autorisations. Consultez également la section Configuration supplémentaire pour le déploiement.

Vous pouvez déployer une fonction à l'aide de la gcloud CLI ou la console Google Cloud. L'exemple ci-dessous illustre un déploiement avec la gcloud CLI. Pour en savoir plus sur le déploiement avec la console Google Cloud, consultez la page Déployer des fonctions Cloud Run.

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. Exécutez la commande gcloud functions deploy pour déployer une fonction :

    gcloud functions deploy FUNCTION_NAME \
    --gen2 \
    --region=FUNCTION_LOCATION \
    --trigger-location=TRIGGER_LOCATION \
    --runtime=RUNTIME \
    --source=SOURCE_LOCATION \
    --entry-point=CODE_ENTRYPOINT \
    --trigger-event-filters="type=EVENT_FILTER_TYPE" \
    --trigger-event-filters="database=DATABASE" \
    --trigger-event-filters="namespace=NAMESPACE" \
    --trigger-event-filters-path-pattern="entity=ENTITY_OR_PATH" \
    

    Le premier argument, FUNCTION_NAME, est le nom de la fonction déployée. Le nom de la fonction doit commencer par une lettre suivie de 62 caractères au maximum (lettres, chiffres, traits d'union ou traits de soulignement) et doit se terminer par une lettre ou un chiffre. Remplacez FUNCTION_NAME par une valeur valide nom de la fonction. Ajoutez ensuite les indicateurs suivants:

    • L'option --gen2 indique que vous souhaitez déployer des fonctions Cloud Run (2e génération). Omission cette option entraîne le déploiement sur les fonctions Cloud Run (1re génération).

    • L'option --region=FUNCTION_LOCATION spécifie la région dans laquelle déployer votre fonction.

      Pour maximiser la proximité, définissez FUNCTION_LOCATION sur une région à proximité de votre base de données Firestore. Si votre base de données Firestore est dans un emplacement multirégional, définissez la valeur sur us-central1 pour les bases de données. dans nam5 et à europe-west4 pour les bases de données dans eur3. Régional Emplacements Firestore définis sur la même région.

    • --trigger-location=TRIGGER_LOCATION spécifie l'emplacement du déclencheur. Vous devez définir TRIGGER_LOCATION sur l'emplacement de votre base de données en mode Datastore.

    • L'option --runtime=RUNTIME spécifie l'environnement d'exécution de langage qui est utilisé par votre fonction. Fonctions Cloud Run est compatible avec plusieurs environnements d'exécution. Voir Environnements d'exécution. Définissez RUNTIME sur un environnement d'exécution compatible.

    • L'option --source=SOURCE_LOCATION spécifie l'emplacement du code source de votre fonction. Consultez les ressources suivantes : pour en savoir plus:

      Définissez SOURCE_LOCATION sur l'emplacement du code source de votre fonction.

    • L'option --entry-point=CODE_ENTRYPOINT spécifie le point d'entrée de votre fonction dans votre code source. C'est le code que votre fonction exécute lorsqu'elle s'exécute. Vous devez définir CODE_ENTRYPOINT à un nom de fonction ou à une classe complète. existant dans votre code source. Voir Point d'entrée de la fonction pour plus d'informations.

    • --trigger-event-filters Les indicateurs définissent le filtre d'événement, qui inclut le type de déclencheur et l'entité ou chemin d'accès qui déclenche les événements. Indiquez les valeurs d'attribut suivantes pour définir votre filtre d'événement:

      • type=EVENT_FILTER_TYPE: Firestore est compatible avec les types d'événements suivants:

        • google.cloud.datastore.entity.v1.created: l'événement est envoyé lorsqu'une est écrite pour la première fois.
        • google.cloud.datastore.entity.v1.updated: l'événement est envoyé lorsqu'une entité existe déjà et a une valeur modifiée.
        • google.cloud.datastore.entity.v1.deleted: l'événement est envoyé lorsqu'une L'entité a été supprimée.
        • google.cloud.datastore.entity.v1.written: l'événement est envoyé lorsqu'une entité est créée, mise à jour ou supprimée.
        • google.cloud.datastore.entity.v1.created.withAuthContext: l'événement est envoyé. lorsqu'un document est écrit pour la première fois et que l'événement inclut informations d'authentification supplémentaires
        • google.cloud.datastore.entity.v1.updated.withAuthContext: l'événement est envoyé. Lorsqu'un document existe déjà et qu'une valeur a été modifiée. Inclut informations d'authentification supplémentaires
        • google.cloud.datastore.entity.v1.deleted.withAuthContext: l'événement est envoyé. Lorsqu'un document est supprimé. Comprend des informations d'authentification supplémentaires
        • google.cloud.datastore.entity.v1.written.withAuthContext: l'événement est envoyé. la création, la mise à jour ou la suppression d'un document, ainsi que l'événement associé. Inclut informations d'authentification supplémentaires

        Définissez EVENT_FILTER_TYPE sur l'un de ces types d'événements.

      • database=DATABASE : base de données Firestore. Pour le nom de base de données par défaut, définissez DATABASE sur (default).

      • namespace=NAMESPACE: base de données namespace. Par défaut, nom de la base de données, définissez NAMESPACE sur (default). Supprimer l'indicateur pour correspondre à n'importe quel espace de noms.

      • entity=ENTITY_OR_PATH: chemin d'accès à la base de données déclenche des événements lorsque des données sont créées, mises à jour ou supprimés. Les valeurs acceptées pour ENTITY_OR_PATH sont les suivantes:

        • Égal à. Par exemple : --trigger-event-filters="entity='users/marie'"
        • Format de chemin d'accès. Exemple : --trigger-event-filters-path-pattern="entity='users/*'" Pour en savoir plus, consultez la page Comprendre les formats de chemin d'accès.

      Vous pouvez éventuellement spécifier des options supplémentaires de configuration, de mise en réseau et de sécurité lorsque vous déployez une fonction.

      Pour en savoir plus sur la commande de déploiement et ses options, consultez la documentation sur gcloud functions deploy.

Exemples de déploiements

Les exemples suivants illustrent les déploiements avec la Google Cloud CLI.

Déployez une fonction pour une base de données dans la région us-west2:

gcloud functions deploy gcfv2-trigger-datastore-node \
--gen2 \
--region=us-west2 \
--trigger-location=us-west2 \
--runtime=nodejs18 \
--source=gs://example_bucket-1/datastoreEventFunction.zip \
--entry-point=makeUpperCase \
--trigger-event-filters=type=google.cloud.datastore.entity.v1.written \
--trigger-event-filters=database='(default)' \
--trigger-event-filters-path-pattern="entity='messages/{pushId}'"

Déployez une fonction pour une base de données dans l'emplacement multirégional nam5:

gcloud functions deploy gcfv2-trigger-datastore-python \
--gen2 \
--region=us-central1 \
--trigger-location=nam5 \
--runtime=python311 \
--source=gs://example_bucket-1/datastoreEventFunction.zip \
--entry-point=make_upper_case \
--trigger-event-filters=type=google.cloud.datastore.entity.v1.written.withAuthContext \
--trigger-event-filters=database='(default)' \
--trigger-event-filters-path-pattern="entity='messages/{pushId}'"

Limites

Notez les limites suivantes concernant les déclencheurs Firestore pour les fonctions Cloud Run:

  • Les fonctions Cloud Run (1re génération) préparent une valeur "(par défaut)" existante en mode natif Firestore. La solution n'est pas compatible avec les bases de données nommées Firestore ni avec le mode Datastore. Veuillez utiliser les fonctions Cloud Run (2e génération) pour configurer des événements dans de tels cas.
  • L'ordre n'est pas garanti. Les modifications rapides peuvent déclencher des appels de fonctions dans un ordre inattendu.
  • Bien que les événements soient diffusés une fois au moins, un même événement peut produire plusieurs appels de fonction. Évitez de dépendre de procédés dits "exactement une fois" et écrivez des fonctions idempotentes.
  • Firestore en mode Datastore nécessite des fonctions Cloud Run (2e génération). Cloud Run (1re génération) ne permet pas est compatible avec le mode Datastore.
  • Un déclencheur est associé à une seule base de données. Vous ne pouvez pas créer un déclencheur qui correspond à plusieurs bases de données.
  • La suppression d'une base de données ne supprime pas automatiquement les déclencheurs de cette base de données. Le déclencheur cesse de diffuser des événements, mais continue d'exister jusqu'à ce que vous le supprimiez.
  • Si un événement mis en correspondance dépasse la taille maximale de la demande, la valeur l'événement ne sera peut-être pas transmis aux fonctions Cloud Run (1re génération).
    • Les événements non distribués en raison de la taille de la requête sont consignés dans les journaux de plate-forme et sont comptabilisés dans l'utilisation des journaux du projet.
    • Vous trouverez ces journaux dans l'explorateur de journaux avec le message "Event cannot deliver to Cloud function due to size exceeding the limit for 1st gen..." (l'événement ne peut pas être distribué à la fonction Cloud, car sa taille dépasse la limite pour la 1re génération...) de gravité error. Vous trouverez le nom de la fonction dans le champ functionName. Si le champ receiveTimestamp date de moins d'une heure, vous pouvez déduire le contenu réel de l'événement en lisant le document en question avec un instantané avant et après le code temporel.
    • Pour éviter une telle cadence, vous pouvez :
      • Migrer des fonctions Cloud Run et les mettre à niveau (2e génération)
      • Réduire la taille du document
      • Supprimer la fonction Cloud Run en question
    • Vous pouvez désactiver la journalisation proprement dite à l'aide d'exclusions, mais notez que les événements mis en cause ne seront toujours pas distribués.

Emplacements Eventarc et Firestore en mode Datastore

Eventarc n'est pas compatible avec les emplacements multirégionaux pour les événements Firestore mais vous pouvez toujours en créer pour les bases de données Firestore. dans des emplacements multirégionaux. Eventarc mappe Firestore emplacements multirégionaux vers les régions Eventarc suivantes:

Firestore – Plusieurs régions Région Eventarc
nam5 us-central1
eur3 europe-west4

Étape suivante