Google Health API でのデータ管理

Google Health API でデータを操作する際の中心となるのは、クラウド内の Google Health API データストアと独自のアプリまたはバックエンド データストアの間でデータを同期するサイクルです。ただし、このサイクルは、さまざまな要因に応じて異なる形式をとることがあります。

  • Google Health API にデータを書き込んでいますか?読み取り専用ですか?または、その両方ですか?
  • データストアはアプリまたはデバイスのローカルにありますか?それとも、独自のクラウドに保存されていますか?
  • ユーザーのアプリとウェアラブル デバイスの間で Google Health API データを同期する必要がありますか?デバイスを同期する頻度はどのくらいですか?
  • どのタイプのデータを扱っていますか?基本的なカウント測定単位サンプリング レートが異なるシリーズ
  • アプリがバックグラウンドで動作しているときにデータを読み取る予定はありますか?
  • アプリがユーザー権限を取得する前に記録された過去のデータを操作する予定はありますか?

これらがどのように連携するかを理解するには、Google Health API の同期ライフサイクルをご覧ください。このライフサイクルには、標準(読み取りと書き込み)と読み取り専用の 2 つのバージョンがあります。

標準の同期ライフサイクル

Google Health API の標準の同期ライフサイクル
図 1: Google Health API の標準同期ライフサイクル

Google Health API と統合するということは、アプリまたはバックエンド データストアにデータをコピーすることを意味します。このドキュメントでは、このデータストアをデベロッパー データストアと呼びます。

ここでの「コピー」は、Google Health API からの読み取り(デベロッパーのデータストアへのコピー)や Google Health API への書き込み(Google Health API へのコピー)など、個別の操作に置き換えることができます。これらのアクションを特定の順序で繰り返し実行することが、同期のライフサイクルです。

図 1 は、前述の要因を考慮しない、読み取りオペレーションと書き込みオペレーションを含む標準の同期ライフサイクルを示しています。

書き込み

  1. 書き込み用の新しいデータを準備する - 外部デバイスまたはアプリからデータを転送し、データポイントを Google Health API のデータ型と互換性のある JSON 表現にフォーマットします。なお、現時点では、Health API で書き込み用のカスタム クライアント割り当て ID はサポートされていません。このような ID は POST で指定できますが、無視されます。
  2. レコードをアップサートする - REST エンドポイントを使用して、データポイントを Google Health API に送信します。レコードの作成には POST を使用し、既存のレコードの挿入と更新には PATCH を使用します。PATCH オペレーションに必要な ID は、前の POST オペレーション(前のサイクルの次のステップ)から取得されます。
  3. 返されたリソース ID を処理する - サーバー生成の ID を使用する場合は、サーバーから返されたリソース name または ID を抽出してデベロッパー データストアに保持し、将来の更新(PATCH)または削除(DELETE)を可能にします。2 つのタイプの詳細については、識別戦略をご覧ください。

読み取り

  1. レコードを読み取る - REST エンドポイント(filter クエリ パラメータと pageToken ページネーションを含む GET、または rollUp や dailyRollUp などの集計エンドポイント)を使用して、Google Health API から新しいデータを取得し、既存のデータを変更します。または、Webhook サブスクリプション(projects.subscribers)を使用して通知を受け取ります。通知は、新しいデータが利用可能であることを示すだけで、実際のデータの内容は示しません。
  2. デベロッパー データストアを調整する - 新しいデータと更新されたデータをデベロッパー データストアに調整します。コネクテッド デバイスは、同期中に重複する間隔を生成することがあります。Google Health API がこれらを解決する方法については、インターバル タイムスタンプとコネクテッド デバイスの同期をご覧ください。

このサイクルは、外部デバイスまたはアプリの特定のニーズに応じて、適切な間隔で繰り返されます。通常、独自のデータストアと Google Health API の間でデータを同期する場合は、この順序をおすすめします。

特定戦略

Google Health API にデータを書き込む場合は、Google Health API との統合を構築する前に、データポイント(データの基本単位)を作成するときにリソース識別戦略を選択する必要があります。

現時点では、Health API で書き込み用のクライアント割り当て ID はサポートされていません。このような ID は POST で指定できますが、無視されます。このオプションの詳細については、情報提供のみを目的としてここで説明します。

  1. サーバー生成 ID(デフォルト オプション): クライアントは ID なしでデータを送信し、Google Health API バックエンドは一意のシステム識別子を生成して返します。
  2. クライアント割り当てのカスタム ID(AIP-133 単位、未サポート): クライアント アプリは固有識別子(UUID やローカル データベースの主キーなど)を生成し、作成時にリソースパスで指定します。

