SinatraでWebAPIをオープンソースライブラリを使って使おう
前回は「Sinatra Framework」と「Ruby言語」を合わせて使いました。 今回はそれらとあわせて、WebAPIを使ってみます。 さらに、APIをプログラミングで扱う際に、Ruby言語用のライブラリを使ってみます。
そうすると、ほんとにあっという間に、APIを利用したウェブサービスが作れるようになります。
WebAPIとは?
FacebookやTwitter, Google, Yahoo Japan!、楽天などが数多くのウェブサービス提供会社が提供しています。 JSONやXMLといったファイル形式で、色々なデータを提供してくれるものです。 たとえば、下記のAPIを利用すると、「1070052」の部分を変えると、 どんな郵便番号でも、該当する住所を取得することが出来るようになります。 http://zip.cgis.biz/xml/zip.php?zn=1070052
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | xml < zip_result > < result name = "ZipSearchXML" > </ result > < result version = "1.01" > </ result > < result request_url = "http%3A%2F%2Fzip.cgis.biz%2Fxml%2Fzip.php%3Fzn%3D1070052" > </ result > < result request_zip_num = "1070052" > </ result > < result request_zip_version = "none" > </ result > < result result_code = "1" > </ result > < result result_zip_num = "1070052" > </ result > < result result_zip_version = "0" > </ result > < result result_values_count = "1" > < address_value > < value state_kana = "トウキョウト" > </ value > < value city_kana = "ミナトク" > </ value > < value address_kana = "アカサカ(ツギノビルヲノゾク)" > </ value > < value company_kana = "none" > </ value > < value state = "東京都" > </ value > < value city = "港区" > </ value > < value address = "赤坂(次のビルを除く)" > </ value > < value company = "none" > </ value > </ address_value > </ result > </ zip_result > |
OAuthとは?
APIと似ていてちょっと異なる、OAuthという技術があります。 OAuthは、Facebook API, Twitter API, Googleなど、色々なサービス提供会社が提供しています。 ログインが必要な機能に関するAPIを、認可(authorization)、利用出来るようにするものです。
たとえば、Twitterであれば、 「自分のタイムラインを取得する」 といった行為が、Twitter API上でOAuth認証を行うと、行えるようになります。
ユーザにとっては、よくある以下の様な流れになります。
- 1.サービス上でTwitter連携ボタンを押す
- 2.Twitterで認可しますか?と表示されるので、OKを押す
- 3.元のサービスに戻って、元のサービス上でTwitterの機能を使うことが出来る
システム上は、3の際に、APIの利用に必要な情報(Token等)が取得できます。
この流れがOAuthというオープンプロトコルを利用したAPI認可の標準的な流れです。
オープンソースライブラリ、Rubygemsで簡単にAPIを利用しよう
色々なサービスのOAuthやAPIを使っていこうと思うと、どうしても書くべきプログラミングのコード量が多くなってしまいます。 そんな時に活躍するのが、オープンソースライブラリです。
Ruby言語ですと、「Rubygems」というサイトで多くのライブラリが配布されています。 http://rubygems.org/ Rubyに関連するほとんどのライブラリがこのサイト上で配布されています。 バージョン管理も行われています。 Gemfile(及びBundler)を利用することで、依存関係も自動で対応、非常に簡単に、各種ライブラリを利用することが出来ます。
今回はTwitter APIを利用してみることにします。
今回はTwitter APIを利用するためのRuby言語用ライブラリとして、下記を利用してみます。 twitter | RubyGems.org
ただし、APIの利用にあたっては、下記の4つの情報が必要です。
- 1.CONSUMER_KEY
- 2.CONSUMER_SECRET
- 3.OAUTH_TOKEN
- 4.OAUTH_TOKEN_SECRET
1, 2に関しては Create an application | Twitter Developers から取得できます。
アプリを登録、キーを取得してください。
このとき、アプリの設定でCallback URLを指定するOptionalの欄がありますが、
1 |
など適切な値を指定しておいてください。
3, 4に関しては、OAuth認証が必要です。 Twitter APIに1,2の情報を渡して、ユーザにログインしてもらって、3と4の情報を貰う必要があります。
OAuthは下記のライブラリを使ってみます。 oauth | RubyGems.org
非常にざっくりと、コードに書き起こしてみました。
myapp.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | ruby # myapp.rb require 'sinatra' require 'sinatra/reloader' require 'oauth' require 'twitter' # Sessionの有効化 enable :sessions # Twitter API情報の設定 YOUR_CONSUMER_KEY = "YOUR_CONSUMER_KEY" YOUR_CONSUMER_SECRET = "YOUR_CONSUMER_SECRET" # TwitterAPI ライブラリ 設定(1/2) Twitter.configure do |config| config.consumer_key = YOUR_CONSUMER_KEY config.consumer_secret = YOUR_CONSUMER_SECRET end def oauth_consumer return OAuth::Consumer.new(YOUR_CONSUMER_KEY, YOUR_CONSUMER_SECRET, :site => "https://api.twitter.com") end # トップページ get '/' do "< html >< body >< a href = '/twitter/auth' >Twitter access start!!</ a ></ body ></ html >" end # Twitter認証 get '/twitter/auth' do # callback先のURLを指定する callback_url = "http://localhost:4567/twitter/callback" request_token = oauth_consumer.get_request_token(:oauth_callback => callback_url) # セッションにトークンを保存 session[:request_token] = request_token.token session[:request_token_secret] = request_token.secret redirect request_token.authorize_url #"test" end # Twitterからトークンなどを受け取り get '/twitter/callback' do request_token = OAuth::RequestToken.new(oauth_consumer, session[:request_token], session[:request_token_secret]) # OAuthで渡されたtoken, verifierを使って、tokenとtoken_secretを取得 access_token = nil begin access_token = request_token.get_access_token( {}, :oauth_token => params[:oauth_token], :oauth_verifier => params[:oauth_verifier]) rescue OAuth::Unauthorized => @exception # 本来はエラー画面を表示したほうが良いが、今回はSinatra標準のエラー画面を表示 raise end # TwitterAPI ライブラリ 設定(2/2) Twitter.configure do |config| config.oauth_token = access_token.token config.oauth_token_secret = access_token.secret end # 本来であれば上記情報をDBなどに保存 # タイムラインの情報を取得、表示 "< html >< body >#{Twitter.home_timeline}</ body ></ html >" end |
YOUR_CONSUMER_KEY と YOUR_CONSUMER_SECRET は自分の物に差し替えてください。 前回の記事を読んでくれている方やSinatraの使い方を知っている方は、このコードの使い方もわかるかと思います。
myapp.rbというファイル名で保存して、
1 | ruby myapp.rb |
で実行するだけですね。 使うGem関係は
1 | gem install oauth |
などをもちろんする必要があります。
- 1."/"にユーザからアクセスがくる
- ・トップページが表示されます
2.サービス上でTwitter連携ボタンを押す- ・"/twitter/auth"にアクセスが来ます
- ・「OAuth」の仕様に基づいて、リクエスト(Twitterへの問合せ)が「OAuth::Consumer」によって行われます。
- ・リクエスト結果に問題がなければ、Twitterの画面に遷移します
3.Twitterで認可しますか?と表示されるので、承諾を押す- ・「承諾」を押すと、
callback_url
と指定したURLに、Twitterからリダイレクトされて、ユーザが戻ってきます - ・今回の場合は "/twitter/callback" を指定しているので、こちらのURLに戻ってきます
- ・「承諾」を押すと、
4.元のサービスに戻って、元のサービス上でTwitterの機能を使うことが出来る- ・戻ってきたユーザはOAuthTokenと、Verifierと言われる値を持ってきます。VerifierとToken、リクエストをTwitterに送るときに利用したKeyとSecretKeyを利用すると、OAuthTokenとOAuthTokenSecretが取得できます。この処理は本来はもう少し、暗号化や復号化など、色々な処理が絡んでくるのですが、オープンソース・ライブラリを使うことで、自分では実装する必要なく、実現出来ました。
Sinatra x Ruby x Rubygems
TwitterとOAuth認証して、タイムラインの取得などのAPIを実行、取得、表示。コメント込みで67行。APIとオープンソースライブラリの偉大さを感じるかと思います。APIを実行して、パース(JSONを配列などに変換)して...といった処理は書かなくて済みました。
その他にもTwitterのAPIについてもぜひ使ってみてください。Facebookなども、Rubygemsにライブラリがあります。ぜひ見てみましょう。 RubyGems.org | your community gem host
コードを書かなくて済むよう、
- ・ライブラリがある言語を使う
- ・ライブラリを使うようにする
- ・とはいえ、ライブラリの中身はどのように実装されているかイメージはつくように勉強しておく
という3つを心がけると早くコードが書けるようになるのではと思います。
さらに成長するためには?
今回、オープンソースライブラリを使いましたが、オープンソースライブラリにバグがあることもありますし、欲しい機能がないこともあります。そういう場合は、オープンソースライブラリをFork(自分用にコピー)し、自分でコードを書き換えて、該当のオープンソースライブラリを最初に作った人に、自分が作ったコードを提出(Pull Request)する、という行為をしなければならないかと思います。 この行為をすることが、成長するためにはオススメです。プログラマとは常に面倒くさがりなもの、効率化出来る部分を探すもの。常に改善できる点は探しつつ、それを他の人にも提供、世の中をより良くするようにしてはいかがでしょうか。
あなたが書いたコードが Rubygems で公開、他の方に利用されると思うと、ワクワクしませんか?