[Rails] HTTParty gemによるAPIを簡単に利用できる方法


参考:https://www.coursera.org/learn/ruby-on-rails-intro/

APIのほうは私が最近使っている映画のデータベースを例にします。
https://www.themoviedb.org/documentation/api

HTTPartyとは

  • RESTful Webサービス・クライアント
  • 自動的にJSON・XMLを解析しRuby hashesに変換する(素晴らしいw)
  • サポート: Basic HTTP認証、default request query parameters(共通パラメタex.API key)

APIデータサンプル分析(必要な情報)

まず、見やすくするために、ChromeかFirefoxでJSONViewという拡張をインストールする。
例えばとある映画のデータ:

base uri: https://api.themoviedb.org/3/movie/
parameters(「?」の後ろの部分): api_key=1234abcd&language=ja-JP
リクエストのパラメタによってデータがJSONで返ってくる。URL上ではパラメタごとに「&」で繋いでる

実装手順(例:検索+映画詳細)

準備

Gemfile
gem 'httparty', '0.13.5' #インストールの後サーバ再起動
$ rails g controller movies search show

モデル

app/models/movie.rb
class Movie
  include HTTParty

  # default_options.update(verify: false) # disable SSL verification(必要に応じて)
  default_params api_key: '1234abcd', language: 'ja-JP' #共通パラメタ                 
  format :json

  # キーワードによる検索機能
  # https://developers.themoviedb.org/3/search/search-keywordsに参照
  def self.search term
    base_uri 'https://api.themoviedb.org/3/search/movie'
    get("", query: { query: term }) # {}の中身はパラメタ
  end

  # 指定の映画の詳細情報を取得
  # https://developers.themoviedb.org/3/movies/get-movie-detailsに参照
  def self.details id
    base_uri "https://api.themoviedb.org/3/movie/#{id}"
    get("", query: { } ) #パラメタなし
  end
end

コントローラー

movies_controller.rb
def search
  @search_term = params[:looking_for]
  @movie_results = Movie.search(@search_term)
end

def show
  @movie_info = Movie.details(params[:id])
end

ビュー

search.html.erb
<h1>映画検索</h1>

<div>
  <%= form_tag(movies_search_path, method: :get) do %>
    <%= search_field_tag :looking_for, nil, placeholder: 'Movie Title...' %>
    <%= submit_tag '検索' %>
  <% end %>
</div>

<div>
  <% if @movie_results.blank? %>
    <p>[<%= @search_term %>]と一致する情報が見つかりませんでした</p>
  <% else %>
    <p>[<%= @search_term %>]の検索結果</p>
    <table border="1">
      <tr>
        <th>ポスター</th>
        <th>タイトル</th>
        <th>上映日</th>
        <th>あらすじ</th>
      </tr>
      <% @movie_results.each do |movie| %>
        <tr>
          <td><%= image_tag("https://image.tmdb.org/t/p/w200#{movie["poster_path"]}", :alt => 'poster') %></td>
          <td><%= link_to movie['title'], action: 'show', id: "#{movie["id"]}" %></td>
          <td><%= movie['release_date'] %></td>
          <td><%= movie['overview'] %></td>
        </tr>
      <% end %>
    </table>
  <% end %>
</div>
show.html.erb
<h1><%= @movie_info['title'] %></h1>

<p><strong>上映日:</strong><%= @movie_info['release_date'] %></p>

<p><strong>上映時間:</strong><%= @movie_info['runtime'] %></p>

<p>
    <strong>ジャンル:</strong>
    <% @movie_info['genres'].each do |genre| %>
        <% if genre == @movie_info['genres'].last %>
            <span><%= genre['name'] %></span>
        <% else %>
            <span><%= genre['name'] %></span>
        <% end %>
    <% end %>
</p>

<p><strong>ストーリ:</strong><%= @movie_info['overview'] %></p>

<%= image_tag("https://image.tmdb.org/t/p/original#{@movie_info['poster_path']}", :alt => 'poster') %>

結果画面