次の表は、2 つの識別戦略を比較したものです。統合に適したアプローチを選択する際の参考にしてください。

機能 サーバー生成 ID クライアントが割り当てたカスタム ID
ID の生成 サーバーは、POST の実行中にランダムなシステム ID を生成します。 クライアントは、書き込みの前にローカルで安定した ID(UUID v4 / 内部 PK)を生成します。
リソースパス .../dataPoints/{server_id}(レスポンスで返される) .../dataPoints/{custom_id}
書き込み後のローカル ステップ 必須。今後の更新や削除を可能にするには、返された server_id をローカル DB に保存する必要があります。 なし。アプリがすでに ID を所有している。
ID マッピング テーブル 必須。クライアントは、双方向のマッピング(local_id ↔ server_id)を維持する必要があります。 必要ありません。クライアントが独自の主キーを直接使用する。
再試行の動作(ネットワークが弱い場合) 重複のリスク。タイムアウトした POST を再試行すると、新しいサーバー ID で重複レコードが作成されます。 安全かつべき等。同じ custom_id で POST を再試行すると、重複作成が防止されます(409 ALREADY_EXISTS が返されます)。
オフライン同期のサポート 制限あり。参照する前に、サーバーのレスポンスを待って公式のリソース ID を取得する必要があります。 フル。エンティティは、安定した ID を使用してオフラインで作成および変更し、再接続時にシームレスに同期できます。
フォーマットの制約 すべてサーバーによって処理されます。 ^[a-z0-9-]{4,63}$(4 ~ 63 文字の英小文字、数字、ハイフン)に準拠する必要があります。
選択するタイミング

次のような場合は、サーバー生成の ID を選択します。

  • アプリが書き込み専用 / 追加専用である(後で更新または削除されることのないテレメトリーや歩数を送信するなど)。
  • アプリが個々のデータポイントのローカル永続データベースを保持していない。
  • 文字列検証制約(4-63 文字など)を管理せずに、シンプルにしたい。

カスタム ID を選択するケース:

  • デバイス間で医療記録の読み取り、書き込み、更新を行う双方向同期アプリを運用している。
  • アプリに、ローカル主キーを持つレコードを保存するローカル データベース(Room や SQLite など)がある。
  • ユーザーがオフラインで、または断続的なモバイル接続を介してデータを記録し、安全な再試行が必要な場合。
  • バックエンド データベースと API の間の ID マッピング テーブルを排除したい。

読み取り専用同期のライフサイクル

Google Health API の読み取り専用同期ライフサイクル
図 2: Google Health API の読み取り専用同期のライフサイクル

Google Health API からの読み取りのみを目的とするアプリは、データをデベロッパー データストアにコピーし、ライフサイクルの調整部分を処理する必要があります。

読み取りセクションで説明したタスクがここでも適用されます。

図 2 は、読み取り専用のライフサイクルを示しています。

インターバルのタイムスタンプとコネクテッド デバイスの同期

インターバル データは、歩数、心拍数、エクササイズ セッションなど、一定期間にわたって収集された測定値を表します。一方、特定の時点の測定値には、食事の記録や体重計の測定値などの手動入力が含まれます。インターバル データは通常、スマートウォッチやフィットネス トラッカーなどのコネクテッド デバイスの同期から取得されます。

間隔タイムスタンプ(REST JSON ペイロードの startTime と endTime、またはフィルタ式と gRPC の start_time と end_time)は、間隔データを操作するときに固有の動作を導入します。このセクションでは、重複する間隔が発生する理由を説明し、list エンドポイントと reconcile エンドポイントを比較します。

コネクテッド デバイスからの重複するインターバル

Fitbit トラッカーや Google Pixel Watch などのコネクテッド デバイスは、装着中に高頻度で生体認証データを継続的に収集します。デバイスがデータポイントを Google Health に同期した後、既存のレコードを遡及的に変更することはありません。保存されている間隔のタイムスタンプは変更されません。

ただし、後続の同期サイクルの前に、デバイス上のアルゴリズムが未加工のセンサー テレメトリーを再解釈することがよくあります。デバイスは、過去数時間に収集された測定値を再バケット化します。デバイスが再度同期されると、新しいデータポイントがアップロードされます。開始境界と終了境界は、以前に保存された間隔と重複する可能性があります。

たとえば、スマートウォッチを装着しているユーザーのアクティビティ データが、2 つの連続したバッチで同期されるとします。

  1. 最初の同期時に、デバイスは 10:00:00Z から 10:14:59Z までのデータポイントをアップロードします。
  2. デバイス上の再計算に続いて、2 回目の同期で 10:14:00Z から 10:28:59Z までの別のデータポイントがアップロードされます。

