异步POST请求 - R,使用RCurl?

时间:2015-08-25 03:01:01

标签: r asynchronous rcurl httr

我正在尝试从R对REST API发出异步请求。下面的curl命令说明了传递给api所需的参数。我告诉你们linux curl命令,因为我希望能说清楚:

curl -v -X POST https://app.example.com/api/ \
-H 'Authorization: somepwd' \
-H "Content-Type: application/json" \
-d {key1: value1, key2: value2}

现在,我通过执行以下操作在R中完成同样的事情:

library(httr)
library(jsonlite)
content(POST('https://app.example.com/api/'
                    ,add_headers(Authorization = 'somepwd') 
                    ,body = toJSON(rDataFrame)
                    ,content_type_json()
             )
        )

目标是从R提交上述POST请求,但要更改正文中发送的json字符串,并执行异步

我一直在寻找可以帮助我发出异步请求的软件包,而不是按顺序发出请求。我能找到的最接近的是来自RCurl包(https://cran.r-project.org/web/packages/RCurl/RCurl.pdf)的getURIAsynchronous()函数,但是不了解如何使用它们的函数提交带有标题和正文的PUT请求。我真的想从R做出上面的POST请求但是异步地在哪里URI是相同的,但是发送的数据对于每个请求是不同的。

我发现了http://www.omegahat.org/RCurl/concurrent.html

getURIs =
function(uris, ..., multiHandle = getCurlMultiHandle(), .perform = TRUE)
{
  content = list()
  curls = list()

  for(i in uris) {
    curl = getCurlHandle()
    content[[i]] = basicTextGatherer()
    opts = curlOptions(URL = i, writefunction = content[[i]]$update, ...)    
    curlSetOpt(.opts = opts, curl = curl)
    multiHandle = push(multiHandle, curl)
  }

  if(.perform) {
     complete(multiHandle)
     lapply(content, function(x) x$value())
   } else {
     return(list(multiHandle = multiHandle, content = content))
   }
} 

我的想法是,我可以将for (i in uris)替换为for(i in jsons),我将循环显示要发送到同一网址的不同数据,但是我无法理解以下概念RCurl套餐:

  1. 如何将标头作为PUT请求的一部分传递。如何在请求正文中传递数据?如上所述,使用httr包非常简单。

  2. 我尝试传入curl选项中的标题,或者标题。问题是我不知道在哪里传递post请求的组成部分:getURIAsynchronous()函数中的身份验证,标题和正文,或者我上面描述的任何资源。

  3. 有谁知道如何做到这一点?一个例子将是非常有帮助的。

1 个答案:

答案 0 :(得分:4)

最近更新了curl个包以处理异步请求(see here

使用curlmagrittrjsonlite个包,您可以通过以下方式创建异步邮件请求:

  • 使用handle_setform函数
  • 创建包含标题和正文内容的通用句柄
  • 编写回调函数以检索结果
  • 初始化池并向其添加并发请求
  • 通过multi_run
  • 运行您的游泳池

示例代码如下:

library(curl)
library(jsonlite)
library(magrittr)

#create a handle object
h <- new_handle() %>%
handle_setheaders(Authorization = "somepwd",
                  "Content-Type" = "application/json") %>%
  handle_setform(body = toJSON(iris))

pool <- new_pool()
# results only available through call back function
cb <- function(req){cat("done:", req$url, ": HTTP:", req$status, "\n", "content:", rawToChar(req$content), "\n")}

# example vector of uris to loop through
uris <- c("https://app.example.com/api/endpoint1"
          ,"https://app.example.com/api/endpoint2"
          ,"https://app.example.com/api/endpoint3")

# all scheduled requests are performed concurrently
sapply(uris, curl_fetch_multi, done=cb, pool=pool)

# This actually performs requests
out <- multi_run(pool = pool)