Gestion des données dans l'API Google Health

Travailler avec des données dans l'API Google Health consiste principalement à synchroniser les données entre le datastore de l'API Google Health dans le cloud et le datastore de votre propre application ou backend. Toutefois, ce cycle peut prendre différentes formes en fonction de divers facteurs :

  • Écrivez-vous des données dans l'API Google Health ? Lecture seule ? Ou les deux ?
  • Votre datastore est-il local sur l'application ou l'appareil ? Ou dans votre propre cloud ?
  • Avez-vous besoin de synchroniser les données de l'API Google Health entre l'application de l'utilisateur et un accessoire connecté ? À quelle fréquence synchronisez-vous vos appareils ?
  • Avec quels types de données travaillez-vous ? Les décomptes de base ? Quelles sont les unités de mesure ? Séries avec des taux d'échantillonnage différents ?
  • Prévoyez-vous de lire des données lorsque votre application est en arrière-plan ?
  • Prévoyez-vous d'utiliser des données historiques enregistrées avant que votre application n'obtienne les autorisations des utilisateurs ?

Pour comprendre comment tout cela s'articule, consultez le cycle de vie de la synchronisation de l'API Google Health. Il existe deux versions de ce cycle de vie : standard (lecture et écriture) et lecture seule.

Cycle de vie de la synchronisation standard

Cycle de vie de la synchronisation standard dans l'API Google Health
Figure 1 : Cycle de vie de la synchronisation standard dans l'API Google Health

L'intégration à l'API Google Health implique la copie de données dans une application ou un datastore de backend. Pour plus de simplicité dans cette documentation, nous appellerons ce datastore datastore du développeur.

