Utiliser la bibliothèque cliente JavaScript (v2.0)

Avertissement : Cette page concerne les anciennes API Google, les API Google Data. Elle ne concerne que les API répertoriées dans l'annuaire des API Google Data, dont la plupart ont été remplacées par de nouvelles API. Pour en savoir plus sur une nouvelle API spécifique, consultez sa documentation. Pour en savoir plus sur l'autorisation des requêtes avec une API plus récente, consultez Authentification et autorisation des comptes Google.

Ce document explique comment utiliser la bibliothèque cliente JavaScript pour envoyer des requêtes à l'API Google Data et interpréter les réponses renvoyées.

Google fournit un ensemble de bibliothèques clientes, dans différents langages de programmation, pour interagir avec des services dotés d'API de données. Ces bibliothèques vous permettent de créer des requêtes API, de les envoyer à un service et de recevoir des réponses.

Ce document fournit des informations générales sur l'utilisation de la bibliothèque cliente JavaScript, ainsi qu'un ensemble d'exemples d'utilisations courantes.

Audience

Ce document est destiné aux programmeurs JavaScript qui souhaitent créer des applications clientes capables d'interagir avec les services Google Data.

Dans ce document, nous partons du principe que vous comprenez les principes généraux du protocole Google Data APIs. Nous supposons également que vous savez programmer dans JavaScript.

Pour en savoir plus sur les classes et les méthodes fournies par la bibliothèque cliente, consultez la documentation de référence de l'API de la bibliothèque cliente JavaScript (au format JSdoc).

Ce document est conçu pour être lu dans l'ordre. Chaque exemple s'appuie sur des exemples précédents.

Conditions d'utilisation

Vous vous engagez à respecter les Conditions d'utilisation de la bibliothèque cliente JavaScript lorsque vous utilisez cette bibliothèque.

Présentation du modèle de données et du flux de contrôle

La bibliothèque cliente JavaScript utilise un ensemble de classes pour représenter les éléments utilisés par les API Google Data.

Remarque : La représentation sous-jacente des données est au format JSON, mais la bibliothèque cliente fournit une couche d'abstraction pour que vous n'ayez pas à travailler directement avec les données JSON. Si vous souhaitez travailler directement avec JSON, sans la bibliothèque cliente, consultez Utiliser JSON avec les API Google Data.

La bibliothèque fournit des méthodes qui vous permettent d'envoyer et de recevoir des données de manière asynchrone à partir d'un service disposant d'une API de données. Par exemple, la méthode google.gdata.calendar.CalendarService.getEventsFeed() envoie une requête de flux à Google Agenda. L'un des paramètres que vous transmettez est une fonction de continuation, également appelée rappel. Le service renvoie le flux au format JSON en appelant la fonction de continuation. Le client peut ensuite appeler diverses méthodes get pour utiliser les données sous la forme d'objets JavaScript.

Pour ajouter une entrée, vous devez la créer à l'aide des classes et des méthodes de la bibliothèque cliente, puis appeler la méthode feed.insertEntry() pour envoyer la nouvelle entrée au service. Là encore, vous fournissez une fonction de continuation, que le service appelle lorsque l'entrée a bien été ajoutée.

Si vous débutez avec JavaScript, le flux de contrôle peut être un peu déroutant. Après avoir appelé une méthode telle que getEventsFeed() ou insertEntry(), votre script se termine généralement. L'exécution reprend dans la fonction de continuation lorsque le service renvoie les données demandées. Par conséquent, toute action effectuée par votre client sur les données renvoyées doit être effectuée dans la fonction de continuation, ou appelée à partir de cette fonction. Vous devrez peut-être rendre certaines variables globales pour les utiliser dans plusieurs fonctions.

Pour en savoir plus sur ce style de programmation, consultez l'article Wikipédia Continuation-passing style.

À propos des environnements compatibles

Actuellement, nous n'acceptons que les applications clientes JavaScript qui s'exécutent sur une page Web dans un navigateur. Les navigateurs actuellement compatibles sont les suivants:

  • Firefox 2.x et 3.x
  • Internet Explorer 6, 7 et 8
  • Safari 3.x et 4.x
  • Google Chrome (toutes les versions)

