Rails APIを使ってみる(郵便番号)


YoutubeでAPIを叩く動画があって、とてもわかりやすかったので
ハンズオンで行いつつ、わからないところなどは
深堀りして調べ記事を書いていこうと思います。

特に何かを読み込む必要とかないので
きちんとURLをparseすることができれば、使える

動作環境

ruby 2.5.1p57
Rails 5.2.4.4

APIとは…

API:(Application Programming Interface)…
Interface → アプリの機能を利用するための窓口になる部分

通常Web上に公開されていて、無料で誰でも使うことができる
自分のソフトウェアに他のソフトウェアの機能を埋め込むことができるようになる

APIは、外部のアプリケーションと連携するための機能のこと

APIを叩くとは…APIを使ってデータを取りにいくこと
返ってくるデータは、JSON形式のテキスト

メリット

より多くの新しいサービスと開発できる
→ある機能に特化させたり、さらに使いやすく一部の機能だけ改良することも可能
データを二次利用できる
→他社のデータを使うことができ、情報を分析することが簡単にできる
効率的に開発できる
→作りたい機能がAPIで公開されているなら、同じプログラムを1から作る必要がない
サービス利用者の利便性がアップする
→他社のユーザー情報を使って、ログインできる機能を作ることができる
セキュリティの向上
→セキュリティーレベルの高い企業のシステムを使うことができる

実際に使ってみよう

お約束

rails new アプリ名

で、Searchesコントローラーを作成する、アクション名は、「search」

rails g controller searches search

ルーティングを記述する

config/routes.rb
Rails.application.routes.draw do
  get 'search', to: 'searches#search'
end

フォームを作成

次は、viewの修正

app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>郵便番号検索</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <div class="container">
      #getで送信する
      <%= form_with url: search_path, method: :get, local: true do |f| %>
        <%= f.text_field :postal_code, class: "search_form", placeholder: "郵便番号を入力してください" %>
      <% end %>
      <%= yield %>
    </div>
  </body>
</html>

【ポイント】
・form_withメソッドは、デフォルトでajaxの非同期通信を行っている。
そのため、local: true オプションをつけないとHTMLをレンダリングしてくれない
<%= f.text_field :postal_code %>の部分でパラメータ名を指定する
→ コントローラーで、「params[:postal_encode]」とすると取得することができる
placeholderでフォームの中にあるデフォルトの文字を入れておく

コントローラー実装

次は、コントローラーの中身の実装をしていく

app/controllers/searches.controller.rb
class SearchsController < ApplicationController
  # require 'net/http'

  def search
    # フォームで送られたパラメータを取得する
    if postal_code = params[:postal_code]
      # ここでエンコードする。URI.encode_www_formメソッドで、URLの末尾に「zipcode=郵便番号」を作っている
      params = URI.encode_www_form({zipcode: postal_code})
      # これでURLを取得する、paramsは変数なので展開する必要あり
      uri = URI.parse("https://zipcloud.ibsnet.co.jp/api/search?#{params}")
      # レスポンスを取得している、GET![スクリーンショット 2020-12-18 23.46.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431899/9b912f6a-f11b-5065-73e6-909459901403.png)

      response = Net::HTTP.get_response(uri)
      # JSON形式に変換
      if result = JSON.parse(response.body)
        #viewで使用するために、インスタンス変数に格納
        #レスポンスで、都道府県名や、市区町村を指定して取得する
        @zipcode = result["results"][0]["zipcode"]
        @address1 = result["results"][0]["address1"]
        @address2 = result["results"][0]["address2"]
        @address3 = result["results"][0]["address3"]
      end
    end
  end
end

URI.encode_www_formメソッド
encodeとは…文字などのある形式のデータを一定の規則に従って
別の形式のデータに変換すること

完成形の画面

【完成版の画面はこちらです】
そのままURLを叩いて、郵便番号を挿入するだけでこの結果が返ってきます

取得した結果を表示するviewの方も作成していく

app/searches/search.html.erb
<p>郵便番号: <%= @zipcode %></p>
<p>都道府県: <%= @address1 %></p>
<p>市区町村: <%= @address2 %></p>
<p>町域: <%= @address3 %></p>

実際の画面はこんな感じです

エラーがでたら

エラーがでる場合があったのですが、
コントローラーで「require 'net/http'」すれば解決しました。
また、GETで表示するだけなら、上の読み込み(require)だけでいいそう
https://docs.ruby-lang.org/ja/latest/library/net=2fhttp.html

参考動画