פברואר 2009
מבוא
"Where's Ruby on the customer directories?"
התשוקה הגדולה של המפתחים שלנו והפופולריות הגבוהה של Ruby on Rails (RoR) מעוררת תיאבון, והעמיתה שלי ג'ף פישר זילבה ספריית כלי אודם במעמקי הגבעה של מאונט דום. חשוב לזכור שזוהי לא ספריית לקוח מלאה, אבל היא מטפלת בעקרונות בסיסיים, כמו אימות ומניפולציה בסיסית ב-XML. כדי להשתמש בו צריך לעבוד ישירות עם פיד ה-Atom באמצעות המודול REXML ו-XPath.
Audience
המאמר הזה מיועד למפתחים שרוצים לקבל גישה לממשקי ה-API של Google Data באמצעות Ruby, ובאופן ספציפי Ruby on Rails. הוא יוצא מנקודת הנחה שהקורא מכיר היטב את שפת התכנות Ruby ואת המסגרת לפיתוח אתרים של Rails. אני מתמקד ב-Docs List API לרוב הדוגמאות, אבל ניתן ליישם את אותם קונספטים בכל אחד מה-API של הנתונים.
תחילת העבודה
הדרישות
התקנת ספריית הנתונים של Google Data Ruby Utility
כדי למצוא את הספרייה, אפשר להוריד את מקור הספרייה ישירות מאירוח הפרויקט או להתקין את אבן החן:
sudo gem install gdata
טיפ: מומלץ להשתמש ב-gem list --local
כדי לוודא שהסמן הותקן כראוי.
אימות
ClientLogin
בעזרת ClientLogin האפליקציה שלך יכולה להתחבר באופן פרוגרמטי לחשבונות Google או G Suite. לאחר אימות פרטי הכניסה של המשתמש, Google מנפיקה אסימון אימות כהפניה לבקשות API נוספות. האסימון תקף למשך פרק זמן מוגדר, המוגדר לפי שירות Google שאיתו אתם עובדים. מטעמי אבטחה וכדי לספק למשתמשים שלך את החוויה הטובה ביותר, עליך להשתמש ב-ClientLogin רק בעת פיתוח יישומים שולחניים ומותקנים. באפליקציות אינטרנט, עדיף להשתמש ב-AuthSub או ב-OAuth.
לספריית Ruby יש סיווג לקוח לכל אחד מממשקי ה-API. לדוגמה, אפשר להשתמש בקטע הקוד הבא כדי להתחבר ל-user@gmail.com
ל-Docs Documents Data API:
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')
להצגת הרשימה המלאה של מחלקות השירות המיושמות.
אם השירות לא כולל את סיווג הלקוח, תוכלו להשתמש באותה מחלקה GData::Client::Base
.
לדוגמה, הקוד הבא מאלץ את המשתמשים להיכנס עם חשבון 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)
הערה: כברירת מחדל, הספרייה משתמשת ב-HOSTED_OR_GOOGLE
של accountType
. הערכים האפשריים הם HOSTED_OR_GOOGLE
, HOSTED
או GOOGLE
.
אחד החסרונות בשימוש ב-ClientLogin הוא שניתן לשלוח לאפליקציה שלך בקשות CAPTCHA במהלך ניסיונות התחברות שנכשלו. במקרה כזה, תוכלו לתקן את השגיאה על ידי קריאה לשיטה clientlogin()
באמצעות הפרמטרים הנוספים שלה: client.clientlogin(username, password, captcha_token, captcha_answer)
. במסמכי התיעוד המלאים על אימות לאפליקציות מותקנות תוכלו לקרוא מידע נוסף על השימוש ב-CAPTCHA.
AuthSub
יצירת כתובת האתר של 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)
בלוק הקוד הקודם יוצר את כתובת ה-URL הבאה ב-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
אפשר גם להשתמש בשיטה authsub_url
של אובייקט הלקוח. לכל רמת שירות הוגדר מאפיין ברירת מחדל authsub_scope
, כך שאין צורך לציין מאפיין משלכם.
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)
בלוק הקוד הקודם יוצר את כתובת ה-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
שדרוג של אסימון לשימוש חד-פעמי באסימון
AuthSub יפנה את המשתמש בחזרה אל http://example.com/change/to/your/app?token=SINGLE_USE_TOKEN
לאחר שתעניק גישה לנתונים שלו. שימו לב שכתובת ה-URL היא רק next_url
עם האסימון לשימוש יחיד
שמתווסף כפרמטר של שאילתה.
לאחר מכן, מחליפים את האסימון לשימוש חד-פעמי באסימון עם משך חיים ארוך:
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]
AuthSub מאובטח דומה מאוד. התוספת היחידה היא הגדרת המפתח הפרטי שלך לפני שדרוג האסימון:
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]
הערה: כדי להשתמש באסימונים מאובטחים, חשוב להגדיר את secure=true
כשמבקשים אסימון לשימוש חד-פעמי. יש לעיין למעלה בקטע יצירת כתובת ה-URL של AuthSubRequest.
ניהול אסימונים
AuthSub מספק שני רכיבי handler נוספים, AuthSubTokenInfo ו-AuthSubRevokeToken לניהול אסימונים. בעזרת AuthSubTokenInfo
אפשר לבדוק את התקינות של האסימון. AuthSubRevokeToken
מאפשר למשתמשים להפסיק את הגישה לנתונים שלהם. השיטה המומלצת לאפליקציה היא AuthSubRevokeToken
. שתי השיטות נתמכות בספריית Ruby.
כדי לשלוח שאילתה למטא-נתונים של אסימון:
client.auth_handler.info
כדי לבטל אסימון סשן:
client.auth_handler.revoke
עיין בתיעוד המלא של אימות SubSub עבור יישומי אינטרנט עבור הסקופ המלא ב-AuthSub.
OAuth
במועד כתיבת המאמר הזה, ה-OAuth לא נוסף למודול GData::Auth
.
השימוש ב-OAuth בספריית השירות צריך להיות קל יחסית כשמשתמשים ב-Rails oauth-plugin או Ruby oauth gem. בכל מקרה, כדאי ליצור אובייקט GData::HTTP::Request
ולהעביר אותו לכותרת Authorization
שנוצרת על ידי כל ספרייה.
גישה לפידים
GET (שליפת נתונים)
אחרי שמגדירים אובייקט לקוח, צריך להשתמש בשיטה get()
כדי לשלוח שאילתה לגבי פיד נתוני Google. אפשר להשתמש ב-XPath כדי לאחזר רכיבי Atom ספציפיים. הנה דוגמה לאחזור מסמכי Google של משתמש:
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 (יצירת נתונים חדשים)
צריך להשתמש בשיטה post()
של לקוח כדי ליצור נתונים חדשים בשרת. בדוגמה הבאה יתווסף new_writer@example.com
בתור שותף עריכה למסמך עם המזהה: 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 (עדכון נתונים)
כדי לעדכן נתונים בשרת, יש להשתמש בשיטה put()
של הלקוח. הדוגמה הבאה תעדכן את הכותרת של המסמך.
ההנחה היא שיש לכם פיד משאילתה קודמת.
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)
מחיקה
כדי למחוק <atom:entry> או נתונים אחרים מהשרת, יש להשתמש בשיטה delete()
.
הדוגמה הבאה תמחק מסמך. הקוד יוצא מנקודת הנחה שיש רשומת מסמך משאילתה קודמת.
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)
יצירת אפליקציה חדשה של Rails
בדרך כלל התרגיל הראשון ביצירה של אפליקציית Rails חדשה כרוך בהפעלת מחוללי הפיגומים כדי ליצור את קובצי ה-MVC.
לאחר מכן, הוא מפעיל את rake db:migrate
כדי להגדיר את טבלאות מסדי הנתונים. עם זאת, מאחר שהאפליקציה שלנו שולחת שאילתה לממשק ה-API של רשימת המסמכים של Google, יש לנו צורך מועט בפיגומים כלליים או במסדי נתונים. במקום זאת, צרו אפליקציה חדשה ובקר פשוט:
rails doclist cd doclist ruby script/generate controller doclist
ולבצע את השינויים הבאים ב-config/environment.rb
:
config.frameworks -= [ :active_record, :active_resource, :action_mailer ] config.gem 'gdata', :lib => 'gdata'
השורה הראשונה מבטלת את הנעילה של ActiveRecord
מהאפליקציה.
השורה השנייה טוענת את אבן החן gdata
בזמן האתחול.
לבסוף, בחרתי לחבר את מסלול ברירת המחדל ('/
') לפעולה documents
בDoclistController
.
הוספת השורה הזו אל config/routes.rb
:
map.root :controller => 'doclist', :action => 'all'
הפעלת שלט רחוק
מאחר שלא יצרנו פיגומים, הוסיפו באופן ידני פעולה בשם 'all
'
ל-DoclistController
ב-app/controllers/doclist_controller.rb
.
class DoclistController < ApplicationController def all @foo = 'I pity the foo!' end end
וליצור all.html.erb
במסגרת app/views/doclist/
:
<%= @foo %>
הפעלת שרת האינטרנט והתחלת הפיתוח
עכשיו אמורה להיות לך אפשרות להפעיל את שרת האינטרנט המוגדר כברירת מחדל על ידי הפעלה של ruby script/server
.
אם אין בעיה, הכוונה של הדפדפן ל-http://localhost:3000/
היא 'I pity the foo!
'.
טיפ: חשוב לזכור להסיר את השם של public/index.html
או לשנות את השם שלו.
כשיהיה לכם משהו לעבוד, תוכלו לצפות ב-DoclistController
האחרון שלי וב-ApplicationController
לבשר הפרויקט של DocList Manager. כדאי גם לבדוק את ContactsController
, המטפל בקריאות ל-Google contacts API.
סיכום
החלק הקשה ביותר ביצירה של אפליקציית Google Data Rails הוא הגדרת Rails! עם זאת, המערכת מבצעת פריסה של האפליקציה שלכם. לכן מומלץ מאוד להשתמש ב-mod_rails ב-Apache. קל מאוד להגדיר, להתקין ולהפעיל. תוך זמן קצר תוכל להתחיל לפרסם!
משאבים
- רשימת ממשקי API של נתונים של Google
- דף הפרויקט Google Data Ruby Utility Library
- מאמר: שימוש ב-Ruby עם ממשקי ה-API של נתונים של Google
- להורדת Ruby
- להורדת RubyGems and Rails
נספח
דוגמאות
DocList Manager הוא דוגמה מלאה ל-Ruby on Rails שממחישה את הנושאים שמוזכרים במאמר הזה. קוד המקור המלא זמין לאירוח פרויקטים.