La bibliothèque cliente JavaScript gère toutes les communications avec le serveur du service. Si vous êtes un développeur JS expérimenté, vous pensez peut-être : "Mais qu'en est-il de la même règle d'origine ? La bibliothèque cliente JavaScript permet à votre client d'envoyer des requêtes de données Google à partir de n'importe quel domaine tout en respectant le modèle de sécurité du navigateur.

Pour en savoir plus sur l'authentification avec les API Google Data, consultez la présentation de l'authentification des API Google Data. Dans la suite de ce document, nous partons du principe que vous connaissez les principes de base de ce système.

Exemples d'applications clientes

Pour voir une démonstration de la bibliothèque cliente JavaScript en action, consultez nos exemples de page.

Tutoriel et exemples

Les exemples suivants montrent comment envoyer diverses requêtes API de données à l'aide de la bibliothèque cliente JavaScript.

Pour les rendre plus concrets, ces exemples montrent comment interagir avec un service spécifique: Google Agenda. Nous allons indiquer les endroits où Agenda diffère des autres services Google afin de vous aider à adapter ces exemples pour les utiliser avec d'autres services. Pour en savoir plus sur Google Agenda, consultez le document API Google Calendar Data.

Charger la bibliothèque

Pour que votre client puisse utiliser la bibliothèque cliente, il doit en demander le code au serveur.

Commencez par utiliser une balise <script> dans la section <head> de votre document HTML pour récupérer le chargeur d'API Google AJAX:

<script type="text/javascript" src="https://www.google.com/jsapi"></script>

Vous pouvez minimiser les allers-retours vers les serveurs de Google et réduire la latence en préchargeant la bibliothèque. Pour précharger certains packages directement à partir du chargeur d'API Google AJAX (sans utiliser google.load()), consultez la section ci-dessous:

<script type="text/javascript"
      src="https://www.google.com/jsapi?autoload=%7Bmodules%3A%5B%7Bname%3Agdata%2Cversion%3A2.x%2Cpackages%3A%5Bblogger%2Ccontacts%5D%7D%5D%7D"></script>

Remarque: L'URL src du script doit être entièrement encodée. Par exemple, l'exemple précédent est
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={modules:[{name:gdata,version:2.x,packages:[blogger,contacts]}]}"></script>.

Si vous ne chargez pas les modules automatiquement, vous pouvez charger la bibliothèque cliente Google Data en utilisant l'exemple suivant dans votre code de configuration JavaScript, après avoir récupéré le chargeur commun. Cet appel doit être effectué depuis la section <head> de votre document HTML (ou depuis un fichier JavaScript inclus à l'aide d'une balise <script> dans la section <head> de votre document HTML):

google.load("gdata", "2");

Vous pouvez également demander des services spécifiques au lieu de la bibliothèque entière. Dans cet exemple, seuls les packages Blogger et Contacts sont téléchargés:

google.load("gdata", "2.x", {packages: ["blogger", "contacts"]});

Le deuxième paramètre de google.load() est le numéro de version demandé de la bibliothèque cliente JavaScript.Le schéma de numérotation des versions est basé sur celui de l'API Google Maps. Voici les numéros de version possibles et leur signification:

"1"
avant-dernière révision de la version majeure 1.
"1.x"
Dernière révision de la version majeure 1.
"1.s"
Dernière révision stable de la version majeure 1. Nous déclarons parfois qu'une certaine version de la bibliothèque cliente est "stable", en fonction des commentaires que nous recevons des développeurs. Toutefois, il est possible qu'elle ne dispose pas des dernières fonctionnalités.
"1.0", "1.1", etc.
Version spécifique de la bibliothèque, avec un numéro de révision principal et mineur spécifié.

Après avoir appelé google.load(), vous devez demander au chargeur d'attendre la fin du chargement de la page, puis d'appeler votre code:

google.setOnLoadCallback(getMyFeed);

getMyFeed() est une fonction définie dans la section suivante de ce document. Utilisez cette approche plutôt que d'associer un gestionnaire onload à l'élément <body>.

Demander un flux non authentifié

Pour demander un flux non authentifié, ajoutez le code suivant à votre fichier JavaScript ou à une balise <script> de votre fichier HTML.