どちらの記録も、Google Health のバックエンドに個別に保存されます。その結果、両方のデータポイントが 10:14:00Z から 10:14:59Z までの間隔をカバーします。これにより、未加工のレコードをクエリすると 59 秒の重複が発生します。

リストを比較してエンドポイントを調整する

これらの重複する間隔は、list エンドポイントまたは reconcile エンドポイントを使用して処理できます。アプリケーションの要件に一致するエンドポイントを選択します。

機能 list エンドポイント reconcile エンドポイント
HTTP メソッド GET https://health.googleapis.com/v4/users/me/dataTypes/dataType/dataPoints GET https://health.googleapis.com/v4/users/me/dataTypes/dataType/dataPoints:reconcile
重複の動作 アップロードされたすべての保存済みレコードを重複除去なしで返します。間隔が重複している場合、両方のレコードが返されます。 デバイスと同期セッション間で重複するレコードの競合を解決し、重複を排除して、1 つの連続したストリームにまとめます。
メリット 各デバイスと同期バッチによってアップロードされたすべてのレコードの、変更されていない完全な監査証跡を提供します。 重複する間隔やマルチデバイスの競合を自動的に処理することで、タイムラインのレンダリングと期間の計算を簡素化します。
デメリット アプリは、重複する間隔、マルチデバイスの競合、手首から外れている期間を検出して解決する必要があります。 下位の重複するレコードはレスポンスから除外されるため、個々のデバイスの同期バッチを個別に監査することはできません。

reconcile エンドポイントは、ユーザー インターフェースの描画、アクティビティ タイムラインのレンダリング、重複しない期間の合計の計算を行うように設計されています。これにより、再バケット化された同期セッションの競合する間隔が解決されます。また、スマートウォッチやスマートフォンなど、複数のデバイスで同時に記録されたアクティビティも調整します。

調整では、人工的な時間の結合を合成するのではなく、信頼できるレコードを選択することで、競合するセッションを解決します。たとえば、11:00:00Z から 11:30:00Z と 11:20:00Z から 11:50:00Z を 11:00:00Z から 11:50:00Z にマージすることはありません。調整されたレスポンスは、元の記録された間隔で、優先されるデータポイントを返します。これにより、そのセッションで測定されたテレメトリーと指標の整合性が維持されます。

図 3 は、reconcile エンドポイントが重複するセッションを処理する方法を示しています。人工的な時間結合を作成するのではなく、信頼できるレコードを選択します。

重複する間隔の解決: エンドポイントの重複除去と人工的な時間結合マージの調整
図 3: 競合するセッションの調整と人工的な時間ユニオン マージの比較

Endpoints ガイドには、リクエストとレスポンスの完全な例が記載されています。未加工の list レコードと reconcile 出力を比較するには、インターバル データの調整済みビューを取得するをご覧ください。

list エンドポイントは、デバイス診断とデータ監査用に設計されています。各デバイスによってアップロードされた未変更のレコードを検査する必要があるワークフローで使用します。list を使用してクエリを実行する場合、クライアント ロジックは元データの間隔の重複を処理する必要があります。

タイムスタンプの変更可能性とオーナーの更新

コネクテッド デバイスは、通常の同期サイクル中に、保存されているタイムスタンプを遡って変更することはありません。ただし、間隔タイムスタンプ(REST JSON ペイロードの startTime と endTime、フィルタ式と gRPC の start_time と end_time)は、すべてのデータソースで不変ではありません。レコードのフィールドを変更できるのは、そのレコードの元の作成者またはオーナーのみです。他のアプリケーションは、作成していないデータポイントを編集できません。

オーナー アプリケーションは、patch エンドポイントを使用して既存のレコードを更新できます。これには、開始タイムスタンプまたは終了タイムスタンプの変更が含まれます。これにより、サーバー上の UTC(startTime と endTime)フィールドと常用時(civilStartTime と civilEndTime)フィールドの両方が更新されます。PATCH を使用してタイムスタンプを更新する例については、Endpoints ガイドの既存のデータの間隔タイムスタンプを更新するをご覧ください。

同様に、ヘルスコネクトやパートナー アプリなどの外部プラットフォームから同期されたデータポイントは、元のソースからの更新を継承します。その後、ヘルスコネクトが元のサードパーティ製アプリから同期されたレコードの更新を受け取ると、それらの変更が反映され、既存のレコードが上書きされます。