使用R&#39的管道工 - 创建GET端点来托管CSV格式的数据,而不是JSON

时间:2018-03-06 22:39:35

标签: json r csv plumber

我认为这是R管道工程师的一个很好的快速演示,但主要是我努力以csv格式提供数据

我正在使用R&P的管道工程序包来托管我的一些体育数据的API端点。目前我有一些数据可以抓住我试图服务的MLB棒球队的总胜场数。使用管道工,我设置了以下2个脚本:

setupAPI.R :使用两个GET端点设置我的API:

library(plumber)
library(jsonlite)

# load in some test sports data to host
mydata = structure(list(Team = structure(c(8L, 20L, 7L, 28L, 2L, 30L, 
23L, 1L, 6L, 19L), .Label = c("Angels", "Astros", "Athletics", 
"Blue Jays", "Braves", "Brewers", "Cardinals", "Cubs", "Diamondbacks", 
"Dodgers", "Giants", "Indians", "Mariners", "Marlins", "Mets", 
"Nationals", "Orioles", "Padres", "Phillies", "Pirates", "Rangers", 
"Rays", "Red Sox", "Reds", "Rockies", "Royals", "Tigers", "Twins", 
"White Sox", "Yankees"), class = "factor"), GamesPlayed = c(162L, 
162L, 162L, 162L, 162L, 162L, 162L, 162L, 162L, 162L), CurrentWins = c(92L, 
75L, 83L, 85L, 101L, 91L, 93L, 80L, 86L, 66L)), .Names = c("Team", 
"GamesPlayed", "CurrentWins"), row.names = c(NA, 10L), class = "data.frame")

# create a GET request for shareprices (in JSON format)
#* @get /shareprices_json
getSPs <- function(){ 
  return(toJSON(mydata))
}

# create a GET request for MLB shareprices (in CSV format)
#* @get /shareprices_csv
csvSPs <- function(){
  return(mydata)
}

# run both functions (i think needed for the endpoints to work)   
getSPs()
csvSPs()

RunAPI.R :plumb的setupAPI.R,获取本地托管的端点

library(plumber)
r <- plumb("setupAPI.R") 
r$run(port=8000)

。 。

在我的控制台中运行RunAPI.R代码后,当我转到端点时,我的http://127.0.0.1:8000/shareprices_csv端点显然正在返回一个JSON对象,而我的http://127.0.0.1:8000/shareprices_json端点似乎是奇怪地返回长度为1的JSON,字符串中的JSON作为返回的JSON中的唯一元素。

简而言之,我现在可以看到我应该简单地返回数据帧,而不是返回JSON(数据帧),以使端点主机JSON格式化数据,然而我仍然不知道如何以CSV格式提供此数据。水管工这可能吗?返回语句在setupAPI.R中的函数中应该是什么样的?任何帮助表示赞赏!!

2 个答案:

答案 0 :(得分:3)

这里有两个技巧:

  1. 您可以通过直接返回响应对象来绕过端点上的序列化。更多文档here
  2. 您可以通过改变res$body
  3. 来指定响应的正文

    您可以将这两个想法结合起来创建一个端点,如:

    #' @get /data.csv
    function(res) {
      con <- textConnection("val","w")
      write.csv(iris, con)
      close(con)
    
      res$body <- paste(val, collapse="\n")
      res
    }
    

    请注意,管道工为您免费提供一些不错的功能,例如为JSON响应设置适当的HTTP标头。如果您自己发送回复,那么您就可以自行完成所有操作,因此您需要确保设置适当的标题以告知API客户端应如何解释此响应。

答案 1 :(得分:3)

如果有人帮助,只需发布​​此答案!

Jeff的反应非常好,但是当你必须返回一个大的CSV文件时,它变得非常慢。我遇到了困难的22 MB文件。

如果您以前在磁盘上写入CSV,更快的解决方案是使用include_file功能(文档here):

举个例子:

#* @get /iris_csv
getIrisCsv <- function(req, res) {
    filename <- "/tmp/iris.csv"
    write.csv(iris, filename, row.names = FALSE)
    include_file(filename, res, "text/csv")
}

所以,这取决于你的用例:

  • 如果你要返回一个小的csv并且你不想把它写到磁盘上:使用Jeff的解决方案
  • 如果您的CSV为中等或大(> 2MB)或已在磁盘上使用:请使用include_file解决方案

希望它有所帮助!