Ce guide explique comment implémenter la synchronisation incrémentielle des données d'agenda. Cette méthode vous permet de synchroniser les données de toutes les collections d'agendas tout en économisant de la bande passante.
Sommaire
Présentation
La synchronisation incrémentielle comprend deux étapes :
Synchronisation complète initiale : effectuée une seule fois au début pour synchroniser complètement l'état du client avec l'état du serveur. Le client obtient un jeton de synchronisation qu'il doit conserver.
Synchronisation incrémentielle : effectuée de manière répétée pour mettre à jour le client avec toutes les modifications apportées depuis la synchronisation précédente. Chaque fois, le client fournit le jeton de synchronisation précédent obtenu auprès du serveur et stocke le nouveau jeton de synchronisation de la réponse.
Synchronisation complète initiale
La synchronisation complète initiale est la requête d'origine pour toutes les ressources de la collection que vous souhaitez synchroniser. Vous pouvez éventuellement limiter la requête de liste à l'aide de paramètres de requête si vous ne souhaitez synchroniser qu'un sous-ensemble spécifique de ressources.
Dans la réponse à l'opération de liste, la réponse contient un champ nommé nextSyncToken représentant un jeton de synchronisation. Vous devez stocker la valeur de nextSyncToken. Si l'ensemble de résultats est trop volumineux et que la réponse est
paginée, le nextSyncToken
champ n'est présent que sur la dernière page.
Synchronisation incrémentielle
La synchronisation incrémentielle vous permet de récupérer toutes les ressources qui ont été modifiées depuis la dernière requête de synchronisation. Pour ce faire, effectuez une requête de liste avec votre jeton de synchronisation le plus récent spécifié dans le champ syncToken.
N'oubliez pas que le résultat contient toujours les entrées supprimées, afin que les clients puissent les supprimer du stockage.
Si un grand nombre de ressources ont été modifiées depuis la dernière requête de synchronisation incrémentielle, vous pouvez trouver un pageToken au lieu d'un syncToken dans le résultat de la liste. Dans ce cas, effectuez la même requête de liste que celle utilisée pour récupérer la première page de la synchronisation incrémentielle (avec le même syncToken), ajoutez-y le pageToken, puis parcourez les requêtes suivantes jusqu'à ce que vous trouviez un autre syncToken sur la dernière page. Stockez ce syncToken pour la prochaine requête de synchronisation.
Les exemples suivants montrent une synchronisation incrémentielle paginée :
Requête d'origine
GET /calendars/primary/events?maxResults=10&singleEvents=true&syncToken=CPDAlvWDx70CEPDAlvWDx
Le résultat contient les éléments suivants :
{
"nextPageToken": "CiAKGjBpNDd2Nmp2Zml2cXRwYjBpOXA"
}
Récupération de la page suivante
GET /calendars/primary/events?maxResults=10&singleEvents=true&syncToken=CPDAlvWDx70CEPDAlvWDx&pageToken=CiAKGjBpNDd2Nmp2Zml2cXRwYjBpOXA
Synchronisation complète requise par le serveur
Le serveur invalide parfois les jetons de synchronisation en raison de leur expiration ou de modifications apportées aux LCA associées. Dans ce cas, le serveur répond à une requête incrémentielle avec le code d'état HTTP 410. Lorsque cela se produit, effacez le stockage du client et effectuez une nouvelle synchronisation complète.
Exemple de code
L'exemple suivant montre comment utiliser des jetons de synchronisation avec la
bibliothèque cliente Java. La première fois que la méthode run() est appelée, elle effectue une synchronisation complète et stocke le jeton de synchronisation.
Lors de chaque exécution suivante, elle charge le jeton de synchronisation enregistré et effectue une synchronisation incrémentielle.
private static void run() throws IOException { // Construct the {@link Calendar.Events.List} request, but don't execute it yet. Calendar.Events.List request = client.events().list("primary"); // Load the sync token stored from the last execution, if any. String syncToken = syncSettingsDataStore.get(SYNC_TOKEN_KEY); if (syncToken == null) { System.out.println("Performing full sync."); // Set the filters you want to use during the full sync. Sync tokens aren't compatible with // most filters, but you may want to limit your full sync to only a certain date range. // In this example we are only syncing events up to a year old. Date oneYearAgo = Utils.getRelativeDate(java.util.Calendar.YEAR, -1); request.setTimeMin(new DateTime(oneYearAgo, TimeZone.getTimeZone("UTC"))); } else { System.out.println("Performing incremental sync."); request.setSyncToken(syncToken); } // Retrieve the events, one page at a time. String pageToken = null; Events events = null; do { request.setPageToken(pageToken); try { events = request.execute(); } catch (GoogleJsonResponseException e) { if (e.getStatusCode() == 410) { // A 410 status code, "Gone", indicates that the sync token is invalid. System.out.println("Invalid sync token, clearing event store and re-syncing."); syncSettingsDataStore.delete(SYNC_TOKEN_KEY); eventDataStore.clear(); run(); } else { throw e; } } List<Event> items = events.getItems(); if (items.size() == 0) { System.out.println("No new events to sync."); } else { for (Event event : items) { syncEvent(event); } } pageToken = events.getNextPageToken(); } while (pageToken != null); // Store the sync token from the last request to be used during the next execution. syncSettingsDataStore.set(SYNC_TOKEN_KEY, events.getNextSyncToken()); System.out.println("Sync complete."); }
Synchronisation héritée
Pour les collections d'événements, vous pouvez effectuer une synchronisation héritée en enregistrant la
valeur du champ updated à partir d'une requête de liste d'événements, puis en utilisant le
updatedMin champ pour récupérer les événements mis à jour. Cette approche n'est plus recommandée, car elle est plus sujette aux erreurs (par exemple, elle n'applique pas les restrictions de requête) et n'est disponible que pour les événements.