Reputation: 21
I am trying to build a API with Plumber (v0.4.6). I want to use several .R files (one for each function/endpoints of the API) to avoid making one huge .R file with all functions. It work fine with only one .R file using :
pr <- plumb("api/v1/plumber.R")
pr$run()
But when I try to split the plumber file into two separate files, the mounted endpoints does not shows :
root <- plumber$new("api/v1/plumber.R")
test <- plumber$new("api/v1/fct1.R")
root$mount("/test", test)
root$run()
It is weird because root$mounts
shows all the endpoints and the API shows only the root's ones (plot and sum) :
# Plumber router with 2 endpoints, 5 filters, and 1 sub-router.
# Call run() on this object to start the API.
├──[queryString]
├──[postBody]
├──[cookieParser]
├──[sharedSecret]
├──[logger]
├──/plot (GET)
├──/sum (POST)
├──/test
│ │ # Plumber router with 1 endpoint, 4 filters, and 0 sub-routers.
│ ├──[queryString]
│ ├──[postBody]
│ ├──[cookieParser]
│ ├──[sharedSecret]
│ └──/test8 (GET)
Here is the code of the two files :
library(plumber)
#* @apiTitle Plumber Example API
#* Plot a histogram
#* @png
#* @get /plot
function() {
rand <- rnorm(100)
hist(rand)
}
#* Return the sum of two numbers
#* @param a The first number to add
#* @param b The second number to add
#* @post /sum
function(a, b) {
as.numeric(a) + as.numeric(b)
}
#* Echo back the input
#* @param msg The message to echo
#* @get /test8
function(msg = "") {
list(msg = paste0("The message is: '", msg, "'"))
}
Thanks for your help.
Upvotes: 1
Views: 423
Reputation: 1399
The solution/explanation is here: https://community.rstudio.com/t/functions-within-a-sourced-file-are-not-accessible-as-plumber-api-endpoints/64266 or here: https://github.com/rstudio/plumber/issues/533
One way how to achieve it:
It is also possible to create a new file (e.g. api.R
) and put all the endpoints there( + name the functions in the sourced files). Doing so we also separate the functions from the API, e.g.:
api.R (a new file):
# plumber.R
source("./main.R")
#* Echo back the input
#* @param msg The message to echo
#* @get /echo
function(msg) {
main.echo(msg)
}
#* Return "hello world"
#* @get /hello
function(){
functions.hello()
}
main.R (similar to plumber.R in OP's question):
source("./functions.R")
main.echo = function(msg=""){
list(msg = paste0("The message is: '", msg, "'"))
}
functions.R (similar to fct1.R in OP's question):
functions.hello = function(){
"hello world"
}
And then
library(plumber)
pr = plumb("api.R")
pr$run()
And then both /echo
and /hello
endpoints are accessible.
Upvotes: 0
Reputation: 776
This is fixed in the dev version I believe. It is was mainly a plumber openapi file generation problem as your endpoints would still respond if you used httr or curl to send a request.
devtools::install_github("rstudio/plumber")
Upvotes: 1