Febbraio 2009
Introduzione
"Dov'è Ruby nell'elenco delle librerie client?"
Spinto dalla vorace curiosità dei nostri sviluppatori e dalla duratura popolarità di Ruby on Rails (RoR), il mio collega Jeff Fisher ha forgiato una libreria di utilità Ruby dalle infuocate profondità di Monte Fato. Tieni presente che non si tratta di una libreria client completa, ma gestisce le funzionalità di base come l'autenticazione e la manipolazione di base di XML. Inoltre, richiede di lavorare direttamente con il feed Atom utilizzando il modulo REXML e XPath.
Pubblico
Questo articolo è rivolto agli sviluppatori interessati ad accedere alle API Google Data utilizzando Ruby, in particolare Ruby on Rails. Si presume che il lettore abbia una certa familiarità con il linguaggio di programmazione Ruby e con il framework di sviluppo web Rails. Mi concentro sull'API Document List per la maggior parte degli esempi, ma gli stessi concetti possono essere applicati a qualsiasi API di dati.
Per iniziare
Requisiti
Installazione della libreria di utilità Google Data Ruby
Per ottenere la libreria, puoi scaricare direttamente l'origine della libreria dall'hosting del progetto o installare il gem:
sudo gem install gdata
Suggerimento: per sicurezza, esegui gem list --local
per verificare che la gemma sia stata installata correttamente.
Autenticazione
ClientLogin
ClientLogin consente alla tua applicazione di accedere in modo programmatico agli account Google o G Suite degli utenti. Dopo aver convalidato le credenziali dell'utente, Google rilascia un token di autenticazione a cui fare riferimento nelle successive richieste API. Il token rimane valido per un periodo di tempo prestabilito, definito dal servizio Google che stai utilizzando. Per motivi di sicurezza e per offrire ai tuoi utenti la migliore esperienza, devi utilizzare ClientLogin solo quando sviluppi applicazioni installate e desktop. Per le applicazioni web, è preferibile utilizzare AuthSub o OAuth.
La libreria Ruby ha una classe client per ciascuna API. Ad esempio, utilizza il seguente snippet di codice per accedere a [email protected]
all'API Documents List Data:
client = GData::Client::DocList.new client.clientlogin('[email protected]', 'pa$$word')
The YouTube Data API would be:
client = GData::Client::YouTube.new client.clientlogin('[email protected]', '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, il seguente codice impone agli utenti di 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 libreria utilizza HOSTED_OR_GOOGLE
per accountType
. I valori possibili sono HOSTED_OR_GOOGLE
,
HOSTED
o GOOGLE
.
Uno degli svantaggi dell'utilizzo di ClientLogin è che la tua applicazione può ricevere test CAPTCHA in caso di tentativi di accesso non riusciti. Se ciò accade,
puoi gestire l'errore chiamando il metodo clientlogin()
con i relativi parametri aggiuntivi:
client.clientlogin(username, password, captcha_token, captcha_answer)
. Per ulteriori informazioni sulla gestione dei CAPTCHA, consulta la documentazione completa relativa all'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=https%3A%2F%2F2.zoppoz.workers.dev%3A443%2Fhttp%2Fexample.com%2Fchange%2Fto%2Fyour%2Fapp&scope=https%3A%2F%2F2.zoppoz.workers.dev%3A443%2Fhttp%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=https%3A%2F%2F2.zoppoz.workers.dev%3A443%2Fhttp%2Fexample.com%2Fchange%2Fto%2Fyour%2Fapp&scope=https%3A%2F%2F2.zoppoz.workers.dev%3A443%2Fhttp%2Fdocs.google.com%2Ffeeds%2F&session=1&secure=0&hd=example.com
Eseguire l'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
una volta
che avrà concesso l'accesso ai suoi dati. Tieni presente che l'URL è semplicemente il nostro next_url
con il token monouso
aggiunto come parametro di query.
Successivamente, 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 è impostare la 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. Vedi Generazione dell'URL AuthSubRequest sopra.
Gestione dei token
AuthSub fornisce due gestori aggiuntivi, AuthSubTokenInfo e
AuthSubRevokeToken, 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. Come best practice, la tua app deve utilizzare AuthSubRevokeToken
. Entrambi i metodi sono supportati nella libreria Ruby.
Per eseguire una 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 AuthSub per applicazioni web per saperne di più su 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 si utilizza il plug-in oauth di Rails o
il gem oauth di Ruby. In entrambi i casi, ti consigliamo di creare un oggetto GData::HTTP::Request
e di passargli l'intestazione Authorization
generata da ogni libreria.
Accedere ai feed
GET (recupero dei dati)
Dopo aver configurato un oggetto client, utilizza il relativo metodo get()
per eseguire query su un feed Google Data. 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 post()
di un client per creare nuovi dati sul server. L'esempio seguente aggiungerà
[email protected]
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='[email protected]'/> </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 dei dati)
Per aggiornare i dati sul server, utilizza il metodo put()
di un client. L'esempio seguente aggiornerà il titolo di un documento.
Presuppone che tu abbia un feed da 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 un elemento <atom:entry> o altri dati dal server, utilizza il metodo delete()
.
L'esempio seguente elimina un documento. Il codice presuppone che tu abbia una voce di documento
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 per creare una nuova app Rails prevede l'esecuzione dei generatori di scaffold per creare i file MVC.
Dopodiché, viene eseguito rake db:migrate
per configurare le tabelle del database. Tuttavia, poiché la nostra applicazione eseguirà query sull'API Google Documents List
per i dati, abbiamo poco bisogno di scaffolding o database 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 scollega ActiveRecord
dall'applicazione.
La seconda riga carica la gemma gdata
all'avvio.
Infine, ho scelto di collegare la route predefinita ("/
") all'azione documents
in DoclistController
.
Aggiungi questa riga a config/routes.rb
:
map.root :controller => 'doclist', :action => 'all'
Avviare un controller
Poiché non abbiamo generato scaffolding, aggiungi manualmente un'azione chiamata "all
" a
DoclistController
in 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 %>
Avviare il server web e iniziare lo sviluppo
Ora dovresti essere in grado di avviare il server web predefinito richiamando ruby script/server
.
Se tutto va bene, se indirizzi 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 tutto funziona, dai un'occhiata al mio
DoclistController
e
ApplicationController
per il cuore
del progetto DocList Manager. Ti consigliamo anche 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, al secondo posto c'è il deployment dell'applicazione. Per questo, ti consiglio vivamente mod_rails per Apache. È facilissimo da configurare, installare ed eseguire. Sarai pronto in un attimo.
Risorse
- Elenco delle API Google Data
- Pagina del progetto Google Data Ruby Utility Library
- Articolo: Utilizzo di Ruby con le API Google Data
- Scarica Ruby
- Scaricare RubyGems e Rails
Appendice
Esempi
DocList Manager è un esempio completo di Ruby on Rails che illustra gli argomenti trattati in questo articolo. Il codice sorgente completo è disponibile dall'hosting del progetto.