We are using RPlumber to host an API, and our developers asked that the API endpoints provide data in a CSV format, rather than JSON. To handle this, we have the following:
r_endpoints.R
#* @get /test-endpoint-1
testEndpoint <- function(res) {
mydata <- data.frame(a = c(1,2,3), b = c(3,4,5))
print('mydata')
print(mydata)
con <- textConnection("val","w")
print(paste0('con: ', con))
write.csv(x = mydata, con, row.names = FALSE)
close(con)
print('res and res.body')
print(res);
res$body <- paste(val, collapse="\n")
print(res$body)
return(res)
}
#* @get /test-endpoint-2
testEndpoint2 <- function() {
mydata <- data.frame(a = c(1,2,3), b = c(3,4,5))
return(mydata)
}
run_api.r
library(plumber)
pr <- plumber::plumb("r_endpoints.R")
pr$run(host = "0.0.0.0", port = 8004)
test-endpoint-2
returns the data in a JSON format, whereas test-endpoint-1
returns the data in a CSV format. When these endpoints are run locally on my mac, and when I hit the endpoints, I receive the following correct output:
To host the API, we've installed R + the libraries + pm2 on a Linode Ubuntu 16.04 server, and installed all (I think all) of the dependencies. When we try to hit the endpoints as hosted on the server, we receive:
Here are the print statements that I've added to test-endpoint-1
to help with debugging:
[1] "mydata"
a b
1 1 3
2 2 4
3 3 5
[1] "con: 3"
[1] "res and res.body"
<PlumberResponse>
Public:
body: NULL
clone: function (deep = FALSE)
headers: list
initialize: function (serializer = serializer_json())
removeCookie: function (name, path, http = FALSE, secure = FALSE, same_site = FALSE,
serializer: function (val, req, res, errorHandler)
setCookie: function (name, value, path, expiration = FALSE, http = FALSE,
setHeader: function (name, value)
status: 200
toResponse: function ()
[1] "\"a\",\"b\"\n1,3\n2,4\n3,5"
These are the correct print statements - the same that we get locally. For some reason, the server will not allow us to return in a CSV format in the same way that my local machine allows, and I have no idea why this is the case, or how to fix it.
Edit
After updating the plumber
library on my local machine, I now receive the error An exception occurred.
on my local machine as well. It seems, in the newer version of plumber, that the snippet of code I use to convert the API endpoint output to a CSV file:
...
con <- textConnection("val","w")
write.csv(x = mydata, con, row.names = FALSE)
close(con)
res$body <- paste(val, collapse="\n")
return(res)
no longer works.
Edit 2
Here's my own stackoverflow post from nearly 3 years ago on how to return the data as a CSV... seems to no longer work.
Edit 3
Using @serialize csv does "work", but when I hit the endpoint, the data is downloaded as a CSV onto my local machine, whereas it would be better for the data to simply be returned in a CSV format from the API, but not automatically downloaded into a CSV file...
Maybe look into this for inspiration, here I'm modifying responses content-type headers to text/plain. text/plain should display in the browser I believe.