プログラム関係の備忘録。技術系記事1000記事以上を目指すブログ

Rails APIからPOSTリクエストで結果を取得する

  • 2019年5月14日
  • 2020年6月14日
  • Ruby
  • 2765view
  • 0件

はじめに

前回の記事でRails APIモードでのアプリ作成をやってみました。
少しいじって書き方がわかってきたの備忘録としてメモ。

Rails&Grapeを使ってAPIの踏み台サーバーを作る

住所検索APIを叩いて結果をJSONで返す

さくっとできるAPIリクエストとしてよく利用させてもらっている郵便番号から住所を検索するAPI。RailsアプリからこのAPIを叩いて結果を返すというサンプルをやっています。(そのまま返しているのでRails APIを通している意味がない。あくまでもサンプルとして)

require 'net/http'

~~

# [POST] /api/vi/api_test
# curl command sample
# curl -X POST -H "Content-Type: application/json" -d '{"zipcode":"0790177", "limit":"1"}' localhost:3000/api/v1/api_test

post '/api_test' do
reqParams = URI.encode_www_form({zipcode: params[:zipcode],"limit" => params[:limit]})
uri = URI.parse("http://zipcloud.ibsnet.co.jp/api/search?#{reqParams}")
@query = uri.query

response = Net::HTTP.start(uri.host, uri.port) do |http|
http.open_timeout = 5
http.read_timeout = 10
http.get(uri.request_uri)
end

begin
case response
when Net::HTTPSuccess
@result = JSON.parse(response.body)

when Net::HTTPRedirection
@message = "Redirection: code=#{response.code} message=#{response.message}"
else
@message = "HTTP ERROR: code=#{response.code} message=#{response.message}"
end

# エラー時処理
rescue IOError => e
@message = "e.message"
rescue TimeoutError => e
@message = "e.message"
rescue JSON::ParserError => e
@message = "e.message"
rescue => e
@message = "e.message"
end

{
status: 'ok',
data: @result,
}
end

3行目にあるCurlコマンドをRailsAPIに叩くとjson形式で結果がかえってくるのが確認できます。

ちょっとした小ネタ

Rails初なのでわからないことだらけですが、こんな風に書けるのねっていうのもあったのでこれもメモ。

POSTされたパラメータのバリデーション

params do
    requires :hoge, type: String
    requires :fuga, type: Integer, values: 0..99999999
end

上記例では、hogeは文字列で、fugaは数値で0~99999999までを受け付けるようにすることができます。

数値を文字列に変換

ものすごい初歩的ですが。

num = 123.to_s

楽ちんだーー。

httpsでのリクエスト

httpsでのリクエストを叩くときには、先ほどの「 require ‘net/http’ 」ではなく「 require ‘net/https’ 」を使う。

post '/test' do

payload = "id=testdayo"

uri = URI.parse("https://〇〇〇//")

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.ca_file = "/usr/lib/ssl/cert.pem"

# デバッグ用
http.set_debug_output $stderr

req = Net::HTTP::Post.new(uri.path, initheader = {'Content-Type' =>'application/x-www-form-urlencoded'})
req.body = payload       
res = http.request(req)
res.body.force_encoding("UTF-8")

end

ちょっとハマった。
証明書の場所を見つけられないといったエラーがでたり、レスポンスのボディが文字化けしているせいでエラーがでたり。

プレーンテキストなんかをUTF-8に変換するのは以下の部分でした。

res.body.force_encoding("UTF-8")