Dans le code suivant, getMyFeed() est appelé en premier (par le chargeur d'API AJAX, comme décrit dans la section précédente).

Elle appelle setupMyService() pour créer une connexion (représentée par un objet CalendarService) à Google Agenda. Nous avons extrait le code de création de services dans une fonction distincte pour la modularité. Nous modifierons ultérieurement la fonction setupMyService() en fonction de vos choix d'authentification.

Après avoir configuré le service, getMyFeed() appelle la méthode getEventsFeed() de la bibliothèque cliente pour demander le flux.

Nous indiquons une URL de flux dans une variable globale afin de pouvoir l'utiliser ultérieurement. Dans cet exemple, nous utilisons l'URL du flux public (non authentifié) pour un utilisateur nommé liz@gmail.com. Vous pouvez également utiliser default à la place de l'adresse e-mail de l'utilisateur pour représenter l'utilisateur authentifié.

var feedUrl = "http://www.google.com/calendar/feeds/liz@gmail.com/public/full";

function setupMyService() {
  var myService = new google.gdata.calendar.CalendarService('exampleCo-exampleApp-1');
  return myService;
}

function getMyFeed() {
  myService = setupMyService();

  myService.getEventsFeed(feedUrl, handleMyFeed, handleError);
}

Notez que nous faisons de myService une variable globale, pour faciliter son utilisation dans les fonctions suivantes.

Pour que le code ci-dessus fonctionne dans votre propre client, vous devez utiliser l'adresse e-mail d'un utilisateur réel pour un compte Agenda avec un agenda partagé publiquement.

Remarque: Lorsque vous créez un objet CalendarService, la bibliothèque cliente appelle une méthode nommée google.gdata.client.init(), qui vérifie que le navigateur dans lequel le client est exécuté est compatible. Si une erreur se produit, la bibliothèque cliente affiche un message d'erreur à l'utilisateur. Si vous souhaitez gérer ce type d'erreur vous-même, vous pouvez appeler explicitement google.gdata.client.init(handleInitError) avant de créer le service, où handleInitError() est votre fonction. Si une erreur d'initialisation se produit, votre fonction reçoit un objet Error standard. Vous pouvez faire ce que vous voulez avec cet objet.

Dans l'appel de getEventsFeed(), le deuxième argument est handleMyFeed, qui est une fonction de rappel (voir ci-dessous). Google Agenda traite la demande, puis, si la demande aboutit, transmet un objet "flux racine" contenant le flux demandé au rappel. Une racine de flux est un objet conteneur qui contient un flux.

Le troisième argument de getEventsFeed() est une fonction facultative de gestion des erreurs. Si la bibliothèque cliente rencontre une erreur, elle appelle le gestionnaire d'erreurs spécifié au lieu de la fonction de rappel de réussite. L'objet que la bibliothèque cliente transmet en tant qu'argument au gestionnaire d'erreurs est une instance de l'objet Error JavaScript, avec une propriété cause supplémentaire.

Voici des versions simples de la fonction de rappel et du gestionnaire d'erreurs:

function handleMyFeed(myResultsFeedRoot) {
  alert("This feed's title is: " + myResultsFeedRoot.feed.getTitle().getText());
}

function handleError(e) {
  alert("There was an error!");
  alert(e.cause ? e.cause.statusText : e.message);
}

Nous traitons les erreurs en les présentant simplement à l'utilisateur. Le gestionnaire d'erreurs de votre client devrait être plus sophistiqué. Dans certains contextes, aucune cause n'est indiquée. Dans ce cas, notre gestionnaire d'erreurs revient à afficher la propriété message standard.

Comme ce code ne s'authentifie pas, vous ne pouvez l'utiliser que pour obtenir un flux public.

Authentification

La bibliothèque cliente JavaScript peut être utilisée dans deux modes. Si vous écrivez un gadget, il utilise une fonctionnalité appelée proxy OAuth pour l'authentification. S'il est utilisé depuis une application JavaScript autonome, il utilise le système d'authentification AuthSub. Pour en savoir plus sur l'authentification, consultez le document Présentation de l'authentification des API Google Data. Dans la suite de cette section, nous partons du principe que vous connaissez les principes de base de ce système.

Avant d'utiliser l'authentification avec l'exemple de code fourni dans ce document, remplacez l'URL du flux de publique par privée:

var feedUrl = "http://www.google.com/calendar/feeds/liz@gmail.com/private/full";

S'authentifier dans un client Web avec AuthSub

Le système d'autorisation "AuthSub pour JavaScript" de Google n'est plus disponible.

Nous vous recommandons plutôt d'utiliser OAuth 2.0 pour les applications côté client.

Authentification dans un gadget avec le proxy OAuth

Voici un bref aperçu du processus d'authentification d'un gadget:

  1. Votre gadget se charge pour la première fois et tente d'accéder aux données de l'utilisateur à l'aide de l'une des API de données Google.
  2. La requête échoue, car l'utilisateur n'a pas encore autorisé l'accès à ses données. L'objet de la réponse contient une URL (en response.oauthApprovalUrl) pour la page d'approbation OAuth. Votre gadget doit fournir une méthode pour lancer une nouvelle fenêtre avec cette URL.
  3. Sur la page d'approbation, l'utilisateur choisit d'accorder ou de refuser l'accès à votre gadget. Si l'opération réussit, l'utilisateur est redirigé vers la page oauth_callback que vous spécifiez. Pour une expérience utilisateur optimale, utilisez http://oauth.gmodules.com/gadgets/oauthcallback.
  4. L'utilisateur ferme ensuite la fenêtre pop-up. Pour vous aider à notifier votre gadget que l'utilisateur a donné son approbation, nous avons fourni un gestionnaire de pop-ups que vous pouvez utiliser pour détecter la fermeture de la fenêtre d'approbation. Votre gadget peut également afficher un lien (par exemple, J'ai approuvé l'accès) pour que l'utilisateur puisse cliquer manuellement après la fermeture de cette fenêtre.
  5. Votre gadget tente à nouveau d'accéder à l'API de données Google en redemandant les données de l'utilisateur. Cette tentative a réussi.
  6. Votre gadget est authentifié et peut fonctionner normalement.

Dans votre gadget, ajoutez un élément <OAuth> dans la section <ModulePrefs>:

<ModulePrefs>
...
<OAuth>
  <Service name="google">
    <Access url="https://www.google.com/accounts/OAuthGetAccessToken" method="GET" /> 
    <Request url="https://www.google.com/accounts/OAuthGetRequestToken?
                  scope=http://www.blogger.com/feeds/%20http://www.google.com/calendar/feeds/" method="GET" /> 
    <Authorization url="https://www.google.com/accounts/OAuthAuthorizeToken?
                        oauth_callback=http://oauth.gmodules.com/gadgets/oauthcallback" /> 
  </Service>
</OAuth>
...
</ModulePrefs>

Dans cette section, modifiez les paramètres de requête suivants:

  • scope

    Un paramètre obligatoire dans l'URL de la requête. Votre gadget pourra uniquement accéder aux données du ou des scope utilisés dans ce paramètre. Dans cet exemple, le gadget accède à vos données Blogger et Agenda. Un gadget peut demander des données pour un seul ou plusieurs champs d'application (comme le montre cet exemple).

  • oauth_callback

    Paramètre facultatif de l'URL d'autorisation. La page d'approbation OAuth redirigera l'utilisateur vers cette URL une fois que l'utilisateur aura approuvé l'accès à ses données. Vous pouvez ignorer ce paramètre, le définir sur votre propre "page approuvée" ou utiliser de préférence http://oauth.gmodules.com/gadgets/oauthcallback. La version ultérieure offre la meilleure expérience utilisateur lorsque les utilisateurs installent votre gadget pour la première fois. Cette page fournit un extrait de code JavaScript qui ferme automatiquement la fenêtre pop-up.

Chargez ensuite la bibliothèque cliente JavaScript dans la section <Content> de votre gadget. Modifiez la fonction setupMyService() des exemples précédents pour appeler la méthode useOAuth() de l'objet de service. Cela indique au gadget d'utiliser le proxy OAuth pour s'authentifier plutôt que AuthSub. Le modèle ci-dessous doit vous aider à démarrer:

<Content type="html">
<![CDATA[
  ...
  <script src="https://www.google.com/jsapi"></script>
  <script type="text/javascript">
    var myService = null;
    
    function setupMyService() {
      myService = new google.gdata.calendar.CalendarService('exampleCo-exampleApp-1');
      myService.useOAuth('google');
      fetchData();
    }
    
    function initGadget() {
      google.load('gdata', '2.x');
      google.setOnLoadCallback(setupMyService);
    }

    function fetchData() {            
      var callback = function(response) {
        if (response.oauthApprovalUrl) {
        
          // TODO: Display "Sign in" link (response.oauthApprovalUrl contains the URL) 
          
        } else if (response.feed) {
        
          // TODO: show results
          
        } else {
        
          // TODO: handle the error
          
        }
      };

      myService.getEventsFeed('http://www.google.com/calendar/feeds/default/public/full', callback, callback);
    }
    
    gadgets.util.registerOnLoadHandler(initGadget);
  </script>
  ...
]]> 
</Content>

Notez que l'appel de google.accounts.user.login(scope) a été supprimé. Le proxy gère l'authentification à votre place.

Pour plus d'informations sur l'écriture de gadgets pour l'API Google Data, y compris des informations sur le contenu que fetchData() doit contenir, consultez notre article sur la création d'un gadget de données Google ou consultez la documentation complète sur l'écriture de gadgets OAuth.

Insérer un nouvel élément

Pour créer un événement d'agenda, poursuivez l'exécution de l'exemple précédent en modifiant la fin de la fonction handleMyFeed() pour appeler une nouvelle fonction:

function handleMyFeed(myResultsFeedRoot) {
  alert("This feed's title is: " + myResultsFeedRoot.feed.getTitle().getText());
  insertIntoMyFeed(myResultsFeedRoot);
}

Dans la nouvelle fonction, commencez par utiliser le constructeur CalendarEventEntry pour créer la nouvelle entrée. Insérez ensuite l'entrée en fournissant un rappel que le service appelle une fois l'insertion terminée.

function insertIntoMyFeed(feedRoot) {
  var newEntry = new google.gdata.calendar.CalendarEventEntry({
      authors: [{
        name: "Elizabeth Bennet",
        email: "liz@gmail.com"
      }],
      title: {
        type: 'text', 
        text: 'Tennis with Darcy'
      },
      content: {
        type: 'text', 
        text: 'Meet for a quick lesson'
      },
      locations: [{
        rel: "g.event",
        label: "Event location",
        valueString: "Netherfield Park tennis court"
      }],
      times: [{
        startTime: google.gdata.DateTime.fromIso8601("2007-09-23T18:00:00.000Z"),
        endTime: google.gdata.DateTime.fromIso8601("2007-09-23T19:00:00.000Z")
      }]
  });
  feedRoot.feed.insertEntry(newEntry, handleMyInsertedEntry, handleError);
}

Notez que le nom de chaque propriété d'objet utilisée dans le constructeur correspond au nom de la méthode "setter" utilisée pour cette propriété. (Par exemple, il ne doit pas correspondre au nom du champ JSON correspondant.

Notez également que vous ne pouvez pas vous contenter de fournir des chaînes de date et heure ISO 8601 pour startTime et endTime. Vous devez d'abord exécuter ces chaînes via la méthode fromIso8601().

Le service renvoie une copie de l'entrée insérée en tant qu'objet entryRoot et transmet cet objet au rappel:

function handleMyInsertedEntry(insertedEntryRoot) {
  alert("Entry inserted. The title is: " + insertedEntryRoot.entry.getTitle().getText());
  alert("The timestamp is: " + insertedEntryRoot.entry.getTimes()[0].startTime);
}

Demander une entrée spécifique

Pour demander une entrée spécifique, commencez par modifier la fonction handleMyInsertedEntry() afin d'appeler une nouvelle fonction de requête d'entrée:

function handleMyInsertedEntry(insertedEntryRoot) {
  alert("Entry inserted. The title is: " + insertedEntryRoot.entry.getTitle().getText());
  alert("The timestamp is: " + insertedEntryRoot.entry.getTimes()[0].startTime);
  requestMySpecificEntry(insertedEntryRoot.entry.getSelfLink().getHref());
}

Le code suivant vous permet de demander l'entrée spécifique que vous avez insérée dans l'exemple précédent.

Dans le contexte de cette série d'exemples, il n'est pas nécessaire de récupérer cette entrée, car Agenda a déjà renvoyé l'entrée insérée. Toutefois, la même technique peut être appliquée chaque fois que vous connaissez l'URI d'une entrée.

function requestMySpecificEntry(entryURI) {
  myService.getEventsEntry(entryURI, handleMySpecificEntry, handleError);
}

function handleMySpecificEntry(retrievedEntryRoot) {
  myEntryRoot = retrievedEntryRoot; // Global variable for later use
  alert("This entry's title is: " + retrievedEntryRoot.entry.getTitle().getText());
}

Cet exemple est essentiellement le même que getEventsFeed(), sauf que nous appelons la méthode getEventEntry() du service pour obtenir une entrée spécifique et que l'URI est un peu différent. Il utilise "default" pour désigner l'agenda principal de l'utilisateur authentifié, et se trouve à la fin d'un ID d'entrée.

De plus, nous devons pouvoir utiliser l'entrée récupérée plus tard. Nous la copions donc dans une variable globale.

Rechercher des entrées

Pour effectuer une recherche en texte intégral, commencez par modifier la fonction handleMySpecificEntry() afin d'appeler une nouvelle fonction de recherche:

function handleMySpecificEntry(retrievedEntryRoot) {
  myEntryRoot = retrievedEntryRoot; // Global variable for later use
  alert("This entry's title is: " + retrievedEntryRoot.entry.getTitle().getText());
  searchMyFeed();
}

Ensuite, pour extraire la première correspondance de la recherche, utilisez le code suivant:

function searchMyFeed() {
  var myQuery = new google.gdata.calendar.CalendarEventQuery(feedUrl);
  myQuery.setFullTextQuery("Tennis");
  myQuery.setMaxResults(10);
  myService.getEventsFeed(myQuery, handleMyQueryResults, handleError);
}

function handleMyQueryResults(myResultsFeedRoot) {
  if (myResultsFeedRoot.feed.getEntries()[0]) {
    alert("The first search-match entry's title is: " + myResultsFeedRoot.feed.getEntries()[0].getTitle().getText());
  }
  else {
    alert("There are no entries that match the search query.");
  }
}

Mettre à jour un élément

Pour mettre à jour un élément existant, commencez par ajouter une ligne à la fin de handleMyQueryResults() pour appeler une nouvelle fonction de mise à jour:

  updateMyEntry();

Utilisez ensuite le code suivant. Dans cet exemple, nous remplaçons le titre de l'entrée précédemment récupérée (qui était contenue dans l'objet global nommé myEntryRoot dans un exemple précédent) de son ancien texte ("Tennis avec Darcy") en "Réunion importante".

