5

I want to pass few post parameters in url, say two parameters p1 and p2. Values of p1 and p2 are xyz(string) and 1(numeric). What is difference between following commands:

POST(url, body=list(p1="xyz",p2=1))

OR

POST(url, query=list(p1="xyz",p2=1))

I also cannot understand whether I should use quote for parameters p1 and p2 or not. If yes, then which, single or double.

Kanika Singhal
  • 655
  • 1
  • 9
  • 17

2 Answers2

5

If you're getting started with httr and APIs in general, I would highly recommend that you learn how HTTP requests are structured. One way to do that is empirically, using http://httpbin.org and verbose():

library(httr)

args <- list(p1 = "xyz", p2 = 1)

POST("http://httpbin.org/post", query = args, verbose())
#-> POST /post?p1=xyz&p2=1 HTTP/1.1
#-> Host: httpbin.org
#-> Content-Length: 0

POST("http://httpbin.org/post", body = args, verbose())
#-> POST /post HTTP/1.1
#-> Host: httpbin.org
#-> Content-Length: 232
#-> Expect: 100-continue
#-> Content-Type: multipart/form-data; boundary=---03a3f580d7af2b29
#-> 
#>> ---03a3f580d7af2b29
#>> Content-Disposition: form-data; name="p1"
#>> 
#>> xyz
#>> ---03a3f580d7af2b29
#>> Content-Disposition: form-data; name="p2"
#>> 
#>> 1
#>> ---03a3f580d7af2b29--

You'll notice the way that the data is sent is quite different. With query the data is encoded in the query part of url, and with body its sent in the body of the HTTP request.

Different values of the encode argument send the data in different ways:

POST("http://httpbin.org/post", body = args, verbose(), encode = "form")
#-> POST /post HTTP/1.1
#-> Host: httpbin.org
#-> Content-Type: application/x-www-form-urlencoded
#-> Content-Length: 11
#-> 
#>> p1=xyz&p2=1

POST("http://httpbin.org/post", body = args, verbose(), encode = "json")
#-> POST /post HTTP/1.1
#-> Host: httpbin.org
#-> Content-Type: application/json
#-> Content-Length: 19
#-> 
#>> {"p1":"xyz","p2":1}

(I removed the User-Agent, Accept-Encoding and Accept headers from each example because they're the same in each case, and not germane to the question)

hadley
  • 102,019
  • 32
  • 183
  • 245
1

The answer likely depends on what the server is expecting. I would think in many cases, it wouldn't matter; but it would depend on the server.

The second (query) version, is just like calling: POST(paste0(url, "?p1=xyz&p2=1")), whereas the first (body) version passes the parameters as key-value pairs in the body of the HTTP request.

Thomas
  • 43,637
  • 12
  • 109
  • 140
  • I think the fact that many servers interpret them the same way isn't relevant - the HTTP requests are quite different – hadley Sep 23 '15 at 16:19