העבודה עם נתונים ב-Google Health API היא בעיקרה מחזור של סנכרון נתונים בין מאגר הנתונים של Google Health API בענן לבין האפליקציה או מאגר הנתונים שלכם בקצה העורפי. עם זאת, המחזור הזה יכול להשתנות בהתאם למגוון גורמים:
- האם אתם כותבים נתונים ב-Google Health API? לקריאה בלבד? או גם וגם?
- האם מאגר הנתונים שלכם נמצא באופן מקומי באפליקציה או במכשיר? או בענן שלכם?
- האם אתם צריכים לסנכרן את נתוני Google Health API בין האפליקציה של המשתמש לבין מכשיר לביש? באיזו תדירות אתם מסנכרנים מכשירים?
- עם אילו סוגי נתונים אתם עובדים? ספירות בסיסיות? יחידות מידה? סדרות עם קצבי דגימה שונים?
- האם אתם מתכננים לקרוא נתונים כשהאפליקציה פועלת ברקע?
- האם אתם מתכננים לעבוד עם נתונים היסטוריים שתועדו לפני שהאפליקציה קיבלה הרשאות משתמש?
כדי להבין איך כל זה משתלב, כדאי לעיין במחזור החיים של הסנכרון של Google Health API. יש שתי גרסאות של מחזור החיים הזה: רגילה (קריאה וכתיבה) ולקריאה בלבד.
מחזור החיים הרגיל של הסנכרון
שילוב עם Google Health API פירושו העתקת נתונים לאפליקציה או למאגר נתונים לקצה העורפי. כדי שיהיה קל יותר להשתמש במסמכי התיעוד האלה, נקרא למאגר הנתונים הזה מאגר הנתונים של המפתח.
המונח "העתקה" בהקשר הזה יכול להתייחס לכל פעילות נפרדת, כמו קריאה מ-Google Health API (העתקה למאגר הנתונים של המפתח) או כתיבה ב-Google Health API (העתקה ל-Google Health API). ביצוע הפעולות האלה שוב ושוב בסדר מסוים הוא מחזור החיים של הסנכרון.
איור 1 ממחיש את מחזור החיים הרגיל של סנכרון שכולל פעולות קריאה וכתיבה, בלי להתייחס לאף אחד מהגורמים שהוזכרו קודם.
כתיבה
- הכנת נתונים חדשים לכתיבה – העברת נתונים מאפליקציה או ממכשיר חיצוניים ועיצוב נקודות על הגרף לייצוגי JSON שתואמים לסוגי הנתונים של Google Health API. שימו לב: בשלב הזה, Health API לא תומך במזהים מותאמים אישית שהלקוח מקצה לפעולות כתיבה. אפשר לציין מזהים כאלה ב-
POST, אבל המערכת מתעלמת מהם. - עדכון או הוספה (upsert) של רשומות – שליחת נקודות על הגרף ל-Google Health API באמצעות נקודות קצה (endpoints) של REST. משתמשים ב-
POSTכדי ליצור רשומות, וב-PATCHכדי להוסיף ולעדכן רשומות קיימות. המזהים שנדרשים לפעולהPATCHיגיעו מפעולה קודמת שלPOST(השלב הבא במחזור קודם). - עיבוד מזהי המשאבים שהוחזרו – כשמשתמשים במזהים שנוצרו בשרת, צריך לחלץ את המשאב
nameאו המזהה שהוחזר מהשרת ולשמור אותם במאגר הנתונים של המפתחים כדי לאפשר עדכונים (PATCH) או מחיקות (DELETE) בעתיד. מידע נוסף על שני הסוגים זמין בקטע אסטרטגיות זיהוי.
קריאה
- קריאת רשומות – אחזור נתונים חדשים ושינויים בנתונים קיימים ב-Google Health API באמצעות נקודות קצה (endpoints) של REST (
GETעם פרמטרים של שאילתהfilterועימודpageToken, או נקודות קצה של צבירה כמוrollUpו-dailyRollUp), או קבלת התראות באמצעות מינויים ל-Webhook (projects.subscribers). התראה רק מציינת שנתונים חדשים זמינים, ולא מהם הנתונים בפועל. - התאמה של מאגר הנתונים של המפתח — התאמה של הנתונים החדשים והמעודכנים למאגר הנתונים של המפתח. מכשירים מחוברים יכולים ליצור מרווחי זמן חופפים במהלך הסנכרון. כדי להבין איך Google Health API פותר את הבעיות האלה, קראו את המאמר חותמות זמן של מרווחים וסנכרון של מכשירים מחוברים.
המחזור הזה חוזר על עצמו במרווחי זמן מתאימים, בהתאם לצרכים הספציפיים של האפליקציות או המכשירים החיצוניים. בדרך כלל זה הסדר שמומלץ לסנכרן בו נתונים בין מאגר הנתונים שלכם לבין Google Health API.
שיטות זיהוי
אם אתם מתכוונים לכתוב נתונים ב-Google Health API, לפני שאתם יוצרים את השילוב עם ממשקי ה-API של Google Health, אתם צריכים לבחור אסטרטגיה לזיהוי משאבים כשאתם יוצרים נקודות על הגרף (יחידת הנתונים הבסיסית).
בשלב הזה, Health API לא תומך במזהים שהלקוח מקצה לפעולות כתיבה.
מזהים כאלה יכולים להופיע ב-POST, אבל המערכת מתעלמת מהם. הפרטים על האפשרות הזו מופיעים כאן למטרות מידע בלבד.
- מזהים שנוצרו על ידי השרת (אפשרות ברירת המחדל): הלקוח שולח נתונים בלי מזהה, וה-backend של Google Health API יוצר ומחזיר מזהה מערכת ייחודי.
- מזהים מותאמים אישית שהוקצו על ידי הלקוח (לפי AIP-133, עדיין לא נתמכים): אפליקציית הלקוח יוצרת מזהה ייחודי (לדוגמה, UUID או מפתח ראשי של מסד נתונים מקומי) ומספקת אותו בנתיב המשאב בזמן היצירה.
בטבלה הבאה מוצגת השוואה בין שתי שיטות הזיהוי, כדי לעזור לכם לבחור את הגישה המתאימה לשילוב שלכם:
| תכונה | מזהים שנוצרו על ידי השרת | מזהים מותאמים אישית שהוקצו על ידי הלקוח |
|---|---|---|
| יצירת מזהה | השרת יוצר מזהה מערכת אקראי במהלך ההפעלה של POST. |
הלקוח יוצר מזהה יציב באופן מקומי (UUID v4 או PK פנימי) לפני הכתיבה. |
| נתיב המשאב | .../dataPoints/{server_id} (מוחזר בתגובה) |
.../dataPoints/{custom_id} |
| שלב מקומי אחרי כתיבה | חובה. צריך לאחסן את הערך המוחזר של server_id במסד נתונים מקומי כדי לאפשר עדכונים או מחיקות בעתיד. |
אין. המזהה כבר שייך לאפליקציה. |
| טבלת מיפוי מזהים | חובה. הלקוח צריך לשמור על מיפוי דו-כיווני (local_id ↔ server_id). |
אין צורך. הלקוח משתמש ישירות במפתח הראשי שלו. |
| התנהגות של ניסיון חוזר (רשת חלשה) | סיכון לכפילויות. אם מנסים שוב להפעיל POST שהזמן הקצוב לתפוגה שלו חלף,
נוצרת רשומה כפולה עם מזהה שרת חדש. |
בטוחה ואידמפוטנטית. אם מנסים שוב את POST עם אותו custom_id, לא נוצר עותק כפול (מוחזר 409
ALREADY_EXISTS). |
| תמיכה בסנכרון אופליין | מוגבלת. צריך להמתין לתגובה מהשרת כדי לקבל מזהי משאבים רשמיים לפני שמאזכרים אותם. | מלא. אפשר ליצור ולשנות ישויות אופליין באמצעות מזהים יציבים, ואז לסנכרן אותן בצורה חלקה כשמתחברים מחדש. |
| אילוצי פורמט | השרת מטפל בזה באופן מלא. | חייב לעמוד בדרישות של ^[a-z0-9-]{4,63}$ (4-63 תווים אלפאנומריים קטנים ומקפים). |
| מתי כדאי לבחור באפשרות הזו |
כדאי לבחור במזהים שנוצרו בשרת אם:
|
כדאי לבחור מזהים מותאמים אישית אם:
|
מחזור החיים של סנכרון לקריאה בלבד
באפליקציה שנועדה רק לקרוא מ-Google Health API, צריך להעתיק את הנתונים למאגר הנתונים של המפתח ולטפל בחלק של ההתאמה במחזור החיים.
המשימות שמופיעות בקטע קריאה רלוונטיות גם כאן.
איור 2 ממחיש את מחזור החיים של מצב לקריאה בלבד.
חותמות זמן של מרווחים וסנכרון של מכשירים מחוברים
נתוני מרווחים מייצגים מדידות שנאספו לאורך זמן, כמו צעדים, דופק או אימוני כושר. לעומת זאת, מדידות נקודתיות כוללות רשומות ידניות כמו יומן מזון או קריאה של משקל. נתוני אינטרוול מגיעים בדרך כלל מסנכרון של מכשירים מחוברים, כמו שעונים חכמים וצמידי כושר.
חותמות זמן של מרווחים (startTime ו-endTime במטענים ייעודיים (payloads) של REST JSON, או start_time ו-end_time בביטויי סינון וב-gRPC) מציגות התנהגויות ייחודיות כשעובדים עם נתוני מרווחים. בקטע הזה מוסבר למה יש חפיפה בין מרווחי הזמן, ומוצגת השוואה בין נקודות הקצה list ו-reconcile.
מרווחי זמן חופפים ממכשירים מחוברים
מכשירים מחוברים כמו מכשירי מעקב של Fitbit ו-Google Pixel Watch אוספים באופן רציף נתונים ביומטריים בתדירות גבוהה בזמן שעונדים אותם. אחרי שהמכשיר מסנכרן את הנקודות על הגרף עם Google Health, הוא לא משנה רטרואקטיבית את הרשומות הקיימות. חותמות הזמן של המרווחים ששמורים בהם לא משתנות.
עם זאת, לפני מחזורי הסנכרון הבאים, אלגוריתמים במכשיר מפרשים מחדש לעיתים קרובות את נתוני הטלמטריה הגולמיים של החיישנים. המכשיר מקבץ מחדש את הקריאות שנאספו בשעות הקודמות. כשהמכשיר מסתנכרן שוב, הוא מעלה נקודות חדשות על הגרף. גבולות ההתחלה והסיום שלהם יכולים לחפוף למרווחים שכבר נשמרו.
לדוגמה, נניח שמשתמש עונד שעון חכם ונתוני הפעילות שלו מסונכרנים בשתי קבוצות עוקבות:
- במהלך הסנכרון הראשון, המכשיר מעלה נקודה על הגרף שכוללת את התאריכים
10:00:00Zעד10:14:59Z. - אחרי החישוב מחדש במכשיר, מתבצע סנכרון שני שמעלה עוד נקודה על הגרף שכוללת את הנתונים מ-
10:14:00Zעד10:28:59Z.
שני התיקים מאוחסנים בנפרד בקצה העורפי של Google Health. כתוצאה מכך, שתי נקודות על הגרף מכסות את המרווח בין 10:14:00Z ל-10:14:59Z.
כתוצאה מכך, יש חפיפה של 59 שניות כששולחים שאילתות לגבי רשומות גולמיות.
השוואה בין הרשימה לבין נקודות הקצה והתאמה ביניהן
אפשר לטפל במרווחים החופפים האלה באמצעות נקודת הקצה list או reconcile. בוחרים את נקודת הקצה שמתאימה לדרישות של האפליקציה:
| תכונה | נקודת קצה (endpoint) אחת (list) |
נקודת קצה (endpoint) אחת (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 |
| התנהגות החפיפה | הפונקציה מחזירה את כל הרשומות שנשמרו כפי שהועלו, בלי לבטל כפילויות. כשיש חפיפה בין המרווחים, שתי הרשומות מוחזרות. | פותרת התנגשויות ומסירה רשומות כפולות שחופפות בין מכשירים וסשנים של סנכרון, ויוצרת רצף אחד. |
| יתרונות | מספק נתיב ביקורת מלא וללא שינויים של כל רשומה שהועלתה על ידי כל מכשיר וקבוצת סנכרון. | מפשט את עיבוד ציר הזמן ואת חישובי משך הזמן על ידי טיפול אוטומטי במרווחים חופפים ובקונפליקטים בין כמה מכשירים. |
| חסרונות | האפליקציה שלכם אחראית לזהות ולפתור מרווחים חופפים, התנגשויות בין כמה מכשירים ותקופות שבהן המכשיר לא על פרק כף היד. | רשומות חופפות משניות מושמטות מהתגובה, כך שלא ניתן לבדוק בנפרד קבוצות סנכרון של מכשירים ספציפיים. |
נקודת הקצה reconcile מיועדת ליצירת ממשקי משתמש, לעיבוד של צירי זמן של פעילות ולחישוב של סך משכי הזמן שלא חופפים. הוא פותר מרווחים סותרים מסשנים של סנכרון שחולקו מחדש לקטגוריות. הוא גם מסנכרן פעילות שמתועדת בו-זמנית בכמה מכשירים, כמו שעון וטלפון.
ההתאמה פותרת סשנים סותרים על ידי בחירת הרשומה המוסמכת במקום ליצור איחוד זמן מלאכותי. לדוגמה, הוא לא ממזג את 11:00:00Z עד 11:30:00Z ואת 11:20:00Z עד 11:50:00Z לטווח 11:00:00Z עד 11:50:00Z. התגובה המותאמת מחזירה את הנקודה על הגרף שזכתה עם המרווח המקורי שתועד. כך נשמרת התקינות של נתוני הטלמטריה והמדדים שנמדדו באותו סשן.
באיור 3 מוצג איך נקודת הקצה reconcile מטפלת בסשנים חופפים.
הוא בוחר את הרשומה המוסמכת במקום ליצור איחוד זמן מלאכותי.
במדריך לנקודות הקצה (endpoints) יש דוגמאות מלאות לבקשות ולתגובות. כדי להשוות בין רשומות גולמיות של list לבין פלט של reconcile, קראו את המאמר קבלת תצוגה מותאמת של נתוני מרווחים.
נקודת הקצה (endpoint) של list מיועדת למצב החומרה במכשיר ולביקורת נתונים. השתמשו בה אם תהליך העבודה שלכם דורש בדיקה של רשומות שלא השתנו, כפי שהועלו על ידי כל מכשיר. כששולחים שאילתה באמצעות list, הלוגיקה של הלקוח צריכה לטפל בכל חפיפה בין מרווחים בנתונים הגולמיים.
יכולת שינוי של חותמת הזמן ועדכוני בעלים
מכשירים מחוברים לא משנים באופן רטרואקטיבי חותמות זמן שמאוחסנות במהלך מחזורי סנכרון רגילים. עם זאת, חותמות זמן של מרווחים (startTime ו-endTime במטענים ייעודיים (payloads) של REST JSON, או start_time ו-end_time בביטויי סינון וב-gRPC) לא תמיד ניתנות לשינוי בכל מקורות הנתונים. רק היוצר או הבעלים המקוריים של רשומה יכולים לשנות את השדות שלה. אפליקציות אחרות לא יכולות לערוך נקודות על הגרף שהן לא יצרו.
אפליקציה שהיא בעלים יכולה להשתמש בנקודת הקצה patch כדי לעדכן את הרשומות הקיימות שלה. זה כולל שינוי של חותמות הזמן של ההתחלה או הסיום, שמעדכן גם את השדות של שעון UTC (startTime ו-endTime) וגם את השדות של השעון האזרחי (civilStartTime ו-civilEndTime) בשרת. דוגמה לעדכון חותמות זמן באמצעות PATCH מופיעה בקטע עדכון חותמות זמן של מרווחים לנתונים קיימים במדריך לנקודות קצה.
באופן דומה, נקודות על הגרף שמסונכרנות מפלטפורמות חיצוניות כמו Health Connect או אפליקציות של שותפים מקבלות עדכונים מהמקור המקורי. אם Health Connect מקבלת עדכון לרשומה מסונכרנת מאפליקציית הצד השלישי המקורית, השינויים האלה מועברים ומשכתבים את הרשומה הקיימת.