function updateMyEntry() {
  myEntryRoot.entry.getTitle().setText("Important meeting");
  myEntryRoot.entry.updateEntry(handleMyUpdatedEntry, handleError);
}

function handleMyUpdatedEntry(updatedEntryRoot) {
  alert("Entry updated. The new title is: " + updatedEntryRoot.entry.getTitle().getText());
}

Comme avec toutes les méthodes d'Agenda, la méthode updateEntry() détermine automatiquement l'URI de modification à utiliser pour mettre à jour l'entrée. Vous n'avez donc pas à fournir cet URI explicitement.

Suppression d'un élément

Pour supprimer l'entrée mise à jour, ajoutez d'abord une ligne à handleMyUpdatedEntry():

 deleteMyEntry(updatedEntryRoot);

Utilisez ensuite le code suivant:

function deleteMyEntry(updatedEntryRoot) {
  updatedEntryRoot.entry.deleteEntry(handleMyDeletedEntry, handleError);
}

function handleMyDeletedEntry() {
  alert("Entry deleted");
}

Là encore, la méthode deleteEntry() détermine automatiquement l'URI de modification à utiliser pour supprimer l'entrée.

Notez qu'aucune entrée n'est renvoyée. Si le rappel est appelé, nous savons que la suppression a réussi. Si la suppression échoue, deleteEntry() appelle handleError() au lieu d'appeler handleMyDeletedEntry().

