ambiorix-web / ambiorix

🖥️ Web framework for R
http://ambiorix.dev
GNU General Public License v3.0
211 stars 9 forks source link

Issue with parsing request body #36

Closed psolymos closed 3 years ago

psolymos commented 3 years ago

Hi John, good start on the abiorix package! I checked it out and run into 2 issues when parsing the request body.

(1) 1st thing is easy: parse_json is not exported, so add #' @export to R/parser.R.

(2) But even when I used ::: still got ERROR: attempt to apply non-function. Here is what I had for my Hello World example:

library(ambiorix)

app <- Ambiorix$new()

handle <- function(req) {
  body <- ambiorix:::parse_json(req)
  paste0('Hello ', body, '!')
}

app$post('/', function(req, res){
  res$json(handle(req))
})

app$start()

Maybe it is a content type issue, but something is definitely not right here. Thanks!

JohnCoene commented 3 years ago

That will depend on the form that is POSTed from the browser. There is an example here.

If that does not help, could you share with me more about that form?

psolymos commented 3 years ago

I'd like to be able to

curl http://localhost:3000 -H 'Content-Type: application/json' -d '["Friend"]'

and get ["Hello Friend!"].

I understand the GET quiery type requests, the part that is unclear to me is how to set the content type for the body in ambiroix. I can do it in httpuv, plumber, beakr, firery, RestRserve, I am curious how to do it in your package! Thanks.

psolymos commented 3 years ago

Here is the httpuv example:

library(httpuv)
library(jsonlite)

handle <- function(req) {
  input <- req[["rook.input"]]
  postdata <- input$read_lines()
  jsonlite::toJSON(paste0("Hello ", fromJSON(paste(postdata)), "!"))
}

httpuv::runServer(
  host = "0.0.0.0",
  port = 3000,
  app = list(
    call = function(req) {
      list(
        status = 200L,
        headers = list(
          'Content-Type' = 'application/json'
        ),
        body = handle(req)
      )
    }
  )
)
JohnCoene commented 3 years ago

Sorry for the late response, it's hectic on my end.

Your initial attempt using parse_json was correct; the function, however, was wrong. I have fixed it using more or less what you provided here in handle(), thank you!

library(ambiorix)

app <- Ambiorix$new(port = 3000)

app$post('/', function(req, res){
  data <- parse_json(req)
  pkg <- list(data = data, "Something")
  res$json(pkg)
})

app$start()

With the new version from Github the above works. If you want to remain on CRAN version:

library(ambiorix)

app <- Ambiorix$new(port = 3000)

handle <- function(req, ...){
  data <- req$body[["rook.input"]]
  data <- data$read_lines()
  jsonlite::fromJSON(data, ...)
}

app$post('/', function(req, res){
  data <- handle(req)
  pkg <- list(data = data, "Something")
  res$json(pkg)
})

app$start()
psolymos commented 3 years ago

No worries, thanks for the fix!