メモ:httr::GET()にリクエストボディを指定したいときはhttr::VERB("GET", ...)で

たまーにGET()にリクエストボディを指定したいときがあります。

そもそもGETリクエストにリクエストボディを含めるのは、RFCでも奥歯にものが挟まったような書き方がされています。ダメならダメってはっきり言ってくれればいいのに。。

A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
(https://tools.ietf.org/html/rfc7231#section-4.3.1)

まあぼやいてもしょうがないのでやりかたを調べましょう。

まず、POST()の場合を見てみます。リクエストの内容はresponseオブジェクトのrequest以下に保存されています。ボディはrequest$options$postfieldsです。 (これいい見方があるんでしょうか。いつもよく分からずこんな感じで調べてるんですけど…)

library(httr)

res <- POST("http://example.com", body = list(a = 1), encode = "json")

res$request$options$postfields
#> [1] 7b 22 61 22 3a 31 7d

raw型で保存されているのでrawToChar()をかませば文字列として読むことができます。

cat(rawToChar(res$request$options$postfields))
#> {"a":1}

一方、GETはどうかというと、

res <- GET("http://example.com", body = list(a = 1), encode = "json")
names(res$request$options)
#> [1] "useragent" "cainfo"    "httpget" 

そもそもpostfieldsがありません。

じゃあどうすればいいかというと、VERB()を使います。

res <- VERB("GET", "http://example.com", body = list(a = 1), encode = "json")
res$request$method
#> [1] "GET"

cat(rawToChar(res$request$options$postfields))
#> {"a":1}

ばっちりですね。いつも忘れてググるのでここにメモ。