Utiliser les ETags

Remarque : Les ETag ne peuvent être utilisés qu'avec des services exécutant le protocole Google Data Protocol v2.0.

Introduction

La version 2 du client JavaScript Google Data est compatible avec les ETags. Les ETag sont des identifiants qui spécifient une version particulière d'une entrée particulière. C'est important dans deux cas:

  • Effectuer une "récupération conditionnelle" au cours de laquelle un client demande une entrée, et le serveur ne l'envoie que si celle-ci a été modifiée depuis sa dernière demande.
  • Assurez-vous que plusieurs clients ne remplacent pas les modifications d'un autre utilisateur par inadvertance. Pour ce faire, les API Data mettent à jour et suppriment les données si le client spécifie un ancien ETag pour l'entrée.

Il existe deux types d'ETags: faibles et forts. Un ETag faible commence toujours par W/, par exemple : W/"D08FQn8-eil7ImA9WxZbFEw". Il n'est pas garanti que les ETags faibles changent lors de la modification de l'entrée. C'est pourquoi le protocole HTTP ne permet de les utiliser que pour la récupération conditionnelle. Les ETag solides identifient une version spécifique d'une entrée spécifique et peuvent être utilisés à la fois pour la récupération conditionnelle et lors des mises à jour ou des suppressions afin d'éviter d'écraser les modifications d'autres clients. En raison de cette distinction, la bibliothèque cliente ne vous permet pas d'envoyer des ETag faibles avec une demande de mise à jour ou de suppression.

