箱のプログラミング日記。

渋谷の自社開発企業でRails書いてます。

Railsでhttps通信を使ってjsonでPOSTする

f:id:y_hakoiri:20191102121704j:plain

Railsのアプリケーションでhttpsリクエストを走らせ、jsonでPOSTしたい時の記事があまり無かったので書いておく。

完成形を先に

class Sample
  require 'net/https'
  require 'uri'
  require 'json'

  def post_message
    uri = URI.parse("https://www.y-hakopro.com/articles")
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE

    message = "hogeeeeeeeeeeeee"

    http.start do
      req = Net::HTTP::Post.new(uri.path)
      req.set_form_data(body: message)
      http.request(req)
    end
  end
end

httpもしくはhttps通信に関しては「Rails」「http」とかってググると結構たくさん記事はあって、もうお決まりのおまじないみたいな感じでどこにでも書いてあることなんだけど、何がどうなってるかを細かくみていく。

https通信

そもそもhttps(http)通信はクライアントがリクエストを走らせてレスポンスが返るという大前提を踏まえて、

require 'net/https'
require 'uri'

リクエストやレスポンスのインスタンスを作るためnet/httpsuriをrequireする

pry(main)> uri = URI.parse("https://www.y-hakopro.com/articles")
#<URI::HTTPS https://www.y-hakopro.com/articles>

URIオブジェクトを作成。

ここでparseとしておくことで、このあとuriをホストやポート番号やパスに区切って使えるようになる。

pry(main)> uri.host
=> "www.y-hakopro.com"

pry(main)> uri.port
=> 443

こんな感じに。

で、次

pry(main)> http = Net::HTTP.new(uri.host, uri.port)
=> #<Net::HTTP www.y-hakopro.com:443 open=false>

www.y-hakopro.com443を渡してNet::HTTPオブジェクトを作成。

http.use_ssl = true

この記述によりhttps通信ができるようになる。これは見たまんま。

http.verify_mode = OpenSSL::SSL::VERIFY_NONE

ローカル環境から実行したい場合はこの記述によりSSL証明書の発行をすっ飛ばす。

これがないとローカルからリクエストが行かない。検証のためにもローカルで実行できた方が良いので書いておく

jsonでPOST

require 'json'

とりあえずrequire

http.start do
  req = Net::HTTP::Post.new(uri.path)
  req.set_form_data(body: message)
  http.request(req)
end

ここでPOSTする。

同じように細かく見ていきます

req = Net::HTTP::Post.new(uri.path)
=> #<Net::HTTP::Post POST>

まずPOSTリクエストを作成

ちなみに

pry(main)> uri.path
=> "/articles"

まあ当たり前か。笑

次の一行

pry(main)> req.set_form_data(body: message)
=> "application/x-www-form-urlencoded"

ここで重要なのがset_form_data

今回は実はapiを使用したのだけど、api側の指定でContent-Typeapplication/x-www-form-urlencodedを指定する必要があった。

リクエストに対してset_form_dataメソッドを渡すことでこれを実現できる。

set_form_data

ヘッダフィールド Content-Type: には 'application/x-www-form-urlencoded' が設定されます。

引用元: module Net::HTTPHeader (Ruby 2.7.0 リファレンスマニュアル)

あとは作成したリクエストを投げるだけ。

http.request(req)

返り値はレスポンスなので、このあとレスポンスコードとか取得して何かしらしたい場合は代入してもよし。

res = http.request(req)
res.code

成功したらres.codeで201が返ってくる。

参考

Net::HTTP Cheat Sheet

railsで任意のURLにJSONをPOSTする方法 - Edy | Enjoy, delight, and yolo

class Net::HTTP (Ruby 2.7.0 リファレンスマニュアル)

net/httpsでWebAPIにPOSTリクエストを投げる - Qiita

Net::HTTPHeader#form_data= (Ruby 2.7.0 リファレンスマニュアル)