APIの新規作成[2]
APIの実装
APIの実装を進めます。
まず、今回のAPIに必要なrack-cors、mechanizeという2つのgemを追加でインストールします。rack-corsは、ドメインが違うサーバー間での通信(クロスドメイン通信)を許可する処理をRailsアプリに簡単に入れることができるものです。mechanizeは、Google画像検索結果のHTMLの構造を解析(スクレイピング)する処理を簡単に記述できるようにするものです。
rack-corsについてはAPIモードでRailsアプリを新規作成するとGemfileにコメントアウトされた状態で記述されているので、このコメントを外します。mechanizeは追記します。
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible gem 'rack-cors' gem 'mechanize'
bundle installを実行してgemを追加します。
bin/bundle inst
クロスドメイン通信を許可するコードを追加します。
…(中略)… config.middleware.insert_before 0, Rack::Cors do allow do origins '*' resource '*', :headers => :any, :methods => [:get, :post, :options] end end …(中略)…
rack-corsが提供するDSLであるallowブロックで、ドメインをまたいだリクエストを受け付ける処理を定義しています。
次に、imagesコントローラーを新規作成します。
bin/rails g controller images
↓
Running via Spring preloader in process 27450 create app/controllers/images_controller.rb invoke test_unit create test/controllers/images_controller_test.rb
APIモードのRailsアプリ上では、ジェネレーターコマンドでコントローラーを新規作成した場合、対応するビューファイルが自動生成されないことが実行結果から分かります。
APIは/images/検索語句形式のリクエストをimagesコントローラーのindexアクションに割り振るようにルーティングを設定します。
Rails.application.routes.draw do get '/images/:q', to: 'images#index' end
imagesコントローラーにリスト6の通り、処理を追加します。
class ImagesController < ApplicationController def index page = Mechanize.new.get "https://www.google.co.jp/search?q=#{params[:q]}&tbm=isch" image_path = page.at('img').get_attribute :src render json: { image_path: image_path } end end
mechanizeを使ったWebサイトスクレイピングの方法については本題とは異なるため、詳細な解説は省略します。indexアクションの1行目でGoogle画像検索結果にアクセスし、2行目で検索結果の1番目にきたimgタグのsrc属性を取得し、3行目で取得した画像パスをJSONで返却しています。
APIの動作確認
APIの実装が完了したら動作を確認しましょう。ローカルPC上でチャットアプリのRailsとAPIのRailsの両方を動かすので、APIはポートを3001番で起動するようにオプションを指定してRailsを起動します。
bin/rails s -p 3001
curlコマンドでAPIを実行してみましょう。
curl localhost:3001/images/rails
↓
{"image_path":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTtSXRSk7CYS9bpVi3_WVKI3wdil3em46wI0ch5S5pCrDP5i3mMIvwM_bc"}
正常に動作している場合、上記のようなJSONが返却されます。これでAPI側の開発は一通り完了です。