net/httpパッケージで簡単なpostリクエストを送ろうとして調べていたら混乱したのでメモ。
(Ruby: ver2.6.3で試した)
調べていくとおおまかに2種類の書き方があった。
1つ目がNet::HTTP#post
を使う方法。
require "net/http"
require "json"
uri = URI.parse("http://localhost:8000/")
params = { foo: "bar" }
req = Net::HTTP.new(uri.host, uri.port)
req.post(uri.path, params.to_json)
もう1つがNet::HTTP::Post
のインスタンスを作成し、Net::HTTP#request
でリクエストする方法。
require "net/http"
require "json"
uri = URI.parse("http://localhost:8000/")
params = { foo: "bar" }
http_req = Net::HTTP.new(uri.host, uri.port)
post_req = Net::HTTP::Post.new(uri.path)
post_req.set_form_data(params: params.to_json)
http_req.request(post_req)
どう違うかわからなかったのでサーバ立ててリクエストを確認した。
サーバについては、以下の記事中のコードをそのまま利用させていただいた。
Ruby 標準ライブラリの WEBrick で Web サーバを作る
サーバ起動後、前述のコードを実行したときのリクエストがこんな感じになった。
# 1つ目
POST / HTTP/1.1
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept: */*
User-Agent: Ruby
Connection: close
Host: localhost:8000
Content-Length: 13
Content-Type: application/x-www-form-urlencoded
{"foo":"bar"}
# 2つ目
POST / HTTP/1.1
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept: */*
User-Agent: Ruby
Content-Type: application/x-www-form-urlencoded
Connection: close
Host: localhost:8000
Content-Length: 34
params=%7B%22foo%22%3A%22bar%22%7D
リクエストボディに渡るデータの形式が異なった。
-
Net::HTTP#post
の場合は、JSONがそのままリクエストボディとして渡された。 -
Net::HTTP::Post
インスタンスを利用したNet::HTTP#request
の場合は、URLエンコードされたハッシュがkey=value
の形式で渡された。
というわけでリクエストボディへのデータの渡され方が異なった。
docを見る限りpostは文字列データ、set_from_dataは文字通りフォームのデータを送る感じなので、用途とかによって使い分けていけばいいんだろうか?