【问题标题】:HTTR package POST command not returning json from REST APIHTTR 包 POST 命令未从 REST API 返回 json
【发布时间】:2015-07-11 14:31:06
【问题描述】:

我在将 R 连接到应用程序的 REST API 时遇到问题。

我可以使用 RCurl 包的 getURL 函数从 REST API 调用命令,如下所示,效果很好。

RESTQuery = paste0(MyBaseURL,MyRESTQuery)
RESTHeader = c(
    paste0("Host:",MyServerIP,":",MyServerPort),
    paste0("Authorization:Basic ",MyEncodedToken),
    "Connection: keep-alive"
)
RESTResult = getURL(URL=RESTQuery,httpheader=RESTHeader,verbose=true)

这个 RESTResult 然后可以用 fromJSON(RESTResult) 解析,效果很好。

但是,我找不到发送包含标头的 POST RCurl 请求的等效方法,因此我移至 httr 包来发送 POST 请求。以下代码有效,但 fromJSON 函数返回错误:

RESTQuery = paste0(MyBaseURL,MyRESTQuery)
RESTPOSTHeader = c(
    'Content-Type'="application/json; charset=utf-8",
    'Authorization'=paste0("Basic ",MyEncodedToken),
    'Accept'="application/json"
)
RESTPOSTBody = c(
    "$expand=Axes,Cells"
)
RESTResult <- POST(RESTQuery,query=RESTPOSTBody,add_headers(RESTPOSTHeader),verbose())

返回的值是从 REST API 正确返回的,但它们似乎没有被格式化为 JSON,因此我无法将它们解析为一个好的数据帧。以下是详细模式下查询返回的代码:

-> User-Agent: curl/7.39.0 Rcurl/1.95.4.5 httr/0.6.1
-> Host: <My server>:<My Port>
-> Accept-Encoding: gzip
-> Cookie: SessionId=NMD-MavwPL_QhdHFMRyhZQ
-> Content-Type: application/json; charset=utf-8
-> Authorization: Basic <My Encoded Token>
-> Accept: application/json
-> Content-Length: 0
-> 
<- HTTP/1.1 201 Created
<- Content-Length: 944
<- Connection: keep-alive
<- Content-Encoding: gzip
<- Cache: no-cache
<- Content-Type: application/json;odata.metadata=minimal;odata.streaming=true; charset=utf-8
<- Location: ../../Cellsets('sIYzNM4HAIAGAAAg')
<- OData-Version: 4.0
<- Set-Cookie: SessionId=7V5XAXXjwfbaXmdOb3FgJQ; Path=/api/; HttpOnly

以及我使用内容(RESTResult)时的值:

> content(RESTResult)
$`@odata.context`
[1] "../../$metadata#Cellsets(Axes(Hierarchies+(Name),Tuples+(Members(Name))),Cells)/$entity"

$ID
[1] "sIYzNM4HAIAGAAAg"
$Axes
$Axes[[1]]
$Axes[[1]]$Ordinal
[1] 0
$Axes[[1]]$Cardinality
[1] 3
$Axes[[1]]$Hierarchies
$Axes[[1]]$Hierarchies[[1]]
$Axes[[1]]$Hierarchies[[1]]$Name
[1] "Period_General"
$Axes[[1]]$Tuples
$Axes[[1]]$Tuples[[1]]
$Axes[[1]]$Tuples[[1]]$Ordinal
[1] 0
$Axes[[1]]$Tuples[[1]]$Members
$Axes[[1]]$Tuples[[1]]$Members[[1]]
$Axes[[1]]$Tuples[[1]]$Members[[1]]$Name
[1] "all periods"

$Cells
etc.............

当我尝试使用 fromJSON 对其进行格式化时,如果我尝试以下任何一种操作,则会收到错误消息“Argument 'txt' must be a JSON string, URL or File”:

  • 来自JSON(RESTResult)
  • fromJSON(content(RESTResult))
  • fromJSON(content(RESTResult)$Cells)

所以,我有点坚持以下几点:

  1. 如何使用 RCurl 包发送 POST 请求 或
  2. 如何使用 HTTR 包 POST 命令从 REST API 检索正确的 JSON 结果?

我是否设置了错误的标题,或者做了一些非常愚蠢的事情?任何建议都会很棒! 谢谢!!

【问题讨论】:

  • 我错了content(RESTResult) 的输出是你想要的,但它已经被解析了吗?也就是说,如果你想遍历结果中的“Axes”,你会做for (axis in content(RESTResult)$Axes) {...
  • 如果你想得到 JSON,你可以先j &lt;- toJSON(content(RESTResult)),然后fromJSON(j)。但这只是将其直接转换为 JSON,然后再将其转回!
  • 我觉得有点奇怪的原因是我从 getURL 查询返回的结果格式非常好,但也许你是对的,并且已经完成了一些解析!学习如何使用 RCurl 包执行此操作也很酷,这样我就可以进行直接比较,但无论我尝试什么,我都无法让 RCurl 包处理我的 POST 请求。
  • 我一般会推荐 httr 而不是 RCurl,它提供了更多选项和更强大的界面。但是,如果您想获得具有该格式的文本输出,请尝试content(RESTResult, type = "text")
  • 谢谢大卫,我会试试看!我要试试,如果我没有得到什么,我会回来!

标签: json r api rest


【解决方案1】:

感谢 cmets 的 David Robinson 对我最初的问题的帮助,这个问题现在已经解决了。

为了解决这个问题,使用 fromJSON() 函数的格式化结果,将查询结果解析为文本,然后使用 fromJSON 函数。

RESTResult <- POST(RESTQuery,query=RESTPOSTBody,add_headers(RESTPOSTHeader),verbose())
RESTResultParsed <- fromJSON(content(RESTResult,type="text"))

结果是一个非常好的列表,然后您可以使用标准函数对其进行操作。

【讨论】:

  • 我很高兴你解决了你的问题,但除非我弄错了(也许我错了!)fromJSON(content(RESTResult,type="text"))content(RESTResult) 之间没有区别。这是将列表转换为 JSON,然后无缘无故地返回列表:就像做 sqrt(x^2) 而不仅仅是 x
  • 这两个结果是不同的,因为 fromJSON 函数将结果放入正确命名的列表中,而不是以前的样式输出,所以对我来说更容易处理。不管怎样,它现在工作得很好,所以谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-01
  • 2020-07-02
  • 2015-03-14
相关资源
最近更新 更多