rexyai / RestRserve

R web API framework for building high-performance microservices and app backends
https://restrserve.org
275 stars 32 forks source link

Problem with jsonlite in POST request #155

Closed AThibault92 closed 4 years ago

AThibault92 commented 4 years ago

Hello,

I'm trying to transfer my plumber API function to RestRserve, but I have a problem with POST request. I used jsonlite to convert a dataframe into a json, and then, I use it to convert json back to a dataframe in the API in my old Plumber API. But it doesn't work with RestRserve (I guess I missed something, but I don't know where...)

Here is a small exemple :

library(RestRserve)

foo <- function(x, y){
  coef <- cor(x,y)
  return(coef)
}

foo_handler <- function(request, response){
  rq_body <- request$body
  data <- jsonlite::fromJSON(rq_body)
  res <- coef(data$Sepal.Length, data$Petal.Length)
  response$body <- res
  response$set_content_type("application/json")
}

app = Application$new()

app$add_post(path = "/cor", FUN = foo_handler)

request = Request$new(method = "POST",
                      path = "/cor",
                      content_type = "application/json",
                      body = jsonlite::toJSON(iris)
)
response <- app$process_request(request)

response$body

And it gave me this error :

{"timestamp":"2020-06-18 14:11:40.660989","level":"ERROR","name":"Application","pid":6272,"msg":"","context":{"request_id":"d502cf40-b15c-11ea-b488-89b4a8774cb8","message":{"error":"Argument 'txt' must be a JSON string, URL or file.","call":"NULL","traceback":["FUN(request, response)","data = jsonlite::fromJSON(rq_body)","stop(\"Argument 'txt' must be a JSON string, URL or file.\")","base::stop(..., call. = FALSE)"]}}}

Have you any clues how to solve this ?

dselivanov commented 4 years ago

The body is already parsed from JSON as you specify content_type = "application/json" in the request. Application by default is initialized with EncodeDecodeMiddleware which handles application/json and text/plain out of the box. I suggest to read related article on the RestRserve website.

Also you can always interactively debug your app:

library(RestRserve)

foo <- function(x, y){
  coef <- cor(x,y)
  return(coef)
}

# for debug
request_debug = NULL

foo_handler <- function(request, response){
  # for debug
  request_debug <<- request

  rq_body <- request$body
  data <- jsonlite::fromJSON(rq_body)
  res <- coef(data$Sepal.Length, data$Petal.Length)
  response$body <- res
  response$set_content_type("application/json")
}

app = Application$new()

app$add_post(path = "/cor", FUN = foo_handler)

request = Request$new(method = "POST",
                      path = "/cor",
                      content_type = "application/json",
                      body = jsonlite::toJSON(iris)
)
response <- app$process_request(request)

Now you can interactively inspect request_debug

request_debug