I. Avant-propos

Dans la partie 1 : environnement de développementTutoriel Backbone.js : environnement de développement, j'ai expliqué comment configurer un serveur Node simple pour héberger votre application Backbone.js et vos tests. La façon dont j'ai utilisé des chemins d'accès relatifs est quelque chose que les gens confondent souvent, c'est-à-dire que les essais peuvent échouer si vous ne visitez pas /test/ (/test ne fonctionnera pas). Il y avait une raison à cela : j'ai développé la version originale pour démarrer la Dropbox, alors j'ai voulu utiliser les chemins d'accès relatifs. Il est probablement plus sûr d'utiliser des chemins absolus, donc je devais éclaircir la chose.

Dans cette partie, vous apprendrez ce qui suit :

  • le fonctionnement de Backbone.sync ;
  • comment charger Backbone.js et Underscore.js avec RequireJS ;
  • comment bien démarrer avec les API Google.

II. La méthode Backbone.sync

L'accès au réseau dans Backbone.js est subtilement abstrait grâce à une méthode unique qui possède la signature suivante :

 
Sélectionnez
Backbone.sync = function(method, model, options) {
 
};

L'argument method contient une chaîne de caractères qui peut être l'une des valeurs suivantes :

  • create ;
  • update ;
  • delete ;
  • read.

En interne, Backbone.js mappe ces noms à des méthodes HTTP :

 
Sélectionnez
var methodMap = {
  'create' : 'POST',
  'update' : 'PUT',
  'delete' : 'DELETE',
  'read':   'GET'
};

Si vous êtes un habitué de l'API RESTful particulièrement agréable, alors elles doivent toutes vous sembler familières.

Le deuxième argument, model, est un Backbone.Model ou une Backbone.Collection. Les collections sont utilisées lors de la lecture des valeurs multiples.

L'argument final, options, est un objet qui contient des callbacks de réussite ou d'erreur. Ceci finalement transmis à l'API Ajax de jQuery.

Pour travailler avec les API Google, nous avons besoin d'écrire notre propre méthode Backbone.sync. De manière générale, notre implémentation devrait être structurée comme suit :

 
Sélectionnez
Backbone.sync = function(method, model, options) {
  switch (method) {
    case 'create':
      googleAPI.create(model, options);
    break;
 
    case 'update' :
      googleAPI.update(model, options);
    break;
 
    case 'delete' :
      googleAPI.destroy(model, options);
    break;
 
    case 'read' :
      // Ici, la valeur de model est une collection
      googleAPI.list(model, options);
    break;
 
    default :
      // Il s'est peut-être produit une erreur
      console.error('Unknown method:', method);
    break;
  }
};

L'objet googleAPI est fictif, mais c'est essentiellement ainsi que Backbone.sync est généralement étendue. Un wrapper léger qui mappe les noms des méthodes et des modèles avec ceux d'une autre API. L'utilisation d'un wrapper signifie que l'API sous-jacente de la cible peut facilement être utilisée à l'extérieur de Backbone.js.

Dans notre cas, Google fournit en fait une API JavaScript. Il y a un objet gapi.client disponible une fois que les API Google ont été chargées.

III. Configuration d'un compte d'API Google

La page d'accueil de la documentation pour les développeurs de Google est developers.google.comhttps://developers.google.com/, mais ce qui nous intéresse est l'APIGoogle TasksAPIGoogle Tasks qui figure dans les API Application.

