The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.
Two audiences land here: people coming from Shiny (reactive server) and people porting a plumber v1 API (aurora targets plumber2 only). This covers both shifts.
| Shiny | aurora |
|---|---|
| Reactive server holds state per user | Stateless: state lives in the client or an external store |
ui <- fluidPage(...) |
build_ui() returns an htmltools/bslib tag, compiled to
static HTML |
server <- function(input, output) {...} |
routers/*.R — plumber2 handlers returning JSON |
reactive() / observe() |
JS fetch (aurora.json(...)) + DOM updates
in app.js |
input$x |
request query / body / path params |
output$y <- render*() |
a JSON response a handler returns |
renderPlot/renderDT widgets |
client-side libraries (ECharts, MapLibre, DataTables) fed by
/api |
| shinyapps.io / Connect, sticky sessions | Docker / ShinyProxy, horizontally scalable |
What you keep: the bslib UI transfers almost verbatim. What changes: server logic becomes JSON endpoints, and you write some JavaScript to render. What you gain: no per-user R process, trivial horizontal scaling, CDN-cacheable UI.
A reactive value that recomputed when an input changed becomes: a DOM
event → aurora.json("api/...") → update the DOM. Read-only
datasets that you loaded once at app start map onto
aurora_data_store() (see
vignette("aurora")).
plumber2 is API-incompatible with plumber. The five changes that actually bite:
Only path parameters (<var> in
the annotation) become named arguments. Read the query string from the
reserved query argument and a parsed body from
body.
req/res become reqres
request/responseThe reserved handler arguments are request,
response, query, body,
server, client_id — not
req/res. Translation table:
| Need | plumber v1 | plumber2 / reqres |
|---|---|---|
| Path param | named arg (:var) |
named arg (<var>) |
| Query value | named arg | query$x |
| Parsed body | req$body$x |
body$x (needs @parser json) |
| Request method / path | req$REQUEST_METHOD / req$PATH_INFO |
request$method / request$path |
| A request header | req$HTTP_X_FOO |
request$get_header("X-Foo") |
| Cookies | parse req$HTTP_COOKIE by hand |
request$cookies$name (auto-parsed) |
| Set status | res$status <- 401 |
response$status <- 401L |
| Set header | res$setHeader(n, v) |
response$set_header(n, v) |
| Set / clear cookie | manual Set-Cookie |
response$set_cookie(...) /
response$clear_cookie() |
| Abort with a code | res$status <- n; return(...) |
reqres::abort_unauthorized() /
abort_bad_request() |
| Continue / stop chain | forward() / return() |
return plumber2::Next /
plumber2::Break |
| Logging | cat() |
server$log("message", ...) |
Note: reqres set_cookie(same_site=) wants
"Lax"/"Strict"/"None"
(capitalised). length-1 vectors are not auto-unboxed by
the json serializer, so scalars serialize as 1-element
arrays — jsonlite::unbox() them where a scalar is required
(or use a dedicated serializer like geojson).
@filter / preempt /
forward()Removed. Use a route chain instead: a header-route
handler (@header) runs before the body and can reject
early; return Next to continue or Break to
stop; throw reqres::abort_*() to fail with a status.
aurora’s auth template uses exactly this for its
/api/* guard (see vignette("auth")).
pr_*() → api_*() (not 1:1)pr()/pr_mount() → api() +
api_parse(); pr_static() →
api_assets(); pr_hook("exit", ...) →
api_on("end", ...). aurora already does this assembly for
you in aurora_app().
v1 mounted a router under a prefix; aurora bakes the full path into
the annotation (#* @get /api/iniciativas/data).
aurora_add_route() writes it for you; porting a mounted v1
router means rewriting each annotation to its full path.
pa$test_request(fiery::fake_request(url, method=, content=, headers=))
runs a request through the assembled API without binding a port — handy
for fast, deterministic checks while you port.
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.