Le terme "copier" peut ici remplacer n'importe quelle activité distincte, comme la lecture à partir de l'API Google Health (copie vers le datastore du développeur) ou l'écriture dans l'API Google Health (copie vers l'API Google Health). Le cycle de vie de la synchronisation consiste à effectuer ces actions de manière répétée dans un ordre spécifique.

La figure 1 illustre le cycle de vie de synchronisation standard qui implique des opérations de lecture et d'écriture, sans tenir compte des facteurs mentionnés précédemment.

Écriture

  1. Préparer de nouvelles données à écrire : transférez des données depuis un appareil ou une application externes, puis mettez en forme les points de données en représentations JSON compatibles avec les types de données de l'API Google Health. Notez que les ID personnalisés attribués par le client pour les écritures ne sont actuellement pas acceptés dans l'API Health. Ces ID peuvent être fournis dans un POST, mais ils sont ignorés.
  2. Insérer/Mettre à jour des enregistrements : envoyez des points de données à l'API Google Health à l'aide de points de terminaison REST. Utilisez POST pour créer des enregistrements et PATCH pour insérer et mettre à jour des enregistrements existants. Les ID nécessaires à l'opération PATCH proviennent d'une opération POST précédente (étape suivante d'un cycle précédent).
  3. Traitez les ID de ressources renvoyés : lorsque vous utilisez des ID générés par le serveur, extrayez et conservez la ressource name ou l'ID renvoyé par le serveur dans votre data store de développeur pour permettre de futures mises à jour (PATCH) ou suppressions (DELETE). Pour en savoir plus sur les deux types, consultez Stratégies d'identification.

Lecture

  1. Lire les enregistrements : récupérez les nouvelles données et les modifications apportées aux données existantes dans l'API Google Health à l'aide de points de terminaison REST (GET avec les paramètres de requête filter et la pagination pageToken, ou les points de terminaison d'agrégation tels que rollUp et dailyRollUp), ou recevez des notifications en temps réel à l'aide des abonnements Webhook (projects.subscribers). Une notification indique uniquement que de nouvelles données sont disponibles, et non quelles sont ces données.
  2. Réconcilier le datastore du développeur : réconciliez les données nouvelles et mises à jour avec votre datastore de développeur. Les appareils connectés peuvent générer des intervalles qui se chevauchent lors des synchronisations. Pour savoir comment l'API Google Health les résout, consultez Synchronisation des codes temporels d'intervalle et des appareils connectés.

Ce cycle se répète ensuite à des intervalles appropriés en fonction des besoins spécifiques des applications ou appareils externes. Il s'agit généralement de l'ordre que nous recommandons pour synchroniser les données entre votre propre datastore et l'API Google Health.

Stratégies d'identification

Si vous prévoyez d'écrire des données dans l'API Google Health, vous devez choisir une stratégie d'identification des ressources avant de créer des points de données (l'unité de données de base) pour votre intégration avec les API Google Health.

Les ID attribués par le client pour les écritures ne sont pas compatibles avec l'API Health pour le moment. Ces ID peuvent être fournis dans un POST, mais ils sont ignorés. Les informations sur cette option sont fournies ici à titre indicatif.

  1. ID générés par le serveur (option par défaut) : le client envoie des données sans ID, et le backend de l'API Google Health génère et renvoie un identifiant système unique.
  2. ID personnalisés attribués par le client (conformément à l'AIP-133, non encore pris en charge) : L'application cliente génère un identifiant unique (par exemple, un UUID ou une clé primaire de base de données locale) et le fournit dans le chemin d'accès à la ressource lors de la création.

Le tableau suivant compare les deux stratégies d'identification pour vous aider à choisir l'approche adaptée à votre intégration :

Fonctionnalité ID générés par le serveur ID personnalisés attribués par le client
Génération d'ID Le serveur génère un ID système aléatoire lors de l'exécution de POST. Le client génère un ID stable en local (UUID v4 / clé primaire interne) avant l'écriture.
Chemin d'accès à la ressource .../dataPoints/{server_id} (renvoyé dans la réponse) .../dataPoints/{custom_id}
Étape locale post-écriture Obligatoire. Doit stocker le server_id renvoyé dans la base de données locale pour permettre les futures mises à jour/suppressions. Aucun : L'application est déjà propriétaire de l'ID.
Table de mappage d'ID Obligatoire. Le client doit maintenir un mappage bidirectionnel (local_id ↔ server_id). Non requis. Le client utilise directement sa propre clé primaire.
Comportement de nouvelle tentative (réseau faible) Risque de doublons. Si vous réessayez d'envoyer un POST ayant expiré, un enregistrement en double est créé avec un nouvel ID de serveur. Sûr et idempotent. Si vous réessayez POST avec le même custom_id, vous évitez la création de doublons (renvoie 409 ALREADY_EXISTS).
Prise en charge de la synchronisation hors connexion Limitée Vous devez attendre la réponse du serveur pour obtenir les ID de ressources officiels avant de les référencer. Complète : Les entités peuvent être créées et modifiées hors connexion avec des ID stables, puis synchronisées de manière fluide une fois la connexion rétablie.
Contraintes de format Entièrement géré par le serveur. Doit respecter le format ^[a-z0-9-]{4,63}$ (4 à 63 caractères alphanumériques minuscules et traits d'union).
Quand choisir

Choisissez les ID générés par le serveur si :

  • Votre application est en écriture seule / ajout uniquement (par exemple, elle envoie des données de télémétrie ou des nombres de pas qui ne sont jamais mis à jour ni supprimés ultérieurement).
  • Votre application ne gère pas de base de données persistante locale de points de données individuels.
  • Vous préférez la simplicité sans avoir à gérer les contraintes de validation des chaînes (comme les caractères 4-63).

Choisissez des ID personnalisés si :

  • Vous gérez une application de synchronisation bidirectionnelle qui lit, écrit et met à jour les dossiers de santé sur plusieurs appareils.
  • Votre application dispose d'une base de données locale (telle que Room ou SQLite) qui stocke des enregistrements avec des clés primaires locales.
  • Vos utilisateurs enregistrent des données hors connexion ou via des connexions mobiles intermittentes où des nouvelles tentatives sécurisées sont nécessaires.
  • Vous souhaitez éliminer les tables de mappage d'ID entre votre base de données backend et l'API.

Cycle de vie de la synchronisation en lecture seule

Cycle de vie de la synchronisation en lecture seule dans l'API Google Health
Figure 2 : Cycle de vie de la synchronisation en lecture seule dans l'API Google Health

Une application qui n'a l'intention que de lire des données à partir de l'API Google Health doit copier les données dans son data store de développeur et gérer la partie réconciliation du cycle de vie.

Les mêmes tâches que celles décrites dans la section Lecture s'appliquent ici.

La figure 2 illustre le cycle de vie en lecture seule.

Codes temporels d'intervalle et synchronisation des appareils connectés

Les données d'intervalle représentent des mesures collectées sur une période donnée, comme les pas, la fréquence cardiaque ou les séances d'exercice. En revanche, les mesures ponctuelles incluent les entrées manuelles, comme un journal alimentaire ou une lecture de balance. Les données d'intervalle proviennent généralement de la synchronisation des appareils connectés, tels que les montres connectées et les bracelets d'activité.

Les codes temporels d'intervalle (startTime et endTime) introduisent des comportements uniques lorsque vous travaillez avec des données d'intervalle. Cette section explique pourquoi des intervalles se chevauchent et compare les points de terminaison list et reconcile.

Chevauchement des intervalles provenant d'appareils connectés

Les appareils connectés tels que les bracelets d'activité Fitbit et la Google Pixel Watch collectent en continu des données biométriques à haute fréquence lorsqu'ils sont portés. Lorsqu'un appareil synchronise des points de données avec Google Health, il ne modifie pas rétroactivement les enregistrements existants. Les codes temporels d'intervalle stockés ne sont pas modifiés.

Toutefois, avant les cycles de synchronisation suivants, les algorithmes sur l'appareil réinterprètent souvent la télémétrie brute des capteurs. L'appareil regroupe les lectures collectées au cours des heures précédentes. Lorsque l'appareil se synchronise à nouveau, il importe de nouveaux points de données. Leurs limites de début et de fin peuvent chevaucher des intervalles précédemment stockés.

Prenons l'exemple d'un utilisateur portant une montre connectée dont les données d'activité sont synchronisées dans deux lots consécutifs :

  1. Lors de la première synchronisation, l'appareil importe un point de données couvrant la période allant du 10:00:00Z au 10:14:59Z.
  2. Après le recalcul sur l'appareil, une deuxième synchronisation importe un autre point de données couvrant la période allant du 10:14:00Z au 10:28:59Z.

Les deux enregistrements sont stockés indépendamment dans le backend Google Santé. Par conséquent, les deux points de données couvrent l'intervalle allant de 10:14:00Z à 10:14:59Z. Cela produit un chevauchement de 59 secondes lors de l'interrogation des enregistrements bruts.

Comparer la liste et rapprocher les points de terminaison

Vous pouvez gérer ces intervalles qui se chevauchent à l'aide du point de terminaison list ou reconcile. Choisissez le point de terminaison qui correspond aux exigences de votre application :

Fonctionnalité list point de terminaison reconcile point de terminaison
Méthode HTTP GET https://health.googleapis.com/v4/users/me/dataTypes/<var>dataType</var>/dataPoints GET https://health.googleapis.com/v4/users/me/dataTypes/<var>dataType</var>/dataPoints:reconcile
Comportement de chevauchement Renvoie tous les enregistrements stockés tels qu'ils ont été importés, sans déduplication. Lorsque les intervalles se chevauchent, les deux enregistrements sont renvoyés. Résout les conflits et déduplique les enregistrements qui se chevauchent sur les appareils et les sessions de synchronisation en un seul flux continu.
Avantages Fournit une piste d'audit complète et non modifiée de chaque enregistrement importé par chaque appareil et chaque lot de synchronisation. Simplifie le rendu de la timeline et les calculs de durée en gérant automatiquement les intervalles qui se chevauchent et les conflits entre plusieurs appareils.
Inconvénients Votre application est chargée de détecter et de résoudre les problèmes de chevauchement d'intervalles, les conflits multi-appareils et les périodes où l'appareil n'est pas porté au poignet. Les enregistrements subordonnés qui se chevauchent sont omis de la réponse. Par conséquent, les lots de synchronisation d'appareils individuels ne peuvent pas être audités de manière isolée.

Le point de terminaison reconcile est conçu pour dessiner des interfaces utilisateur, afficher des chronologies d'activité et calculer des totaux de durée non chevauchants. Il résout les intervalles conflictuels des sessions de synchronisation re-bucketées. Il permet également de réconcilier l'activité enregistrée simultanément sur plusieurs appareils, comme une montre et un téléphone.

La réconciliation résout les conflits de sessions en sélectionnant l'enregistrement faisant autorité plutôt que de synthétiser une union temporelle artificielle. Par exemple, il ne fusionne pas 11:00:00Z à 11:30:00Z et 11:20:00Z à 11:50:00Z en 11:00:00Z à 11:50:00Z. La réponse réconciliée renvoie le point de données gagnant avec son intervalle enregistré d'origine. Cela préserve l'intégrité des métriques et de la télémétrie mesurées pour cette session.

La figure 3 illustre la façon dont le point de terminaison reconcile gère les sessions qui se chevauchent. Il sélectionne l'enregistrement faisant autorité au lieu de créer une union temporelle artificielle.

Résoudre les intervalles qui se chevauchent : réconcilier la déduplication des points de terminaison par rapport à la fusion artificielle de l'union temporelle
Figure 3 : Réconciliation des sessions conflictuelles par rapport à la fusion artificielle des unions temporelles

Le guide Endpoints fournit des exemples complets de requêtes et de réponses. Pour comparer les enregistrements list bruts avec les résultats reconcile, consultez Obtenir une vue rapprochée des données d'intervalle.

Le point de terminaison list est conçu pour les diagnostics des appareils et les audits de données. Utilisez-le lorsque votre workflow nécessite d'inspecter les enregistrements non modifiés tels qu'ils ont été importés par chaque appareil. Lorsque vous effectuez des requêtes avec list, la logique de votre client doit gérer les chevauchements d'intervalles dans les données brutes.

Immuabilité du code temporel et mises à jour du propriétaire

Les appareils connectés ne modifient pas rétroactivement les codes temporels stockés lors des cycles de synchronisation normaux. Toutefois, les codes temporels d'intervalle (startTime et endTime) ne sont pas universellement immuables dans toutes les sources de données. Seul le créateur ou le propriétaire d'origine d'un enregistrement peut modifier ses champs. Les autres applications ne peuvent pas modifier les points de données qu'elles n'ont pas créés.

Une application propriétaire peut utiliser le point de terminaison patch pour mettre à jour ses enregistrements existants. Cela inclut la modification des codes temporels de début ou de fin. Pour obtenir un exemple de mise à jour des codes temporels avec PATCH, consultez Mettre à jour les codes temporels des intervalles pour les données existantes dans le guide Endpoints.

De même, les points de données synchronisés depuis des plates-formes externes telles que Santé Connect ou des applications partenaires héritent des mises à jour de la source d'origine. Lorsque l'application d'origine modifie un enregistrement existant, ces modifications sont propagées à Google Santé.