Les API Application de Google sont conçues pour fonctionner avec les scripts côté serveur et JavaScript côté client. Pour travailler avec l'API Google Tasks, vous aurez besoin de trois choses :

  • un compte Google (un qui existe déjà fera l'affaire) ;
  • l'accès à l'API Google Console (vous l'avez probablement déjà activée si vous travaillez avec des services de Google) ;
  • une clé d'API.

Pour configurer votre compte pour travailler avec l'API Google Console, visitez code.google.com/apis/consolecode.google.com/apis/console. Une fois que vous l'avez activée, faites défiler jusqu'à l'API Tasks :

Image non disponible

Puis passez le bouton à on et acceptez les termes (si vous êtes d'accord). Ensuite, cliquez sur l'API Access dans la barre de navigation de gauche et regardez la clé de l'API au niveau de Simple API Access. Cette clé « d'applications sur navigateur » est ce dont nous avons besoin. Prenez note de celle-ci pour plus tard.

IV. OAuth 2.0 pour les applications côté client

Toujours dans la section API Access de la console, cliquez sur le bouton pour créer un projet OAuth 2.0. Entrez bTask (ou ce que vous voulez) pour le nom du produit, puis http://localhost:8080 pour l'URL. Dans la boîte de dialogue suivante, assurez-vous que http:// est sélectionné au lieu de https://, puis tapez localhost:8080 et cliquez sur "Créer un ID client".

Vous verrez maintenant une série de valeurs sous "ID client pour les applications Web". Le champ qui dit "ID Client" est important. Prenez également note de celui-ci.

Vous devriez maintenant avoir une clé d'API et un ID client. Ils serviront à charger les API Google et à nous permettre d'utiliser un service OAuth 2.0 depuis le navigateur. Nous n'aurons pas besoin d'écrire notre propre code côté serveur pour authentifier les utilisateurs.

V. Rappel

Si vous souhaitez vérifier la source de la partie 1, vous pouvez utiliser Git pour obtenir la révision exacte du tutoriel précédent :

 
Sélectionnez
git clone git@github.com:alexyoung/dailyjs-backbone-tutorial.git
cd dailyjs-backbone-tutorial
git reset --hard 2a8517e

VI. Bibliothèques requises

Avant de continuer, téléchargez les bibliothèques suivantes dans app/js/lib/ :

Ouvrez app/js/main.js et modifiez la propriété shim au niveau de requirejs.config pour charger Underscore.js et Backbone.js

 
Sélectionnez
requirejs.config({
  baseUrl : 'js',
 
  paths : {
  },
 
  shim: {
    'lib/underscore-min' : {
      exports : '_'
    },
    'lib/backbone-min' : {
      deps : ['lib/underscore-min']
    , exports : 'Backbone'
    },
    'app' : {
      deps : ['lib/underscore-min', 'lib/backbone-min']
    }
  }
});
 
require([
  'app'
],
 
function(App) {
  window.bTask = new App();
});

Cela fait un peu bizarre, mais n'oubliez pas que nous utilisons RequireJS pour charger les scripts sous forme de modules. Les « shims » permettent d'exprimer des dépendances à des bibliothèques qui ne sont pas implémentées en utilisant AMD.

VII. Charger l'API Tasks

Le modèle de base pour le chargement de l'API Google Tasks est :

  • charger la bibliothèque cliente de l'API Google : https://apis.google.com/js/client.js ;
  • appelez gapi.client.load pour charger l'API « tasks » ;
  • définir la clé de l'API à l'aide de gapi.client.setApiKey().

Pour cela, vous aurez besoin d'un endroit où mettre les informations nécessaires à l'identification. Créez un fichier appelé app/js/config.js et ajoutez-y la clé de l'API et l'ID du client :

 
Sélectionnez
define([], function() {
  var config = {};
  config.apiKey = 'la clé de l'API';
  config.scopes = 'https://www.googleapis.com/auth/tasks https://www.googleapis.com/auth/userinfo.profile';
  config.clientId = 'l'ID client';
  return config;
});

Le require près de la fin s'assure que mocha.run s'exécute uniquement lorsque /js/app.js a été chargé.

Créez un autre fichier appelé test/setup.js :

 
Sélectionnez
var assert = chai.assert;
 
mocha.setup({
  ui: 'tdd'
, globals: ['bTask']
});

Ce fichier peut être chargé par notre implémentation personnalisée de Backbone.sync.

Maintenant, créez un nouveau fichier nommé app/gapi.js :

 
Sélectionnez
define(['config'], function(config) {
  function ApiManager() {
    this.loadGapi();
  }
 
  _.extend(ApiManager.prototype, Backbone.Events);
 
  ApiManager.prototype.init = function() {
  };
 
  ApiManager.prototype.loadGapi = function() {
  };
 
  Backbone.sync = function(method, model, options) {
    options || (options = {});
 
    switch (method) {
      case 'create' :
      break;
 
      case 'update' :
      break;
 
      case 'delete' :
      break;
 
      case 'read' :
      break;
    }
  };
 
  return ApiManager;
});

Cette architecture montre la structure globale de notre chargeur de l'API Google Tasks et de l'implémentation de Backbone.sync. L'ApiManager est un constructeur standard, et j'ai utilisé Underscore.js pour hériter de Backbone.Events. Ce code sera asynchrone, cette gestion des événements sera utile plus tard.

La méthode de loadGapi charge les JavaScript de Google à l'aide de RequireJS. Une fois que l'objet global gapi a été trouvé, il fera le reste de la configuration en appelant la méthode init :

 
Sélectionnez
ApiManager.prototype.loadGapi = function() {
  var self = this;
 
  // Ne pas charger gapi s'il est déjà présent
  if (typeof gapi !== 'undefined') {
    return this.init();
  }
 
  require(['https://apis.google.com/js/client.js?onload=define'], function() {
    // Sondage jusqu'à ce que gapi soit prêt
    function checkGAPI() {
      if (gapi && gapi.client) {
        self.init();
      } else {
        setTimeout(checkGAPI, 100);
      }
    }
 
    checkGAPI();
  });
});

Tout ce que la méthode init doit faire est de charger l'API Tasks avec gapi.client.load :

 
Sélectionnez
ApiManager.prototype.init = function() {
  var self = this;
 
  gapi.client.load('tasks', 'v1', function() { /* Chargée */ });
 
  function handleClientLoad() {
    gapi.client.setApiKey(config.apiKey);
    window.setTimeout(checkAuth, 100);
  }
 
  function checkAuth() {
    gapi.auth.authorize({ client_id: config.clientId, scope: config.scopes, immediate : true }, handleAuthResult);
  }
 
  function handleAuthResult(authResult) {
  }
 
  handleClientLoad();
};

La variable config était l'une des dépendances de ce fichier et contient les informations d'identification requises par les API de Google.

VIII. Chargement de l'API Manager

Maintenant, ouvrez app/js/app.js et faites-le dépendre de gapi, puis créez une instance de ApiManager :

 
Sélectionnez
define([
  'gapi'
],
 
function(ApiManager) {
  var App = function() {
    this.connectGapi();
  };
 
  App.prototype = {
    connectGapi: function() {
      this.apiManager = new ApiManager();
    }
  };
 
  return App;
});

Si vous voulez vérifier que cela fonctionne en exécutant les tests, vous devrez changer test/setup.js pour passer gapi en global :

 
Sélectionnez
var assert = chai.assert;
 
mocha.setup({
  ui : 'tdd'
, globals : ['bTask', 'gapi', '___jsl']
});

Cependant, je n'ai pas l'intention de charger l'API à distance pendant les essais. Cela va effectivement être difficile. J'y reviendrai dans un prochain tutoriel.

IX. Résultats

Image non disponible

Si vous exécutez l'application ou les tests et que vous ouvrez une console JavaScript, un objet global gapi devrait être disponible. Utiliser les API Google avec RequireJS et Backbone.js semble beaucoup de travail, mais la plupart des choses sont effectivement juste de la configuration, et une fois cela fait, cela devrait fonctionner suffisamment solidement, vous permettant de vous concentrer sur l'aspect de conception et de développement des applications.

X. Code source

XI. Références

XII. Remerciements

Cet article a été publié avec l'aimable autorisation de Alex Young. L'article original peut être lu sur le site DailyJSDailyJS : Backbone.js Tutorial : Google's APIs and RequireJSBackbone.js Tutorial: Google's APIs and RequireJS.
Je remercie également ClaudeLELOUP pour sa relecture attentive et assidue.