Les ETags se trouvent à deux emplacements dans la réponse du serveur:

  • Dans l'en-tête HTTP ETag.
  • Dans le flux ou en tant qu'entrée, en tant qu'attribut gd:etag

Si un service est compatible avec la version 2, chaque flux et chaque objet d'entrée disposent d'une méthode getEtag() pour récupérer la valeur de l'ETag.

Le client JavaScript prend en charge deux méthodes pour inclure des ETag avec une requête. Le premier est le nouvel objet opt_params. Toutes les fonctions get/update/insert de la version 2 de la bibliothèque cliente disposent d'un nouveau paramètre opt_params. Cet objet permet de spécifier des paramètres facultatifs lors de l'envoi d'une requête. Pour le moment, 'etag' est le seul paramètre facultatif accepté (bien que d'autres paramètres puissent être introduits ultérieurement). Par exemple, vous pouvez ajouter un ETag à une requête GET comme suit:

var opt_params = {};
opt_params['etag'] = 'ETAG GOES HERE';
service.getFeed(uri, successHandler, errorHandler, opt_params);

Vous pouvez également ajouter un ETag directement à un flux ou à un objet d'entrée en appelant la méthode setEtag() sur le flux ou l'entrée.

Pour en savoir plus sur les ETags, consultez la documentation de référence du protocole GData.

