🗑️

Faraday.deleteでquery stringでなくrequest bodyにパラメータを渡す方法

2023/08/05に公開

結論

以下のように書けば、request bodyにパラメータを渡せる。

Faraday.delete('http://localhost:8000') do |req|
  req.body = { name: 'Alice' }.to_json
end

Faradayとは

これ。
https://github.com/lostisland/faraday

調査

byebugを使ってどういうrequestが構築されるのかを見ながら調査していった。
POSTは以下のように使うらしい。

Faraday.post('http://localhost:8000', { name: 'Alice' }.to_json)
# (byebug) request
# #<struct Faraday::Request http_method=:post, path="http://localhost:8000", params={}, headers={"User-Agent"=>"Faraday v2.7.10"}, body="{\"name\":\"Alice\"}", options=#<Faraday::RequestOptions (empty)>>

DELETEも同様に渡せば良いのかと思いきや、NoMethodErrorになる。

Faraday.delete('http://localhost:8000', { name: 'Alice' }.to_json)
# ..../lib/faraday/utils/params_hash.rb:28:in `update': undefined method `each' for "{\\"name\\":\\"Alice\\"}":String (NoMethodError)

調べてみるとFaraday.deleteの第二引数はhashが渡される想定っぽかった。
https://www.rubydoc.info/github/lostisland/faraday/Faraday%2FConnection.delete

以下のようにhashを渡すとエラーはなくなったが、request bodyでなくquery stringにパラメータが渡されてしまった。
今回直面したケースでは、サーバ側がquery stringでなくrequest bodyでパラメータを受け付けるよう実装になっていたので、これでは使えなかった。

Faraday.delete('http://localhost:8000', { name: 'Alice' })
# (byebug) request
# #<struct Faraday::Request http_method=:delete, path="http://localhost:8000", params={"name"=>"Alice"}, headers={"User-Agent"=>"Faraday v2.7.10"}, body=nil, options=#<Faraday::RequestOptions (empty)>>
# (byebug) exclusive_url
# #<URI::HTTP http://localhost:8000?name=Alice>

以下のissueやドキュメントを参考に、以下のように実装したら無事request bodyにパラメータを入れることが出来た。
https://github.com/lostisland/faraday/issues/693
https://lostisland.github.io/faraday/#/getting-started/quick-start?id=detailed-http-requests

Faraday.delete('http://localhost:8000') do |req|
  req.body = { name: 'Alice' }.to_json
end
# (byebug) request
# #<struct Faraday::Request http_method=:delete, path="http://localhost:8000", params={}, headers={"User-Agent"=>"Faraday v2.7.10"}, body="{\"name\":\"Alice\"}", options=#<Faraday::RequestOptions (empty)>>

補足

HTTPのDELETEメソッドはそもそもrequest bodyでパラメータの受け渡しをして良いの?という話はあるかもしれない。
調査したところ、「普通はquery string。サーバ側の実装がrequest bodyでパラメータを受け付けてないかもしれないから、推奨はしない。でもRFC的にはrequest bodyによるパラメータ受け渡しを禁止もしてない」って感じでした。
https://stackoverflow.com/questions/299628/is-an-entity-body-allowed-for-an-http-delete-request

Discussion