Février 2009
Introduction
"Où se trouve Ruby dans la liste des bibliothèques clientes ?"
Motivé par l'enthousiasme féroce de nos développeurs et par la popularité durable de Ruby on Rails (RoR), mon collègue Jeff Fisher a créé une bibliothèque d'utilitaires Ruby des profondeurs infimes du mont Doom. Il ne s'agit pas d'une bibliothèque cliente complète, mais elle gère les principes de base tels que l'authentification et la manipulation XML de base. Vous devez également travailler directement avec le flux Atom à l'aide du module REXML et de XPath.
Audience
Cet article est destiné aux développeurs souhaitant accéder aux API Google Data à l'aide de Ruby, en particulier Ruby on Rails. Il suppose que le lecteur maîtrise le langage de programmation Ruby et le framework de développement Web Rails. Je me concentre sur l'API Documents List pour la plupart des exemples, mais les mêmes concepts peuvent être appliqués à n'importe quelle API Data.
Premiers pas
Conditions requises
- Version 114 et ultérieure du correctif de Ruby 1.8.6 télécharger
- RubyGems 1.3.1 et versions plus récentes télécharger
- Télécharger Rails 2.2.2 ou version ultérieure
Installer la bibliothèque d'utilitaires Google Data Ruby
Pour obtenir la bibliothèque, vous pouvez la télécharger directement à partir du projet qui héberge le projet ou installer le gem:
sudo gem install gdata
Conseil: Pour une bonne mesure, exécutez gem list --local
pour vérifier que le gem a bien été installé.
Authentification
ClientLogin
ClientLogin permet à votre application de connecter de manière automatisée les utilisateurs à leur compte Google ou G Suite. Lors de la validation des identifiants de l'utilisateur, Google émet un jeton d'authentification à référencer dans les requêtes API ultérieures. Le jeton reste valide pendant une période définie, définie par le service Google avec lequel vous travaillez. Pour des raisons de sécurité et pour offrir une expérience optimale à vos utilisateurs, vous ne devez utiliser ClientLogin que lors du développement d'applications de bureau installées. Pour les applications Web, il est préférable d'utiliser AuthSub ou OAuth.
La bibliothèque Ruby possède une classe cliente pour chacune des API. Par exemple, utilisez l'extrait de code suivant pour vous connecter à user@gmail.com
à l'API Documents List Data:
client = GData::Client::DocList.new client.clientlogin('user@gmail.com', 'pa$$word')
The YouTube Data API would be:
client = GData::Client::YouTube.new client.clientlogin('user@gmail.com', 'pa$$word')
Consultez la liste complète des classes de service mises en œuvre.
Si un service ne possède pas de classe client, utilisez la classe GData::Client::Base
.
Par exemple, le code suivant oblige les utilisateurs à se connecter avec un compte G Suite.
client_login_handler = GData::Auth::ClientLogin
.new('writely', :account_type => 'HOSTED')
token = client_login_handler.get_token('user@example.com', 'pa$$word', 'google-RailsArticleSample-v1')
client = GData::Client::Base.new(:auth_handler => client_login_handler)
Remarque: Par défaut, la bibliothèque utilise HOSTED_OR_GOOGLE
pour accountType
. Les valeurs possibles sont HOSTED_OR_GOOGLE
, HOSTED
ou GOOGLE
.
L'un des inconvénients de l'utilisation de ClientLogin est que votre application peut recevoir des tests CAPTCHA en cas d'échec de tentative de connexion. Dans ce cas, vous pouvez gérer l'erreur en appelant la méthode clientlogin()
avec ses paramètres supplémentaires : client.clientlogin(username, password, captcha_token, captcha_answer)
. Consultez la documentation complète sur l'authentification pour les applications installées pour en savoir plus sur le traitement des captchas.
AuthSub
Générer l'URL AuthSubRequest
scope = 'http://www.google.com/calendar/feeds/' next_url = 'http://example.com/change/to/your/app' secure = false # set secure = true for signed AuthSub requests sess = true authsub_link = GData::Auth::AuthSub.get_url(next_url, scope, secure, sess)
Le bloc de code précédent crée l'URL suivante dans authsub_link
:
https://www.google.com/accounts/AuthSubRequest?next=http%3A%2F%2Fexample.com%2Fchange%2Fto%2Fyour%2Fapp&scope=http%3A%2F%2Fwww.google.com%2Fcalendar%2Ffeeds%2F&session=1&secure=0
Vous pouvez également utiliser la méthode authsub_url
de l'objet client. Chaque classe de service a défini un attribut authsub_scope
par défaut. Il n'est donc pas nécessaire d'en spécifier un.
client = GData::Client::DocList.new next_url = 'http://example.com/change/to/your/app' secure = false # set secure = true for signed AuthSub requests sess = true domain = 'example.com' # force users to login to a G Suite hosted domain authsub_link = client.authsub_url(next_url, secure, sess, domain)
Le bloc de code précédent crée l'URL suivante:
https://www.google.com/accounts/AuthSubRequest?next=http%3A%2F%2Fexample.com%2Fchange%2Fto%2Fyour%2Fapp&scope=http%3A%2F%2Fdocs.google.com%2Ffeeds%2F&session=1&secure=0&hd=example.com
Convertir un jeton à usage unique en jeton de session
AuthSub redirigera l'utilisateur vers http://example.com/change/to/your/app?token=SINGLE_USE_TOKEN
une fois qu'il aura autorisé l'accès à ses données. Notez que l'URL est simplement notre next_url
, avec le jeton à usage unique ajouté en tant que paramètre de requête.
Remplacez ensuite le jeton à usage unique par un jeton de session de longue durée:
client.authsub_token = params[:token] # extract the single-use token from the URL query params session[:token] = client.auth_handler.upgrade() client.authsub_token = session[:token] if session[:token]
Secure AuthSub est très similaire. Le seul ajout consiste à définir votre clé privée avant de mettre à niveau le jeton:
PRIVATE_KEY = '/path/to/private_key.pem' client.authsub_token = params[:token] client.authsub_private_key = PRIVATE_KEY session[:token] = client.auth_handler.upgrade() client.authsub_token = session[:token] if session[:token]
Remarque: Pour utiliser des jetons sécurisés, veillez à définir secure=true
lorsque vous demandez un jeton à usage unique. Consultez la section Générer l'URL de requête AuthSub ci-dessus.
Gestion des jetons
AuthSub fournit deux gestionnaires supplémentaires, AuthSubTokenInfo et AuthSubRevokeToken pour la gestion des jetons. AuthSubTokenInfo
est utile pour vérifier la validité d'un jeton. AuthSubRevokeToken
permet aux utilisateurs d'interrompre l'accès à leurs données. Votre application doit utiliser AuthSubRevokeToken
comme bonne pratique. Les deux méthodes sont compatibles avec la bibliothèque Ruby.
Pour interroger les métadonnées d'un jeton:
client.auth_handler.info
Pour révoquer un jeton de session:
client.auth_handler.revoke
Consultez la documentation complète sur l'authentification AuthSub pour les applications Web pour en savoir plus sur AuthSub.
OAuth
Au moment de la rédaction de cet article, OAuth n'a pas été ajouté au module GData::Auth
.
L'utilisation d'OAuth dans la bibliothèque d'utilitaires doit être relativement simple lorsque vous utilisez le module oauth-plugin ou le gem OAuth de Rails. Dans les deux cas, vous devez créer un objet GData::HTTP::Request
et lui transmettre l'en-tête Authorization
généré par chaque bibliothèque.
Accéder aux flux
GET (extraction des données)
Une fois que vous avez configuré un objet client, utilisez sa méthode get()
pour interroger un flux de données Google. XPath peut être utilisé pour récupérer des éléments Atom spécifiques. Voici un exemple de récupération des documents Google d'un utilisateur:
feed = client.get('http://docs.google.com/feeds/documents/private/full').to_xml feed.elements.each('entry') do |entry| puts 'title: ' + entry.elements['title'].text puts 'type: ' + entry.elements['category'].attribute('label').value puts 'updated: ' + entry.elements['updated'].text puts 'id: ' + entry.elements['id'].text # Extract the href value from each <atom:link> links = {} entry.elements.each('link') do |link| links[link.attribute('rel').value] = link.attribute('href').value end puts links.to_s end
POST (création de données)
Utilisez la méthode post()
d'un client pour créer des données sur le serveur. L'exemple suivant permet d'ajouter new_writer@example.com
en tant que collaborateur du document portant l'ID doc_id
.
# Return documents the authenticated user owns feed = client.get('http://docs.google.com/feeds/documents/private/full/-/mine').to_xml entry = feed.elements['entry'] # first <atom:entry> acl_entry = <<-EOF <entry xmlns="http://www.w3.org/2005/Atom" xmlns:gAcl='http://schemas.google.com/acl/2007'> <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/acl/2007#accessRule'/> <gAcl:role value='writer'/> <gAcl:scope type='user' value='new_writer@example.com'/> </entry> EOF # Regex the document id out from the full <atom:id>. # http://docs.google.com/feeds/documents/private/full/document%3Adfrk14g25fdsdwf -> document%3Adfrk14g25fdsdwf doc_id = entry.elements['id'].text[/full\/(.*%3[aA].*)$/, 1] response = client.post("http://docs.google.com/feeds/acl/private/full/#{doc_id}", acl_entry)
PUT (mise à jour des données)
Pour mettre à jour les données sur le serveur, utilisez la méthode put()
d'un client. L'exemple suivant met à jour le titre d'un document.
Nous partons du principe que vous disposez d'un flux issu d'une requête précédente.
entry = feed.elements['entry'] # first <atom:entry> # Update the document's title entry.elements['title'].text = 'Updated title' entry.add_namespace('http://www.w3.org/2005/Atom') entry.add_namespace('gd','http://schemas.google.com/g/2005') edit_uri = entry.elements["link[@rel='edit']"].attributes['href'] response = client.put(edit_uri, entry.to_s)
SUPPRIMER
Pour supprimer une <atom:entry> ou d'autres données du serveur, utilisez la méthode delete()
.
L'exemple suivant permet de supprimer un document. Le code suppose que vous disposez d'une entrée de document d'une requête précédente.
entry = feed.elements['entry'] # first <atom:entry> edit_uri = entry.elements["link[@rel='edit']"].attributes['href'] client.headers['If-Match'] = entry.attribute('etag').value # make sure we don't nuke another client's updates client.delete(edit_uri)
Créer une application Rails
En général, le premier exercice de création d'une application Rails implique l'exécution des générateurs d'échafaudage pour créer vos fichiers MVC.
Ensuite, il exécute rake db:migrate
pour configurer vos tables de base de données. Toutefois, comme notre application interroge l'API Google Documents List pour obtenir des données, nous n'avons pas vraiment besoin d'échafaudages génériques ni de bases de données. À la place, créez une application et un contrôleur simple:
rails doclist cd doclist ruby script/generate controller doclist
et apportez les modifications suivantes à config/environment.rb
:
config.frameworks -= [ :active_record, :active_resource, :action_mailer ] config.gem 'gdata', :lib => 'gdata'
La première ligne dissocie ActiveRecord
de l'application.
La deuxième ligne charge le gem gdata
au démarrage.
Enfin, j'ai choisi d'associer l'itinéraire par défaut (/
) à l'action documents
dans DoclistController
.
Ajoutez cette ligne à config/routes.rb
:
map.root :controller => 'doclist', :action => 'all'
Démarrer une manette
Comme nous n'avons pas généré d'échafaudage, ajoutez manuellement une action appelée "all
" à DoclistController
dans app/controllers/doclist_controller.rb
.
class DoclistController < ApplicationController def all @foo = 'I pity the foo!' end end
et créez all.html.erb
sous app/views/doclist/
:
<%= @foo %>
Déclencher le serveur Web et commencer le développement
Vous devriez maintenant pouvoir démarrer le serveur Web par défaut en appelant ruby script/server
.
Si tout va bien, pointez http://localhost:3000/
dans votre navigateur pour afficher « I pity the foo!
».
Conseil: N'oubliez pas de supprimer ou de renommer public/index.html
.
Une fois que les choses fonctionnent, regardez ma version finale de DoclistController
et ApplicationController
pour le viaur du projet DocList Manager. Vous pouvez également examiner ContactsController
, qui gère les appels à l'API Google Contacts.
Conclusion
Le plus difficile dans la création d'une application Google Data Rails est de configurer Rails. Toutefois, le déploiement de votre application prend une seconde seconde. Pour cela, nous vous recommandons vivement d'utiliser mod_rails pour Apache. Il est très facile à configurer, à installer et à exécuter. Lancez-vous en un rien de temps !
Ressources
- Liste des API Google Data
- Page de projet de la bibliothèque d'utilitaires Ruby de données Google
- Article: Utiliser Ruby avec les API Google Data
- Télécharger Ruby
- Télécharger RubyGems et Rails
Annexe
Exemples
Le gestionnaire de listes de documents est un exemple complet de Ruby on Rails illustrant les sujets abordés dans cet article. Le code source complet est disponible sur le site d'hébergement de projet.