Utiliser les ETags pour récupérer les données

Les ETag peuvent contribuer à réduire la bande passante et le temps d'exécution lors de la récupération de données. Un ETag peut être inclus dans une requête GET avec If-None-Match header:

If-None-Match: ETAG GOES HERE

Si l'ETag correspond à la version actuelle du flux ou de l'entrée, le serveur renvoie une réponse 304 NOT MODIFIED et un corps vide. Sinon, le serveur renvoie une réponse 200 OK et les données de flux ou d'entrée.

Vous pouvez utiliser des ETag dans le client JavaScript en incluant un paramètre 'etag' lorsque vous effectuez la requête:

var etag = feed.getEtag(); // Feed loaded from a previous request
var opt_params = {};
opt_params['etag'] = etag;
service.getFeed(feedUrl, successHandler, errorHandler, opt_params);

Les récupérations conditionnelles fonctionnent avec des ETag forts et faibles. Si l'ETag est une correspondance, le gestionnaire d'erreurs est appelé avec une réponse 304:

function successHandler(feedRoot) {
  // 200 response
  // Update UI to display updates
}

function errorHandler(errorObj) {
  if (errorObj.cause.getStatus() == 304) {
    // 304 response, do nothing
  }
  // otherwise the response is some other error
}

Consultez l'exemple Récupération conditionnelle avec Blogger pour voir un exemple plus pratique d'utilisation des ETags dans le client JavaScript. Cet exemple interroge Blogger à intervalles de cinq secondes à la recherche de mises à jour. En cas de modifications, l'exemple met à jour une liste de posts.

