febbraio 2009
Introduzione
"Dov'è Ruby nell'elenco delle librerie client?"
Motivato dal feroce appetito dei nostri sviluppatori e dalla continua popolarità di Ruby on Rails (RoR), il mio collega Jeff Fisher ha creato una raccolta di utilità di rubini dalle incredibili profondità di Mount Doom. Tenete presente che non è una libreria client a tutti gli effetti, ma gestisce i concetti fondamentali come autenticazione e manipolazione XML di base. Richiede inoltre di lavorare direttamente con il feed Atom utilizzando il modulo REXML e XPath.
Pubblico
Questo articolo è rivolto agli sviluppatori interessati ad accedere alle API di dati di Google utilizzando Ruby, in particolare Ruby on Rails. Si presume che il lettore abbia familiarità con il linguaggio di programmazione Ruby e con il framework di sviluppo web di Rails. Per la maggior parte degli esempi, mi occupo dell'API Docs List, ma gli stessi concetti possono essere applicati a qualsiasi API di dati.
Per iniziare
Requisiti
- Download Ruby 1.8.6 livello patch 114+
- RubyGems 1.3.1+ download
- Scarica Rails 2.2.2 o versioni successive
Installare la libreria di utilità Ruby dei dati di Google
Per ottenere la libreria, puoi scaricare l'origine della libreria direttamente dall'hosting del progetto o installare la gemma:
sudo gem install gdata
Suggerimento: per sicurezza, esegui gem list --local
per verificare che la gemma sia stata installata correttamente.
Autenticazione
ClientLogin
ClientLogin consente all'applicazione di accedere in modo programmatico agli utenti all'account Google o G Suite. Dopo la convalida delle credenziali dell'utente, Google emette un token di autenticazione a cui fare riferimento nelle successive richieste API. Il token rimane valido per un periodo di tempo definito, definito dal servizio Google in uso. Per motivi di sicurezza e per offrire agli utenti la migliore esperienza possibile, ti consigliamo di utilizzare ClientLogin soltanto durante lo sviluppo di applicazioni desktop installate. Per le applicazioni web è preferibile utilizzare AuthSub o OAuth.
La libreria Ruby ha una classe client per ciascuna delle API. Ad esempio, utilizza il seguente snippet di codice per accedere a user@gmail.com
con l'API di dati dell'elenco documenti:
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')
Consulta l'elenco completo delle classi di servizio implementate.
Se un servizio non ha una classe client, utilizza la classe GData::Client::Base
.
Ad esempio, nel codice seguente gli utenti devono accedere con un account 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)
Nota: per impostazione predefinita, la raccolta utilizza HOSTED_OR_GOOGLE
per accountType
. I valori possibili sono HOSTED_OR_GOOGLE
, HOSTED
o GOOGLE
.
Uno degli svantaggi dell'uso di ClientLogin è che all'applicazione possono essere inviate richieste CAPTCHA in caso di tentativi di accesso non riusciti. In questo caso,
puoi gestire l'errore chiamando il metodo clientlogin()
con i parametri aggiuntivi:
client.clientlogin(username, password, captcha_token, captcha_answer)
. Per ulteriori informazioni sulla gestione dei CAPTCHA, consulta la documentazione completa sull'Autenticazione per le applicazioni installate.
AuthSub
Generazione dell'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)
Il blocco di codice precedente crea il seguente URL in 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
Puoi anche utilizzare il metodo authsub_url
dell'oggetto client. Ogni classe di servizio ha impostato un attributo authsub_scope
predefinito, quindi non è necessario specificarne uno personalizzato.
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)
Il blocco di codice precedente crea il seguente URL:
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
Upgrade di un token monouso a un token di sessione
AuthSub reindirizzerà l'utente a http://example.com/change/to/your/app?token=SINGLE_USE_TOKEN
dopo aver concesso l'accesso ai propri dati. Tieni presente che l'URL è solo il nostro next_url
con il token monouso aggiunto come parametro di ricerca.
Quindi, scambia il token monouso con un token di sessione di lunga durata:
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 è molto simile. L'unica aggiunta è l'impostazione della chiave privata prima di eseguire l'upgrade del token:
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]
Nota: per utilizzare i token sicuri, assicurati di impostare secure=true
quando richiedi un token monouso. Consulta la sezione Generazione dell'URL di AuthSubRequest in alto.
Gestione dei token
AuthSub fornisce due gestori aggiuntivi, AuthSubTokenInfo e AuthSubRevocaToken per la gestione dei token. AuthSubTokenInfo
è utile per verificare la validità di un token. AuthSubRevokeToken
offre agli utenti la possibilità di interrompere l'accesso ai propri dati. La tua app dovrebbe utilizzare AuthSubRevokeToken
come best practice. Entrambi i metodi sono supportati nella libreria Ruby.
Per eseguire query sui metadati di un token:
client.auth_handler.info
Per revocare un token di sessione:
client.auth_handler.revoke
Consulta la documentazione completa sull'autenticazione SubSub per applicazioni web per la versione completa di AuthSub.
OAuth
Al momento della stesura di questo articolo, OAuth non è stato aggiunto al modulo GData::Auth
.
L'utilizzo di OAuth nella libreria di utilità dovrebbe essere relativamente semplice quando utilizzi il plug-in oauth Rails o Gem OAuth. In entrambi i casi, dovrai creare un oggetto GData::HTTP::Request
e trasmetterlo all'intestazione Authorization
generata da ciascuna libreria.
Accedere ai feed
GET (recupero dati)
Dopo aver configurato un oggetto client, utilizza il relativo metodo get()
per eseguire query su un feed di dati di Google. XPath può essere utilizzato per recuperare elementi Atom specifici. Ecco un esempio di recupero dei documenti Google di un utente:
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 (creazione di nuovi dati)
Utilizza il metodo del client post()
per creare nuovi dati sul server. L'esempio seguente aggiungerà new_writer@example.com
come collaboratore al documento con 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 (aggiornamento dati)
Per aggiornare i dati sul server, utilizza il metodo put()
del client. L'esempio seguente aggiornerà il titolo di un documento.
Presuppone che tu abbia un feed di una query precedente.
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)
ELIMINA
Per eliminare <atom:entry> o altri dati dal server, utilizza il metodo delete()
.
Il seguente esempio eliminerà un documento. Il codice presume che tu abbia una voce di documento proveniente da una query precedente.
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)
Creazione di una nuova applicazione Rails
Di solito il primo esercizio nella creazione di una nuova app Rails prevede l'esecuzione dei generatori di impalcature per creare i file MVC.
Successivamente, eseguirà rake db:migrate
per configurare le tabelle del database. Tuttavia, poiché la nostra applicazione eseguirà una query sui dati dell'API Google List List, abbiamo pochissimo bisogno di database o scaffolding generici. Crea invece una nuova applicazione e un controller semplice:
rails doclist cd doclist ruby script/generate controller doclist
e apporta le seguenti modifiche a config/environment.rb
:
config.frameworks -= [ :active_record, :active_resource, :action_mailer ] config.gem 'gdata', :lib => 'gdata'
La prima riga sgancia ActiveRecord
dall'applicazione.
La seconda riga carica la gemma gdata
all'avvio.
Infine, ho scelto di connettere la route predefinita ("/
") all'azione documents
in DoclistController
.
Aggiungi questa riga a config/routes.rb
:
map.root :controller => 'doclist', :action => 'all'
Avvia un controller
Poiché non abbiamo generato impalcature, aggiungi manualmente un'azione chiamata "all
" alla DoclistController
di app/controllers/doclist_controller.rb
.
class DoclistController < ApplicationController def all @foo = 'I pity the foo!' end end
e crea all.html.erb
in app/views/doclist/
:
<%= @foo %>
Avvia il server web e avvia lo sviluppo
Ora dovresti essere in grado di avviare il server web predefinito richiamando ruby script/server
.
Se tutto funziona correttamente, puntando il browser a http://localhost:3000/
dovrebbe essere visualizzato "I pity the foo!
".
Suggerimento: non dimenticare di rimuovere o rinominare public/index.html
.
Una volta che avrai finito di lavorare, dai un'occhiata alle mie ultime DoclistController
e a ApplicationController
per l'elenco di progetti del progetto DocList Manager. Ti consigliamo inoltre di esaminare
ContactsController
, che
gestisce le chiamate all'API Google Contacts.
Conclusione
La parte più difficile della creazione di un'app Google Data Rails è la configurazione di Rails. Tuttavia, un attimo di tempo sta eseguendo il deployment dell'applicazione. Per questo consiglio vivamente mod_rails per Apache. È facilissimo da configurare, installare ed eseguire. Potrai pubblicare gli annunci in pochissimo tempo.
Risorse
- Elenco delle API di dati di Google
- Pagina del progetto Libreria dati di Ruby di Google Data
- Articolo: Utilizzo di Ruby con le API di dati di Google
- Scarica Ruby
- Scarica RubyGems e Rails
Appendice
Esempi
DocList Manager è un esempio completo di Ruby on Rails che mostra gli argomenti discussi in questo articolo. Il codice sorgente completo è disponibile nell'hosting del progetto.