Plumber with additional arguments

I would like to run plumber API with additional arguments. I've created following function:

run_api <- function(api, config_args = list(), ...) {

  api <- match.arg(api, c("api1", "api2"))
  api_directory <- system.file("plumber", api, package = "my_pkg")

  x <- plumber::plumb(dir = api_directory)

  invisible(
    mapply(
      assign,
      names(config_args),
      config_args,
      MoreArgs = list(envir = x$environment)
    )
  )
  x$run(...)
}

Function adds specified arguments to router environment. Is there any convenient way to retrieve these arguments?

From api endpoint it seems that they can be retrieved by specifying parent.env(environment()) for environment in functions like ls, get, mget. For example:

#* Check if API is Running
#* @get /status
function(){
  print(ls(parent.env(environment())))
  TRUE
}

But if endpoint calls another function and that function wants to retrieve these arguments then this way of retrieving becomes more convoluted.

Is there any 'good practice' way of running plumber API with additional arguments (something similar to golem way of running shiny app with additional arguments)?

After trying few things I've managed to find solution by adding:

options(API_ENVI = environment())

at start of plumber.R script with endpoints and then use getOption("API_ENVI") for envir argument in get/mget functions. Still interesting is there some other more practical way of doing this.

1 Like

Probably because the router function is defined within the environment that has the variable available on the search path. Other function, defined somewhere else (like in a package), do not have them available in their search path because they have been defined outside the router environment.

It seems like you are trying to use globals? Have you tried defining them in the .Global environment instead of the router environment?

Could you create a function that returns your parameters when wanted?

Wondering how these config_args are used down the pipe.

API is implemented as R package. In inst folder I have configuration file - config.yaml. Sometimes I want to run API with different configuration arguments so I want to overwrite them by passing additional arguments to run_api function instead of changing them in configuration. Currently I'm retrieving configuration arguments with:

getConfigArgs <- function(args = NULL, envir = getOption("API_ENVI")){

  initial_values <- readConfig()

  if(is.null(args))
    args <- names(initial_values)

  stopifnot(args %in% names(initial_values))

  my_args <- mget(
    x = args,
    envir = envir,
    ifnotfound = initial_values[args],
    inherits = FALSE
  )

  if(length(my_args) == 1) my_args[[1]] else my_args
}

where readConfig reads config.yaml file.

This is currently just convenience for testing purposes. Once the API is deployed in docker its configuration can be changed by mounting local configuration file when starting docker container. I'm just interested is this something possible and if so what would be best way of implementing it.

For this type of use case, we use environment variable internally.

Retrieved via Sys.getenv().