Mettre à jour et supprimer des données à l'aide des ETag

L'utilisation d'ETag dans les requêtes de mise à jour/suppression permet à plusieurs clients de ne pas écraser accidentellement les modifications d'un autre utilisateur. Dans ce cas, un ETag est inclus avec l'en-tête If-Match:

If-Match: ETAG GOES HERE

Si l'ETag dans la requête correspond à l'ETag sur le serveur, la mise à jour/suppression aboutit. Cependant, un ETag incohérent indique que l'entrée a changé et que la mise à jour/la suppression échoue. Dans ce cas, l'application doit demander une nouvelle instance des données, puis relancer la mise à jour/la suppression.

Dans certains cas, vous souhaiterez peut-être forcer vos modifications, quelles que soient les autres modifications apportées à l'entrée. Pour ce faire, transmettez un * à l'en-tête If-Match:

If-Match: *

N'oubliez pas que cette opération remplace les modifications apportées par d'autres clients. Utilisez donc cette option avec précaution.

Vous ne pouvez mettre à jour/supprimer qu'une entrée dont l'ETag est fort. Si vous spécifiez un ETag faible, une erreur sera générée. Pour se prémunir contre cette situation, le client JavaScript ne définit pas de ETags faibles lors des demandes de mise à jour et de suppression.

Les ETag sont utilisés de la même manière que les récupérations conditionnelles:

function updateData(entry, service) {
  var etag = entry.getEtag();
  var opt_params = {};
  opt_params['etag'] = etag; // Or use '*' to force an update.
  service.updateEntry(successHandler, errorHandler, opt_params);
}

function successHandler(response) {
  // Successful update
}

function errorHandler(errorObj) {
  // ERROR - Update failed. Could be due to an ETag mismatch, but check the
  // error message to make sure. An ETag error will be in the format:
  // Mismatch: etags = ["Qnc-fTVSLyp7ImA9WxJbFEsDRAw."], version = [1249675665358000]
}

Lorsque vous effectuez des mises à jour, un ETag peut être spécifié à deux endroits:

  1. Dans l'entrée elle-même, à l'aide des méthodes getEtag() et setEtag()
  2. Dans l'en-tête, à l'aide de l'objet opt_params (comme illustré ci-dessus).

Un champ ETag est déjà défini pour une entrée chargée à partir d'une précédente requête GET. Par conséquent, spécifier le même ETag dans l'objet opt_params est redondant. Dans le cas où un ETag est spécifié à la fois dans le corps de l'entrée et dans le opt_params, l'ETag du opt_params prévaut. Cela peut prêter à confusion. Par conséquent, si vous rencontrez des problèmes avec les mises à jour conditionnelles, vérifiez l'ETag dans l'entrée et dans l'objet opt_params.

Pour faciliter les choses, les classes google.gdata.Entry disposent également de leurs propres méthodes updateEntry() et deleteEntry(). Si la classe d'entrée comporte déjà un ETag, vous n'avez pas besoin de l'ajouter à la requête. La bibliothèque cliente le fait automatiquement pour vous. Exemple :

// entry was loaded from a previous request.  No need to specify
// an ETag in opt_params here, it is added automatically.
entry.deleteEntry(successHandler, errorHandler);

Vous bénéficiez ainsi des ETag sans vous soucier de les définir correctement. Toutefois, si vous souhaitez forcer la mise à jour à l'aide de '*', vous devez toujours inclure l'objet opt_params avec 'etag' = '*'.

Vous pouvez voir les modifications conditionnelles en action dans Mises à jour conditionnelles dans Contacts. L'exemple commence par créer un groupe de contacts de test où toutes les données utilisées seront créées. N'hésitez pas à supprimer ce groupe de contacts lorsque vous aurez fini d'utiliser l'exemple. L'exemple charge ensuite deux iFrames avec le contenu du groupe de contacts. Vous pouvez effectuer des mises à jour dans un iFrame et observer leur impact dans l'autre iFrame. Consultez cet exemple pour en savoir plus sur son utilisation.

Exemples

Reference

Pour en savoir plus sur les classes et les méthodes fournies par la bibliothèque cliente, consultez la documentation de référence de l'API de la bibliothèque cliente JavaScript (au format JSdoc).

Haut de page