I found the if the parameter name in the @param field is the same as the one in the dynamic route (e.g. @param mypar1 and then @get /prediction/<mypar1> and then function(mypar1)), plumber fails on p$run() with the error:
Error in if (type == "bool" || type == "logical") { :
missing value where TRUE/FALSE needed
This is not the case for non-dynamic routes, and can be fixed by changing the @param to anything else.
Example below. Full code can be found at this repository.
library(plumber)
# @param ticket; @get /prediction; function(ticket)...
p1 <- plumb("not_dyn_samenames.R")
# Works:
p1$run(port=8001)
# @param tick; @get /prediction/<ticket>; function(ticket)...
p2 <- plumb("dyn_diffnames.R")
# Works
p2$run(port=8002)
# @param ticket; @get /prediction/<ticket>; function(ticket)...
p3 <- plumb("dyn_samenames.R")
# DOES NOT WORK
p3$run(port=8003)
We had a similar error for a roughly similar scenario, but I just tried now and cannot replicate your DOES NOT WORK scenario I am afraid. Such a not so useful error message.
OK I will see if I can isolate the problem. In the mean time, here is my session info.
(I updated all packages today as well, still the same error)
R version 3.5.0 (2018-04-23)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)
Matrix products: default
locale:
[1] LC_COLLATE=English_Australia.1252 LC_CTYPE=English_Australia.1252
[3] LC_MONETARY=English_Australia.1252 LC_NUMERIC=C
[5] LC_TIME=English_Australia.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] plumber_0.4.6
loaded via a namespace (and not attached):
[1] compiler_3.5.0 magrittr_1.5 R6_2.2.2 promises_1.0.1 later_0.7.2 tools_3.5.0
[7] rstudioapi_0.7 Rcpp_0.12.17 crayon_1.3.4 stringi_1.2.2 jsonlite_1.5 httpuv_1.4.3
The problem occurs in extractSwaggerParams (swagger.R):
for (p in names(endpointParams)){
location <- "query"
if (p %in% pathParams$name){
location <- "path"
}
type <- endpointParams[[p]]$type
if (is.null(type) || is.na(type)){
if (location == "path") {
type <- plumberToSwaggerType(pathParams[pathParams$name == p,"type"])
} else {
type <- "string" # Default to string
}
}
If the @param field and dynamic route have the same name, location will be set to path, and an attempt is made to run plumberToSwaggerType but this fails because type is NA.
If the @param field and dynamic routes have different names location will be query, and type will be defaulted to string.
If someone wants to check for reproducibility, this is the definition for dyn_samenames.R :
#* Retrieve prediction for ticket
#* @param ticket Ticket number to retrieve
#* @get /prediction/<ticket>
#* @json
function(ticket){
list(ticket = ticket,
prediction = as.Date(Sys.time()))
}
and then run it as:
p <- plumb("dyn_samenames.R")
p$run(port=8888)
Right! My bad, having suffered from exactly the same error, you are right:
Is @param value meant to be processed?
I cannot do a PR, you should kindly do it @RemkoDuursma
Similar to #273
I believe this is fixed in master branch.
Running reprex above...
Can get
~: curl http://127.0.0.1:8888/prediction/3
{"ticket":["3"],"prediction":["2019-07-11"]}
and have swagger info of
鉂澂 p$swaggerFile() %>% jsonlite::toJSON(pretty = TRUE)
{
"openapi": ["3.0.2"],
"info": {
"description": ["API Description"],
"title": ["API Title"],
"version": ["1.0.0"]
},
"paths": {
"/prediction/{ticket}": {
"get": {
"summary": [" Retrieve prediction for ticket"],
"responses": {
"default": {
"description": ["Default response."]
}
},
"parameters": [
{
"name": ["ticket"],
"description": ["Ticket number to retrieve"],
"in": ["path"],
"required": [true],
"schema": {
"type": ["string"]
}
}
]
}
},
"/openapi.json": {
"get": {
"responses": {
"default": {
"description": ["Default response."]
}
},
"parameters": []
}
},
"/swagger.json": {
"get": {
"responses": {
"default": {
"description": ["Default response."]
}
},
"parameters": []
}
},
"/__swagger__/index.html": {
"get": {
"responses": {
"default": {
"description": ["Default response."]
}
},
"parameters": []
}
},
"/__swagger__/": {
"get": {
"responses": {
"default": {
"description": ["Default response."]
}
},
"parameters": []
}
}
}
}
Please submit a new issue if the problem still exists.
Most helpful comment
The problem occurs in
extractSwaggerParams(swagger.R):If the
@paramfield and dynamic route have the same name,locationwill be set to path, and an attempt is made to runplumberToSwaggerTypebut this fails becausetypeis NA.If the
@paramfield and dynamic routes have different nameslocationwill bequery, and type will be defaulted tostring.If someone wants to check for reproducibility, this is the definition for
dyn_samenames.R:and then run it as: