Hi all, I'm trying to use shinyApp()
's uiPattern
parameter, but having no good luck. And though I understand fundamentally what's happening, I'm struggling to find a good path to correct my errors (apart from forking and editing Shiny code itself, which I'd like not to do).
I'm running a Shiny app via Shiny Server, and I'd like for the single R process (i.e. the "app") to handle two different request paths: /app
and /ok
. The /ok
path simply returns a health check response (which itself is a collection of data fetched from the app's global scope). The /ok
caller knows what to do with those data. That response is handled in the UI using the functional UI variation, like so:
ui <- function(req) {
if (req$PATH_INFO == "ok") return(health_response())
fluidPage(...) ## else return the normal Shiny UI
}
The /app
path should start a Shiny session.
Shiny Server is configured with a location
directive like so:
location / {
app_dir /my/app/dir;
log_dir /my/app/dir/log;
}
... i.e. Shiny Server matches on the path prefix of /
anything and sends that down to the Shiny app.
The Shiny app is launched via:
shinyApp(ui = my_ui, server = my_server, uiPattern = "^(ok/?|app/?)"
... and this, to some extent, works. In particular, the /ok
requests return my health check response as expected. And in fact the initial /app
request also returns the initial Shiny 'shell' page. The problem is that page then tries to fetch all the required components ... the Shiny JS library, the Bootstrap JS and CSS files, FontAwesome files, etc. Those requests have a path structure of /app/some-additional-resource.js
, which unfortunately 404s.
Essentially, by setting Shiny Server to route /
to the app, the app now receives all the additional resource requests, too, which normally would be handled by the Shiny (server-side) framework, not application code. I haven't been able to find a good example of how to handle this 'distinct-path' routing issue with uiPattern
, but the presence of that parameter alone seems to suggest this is doable. Has anyone had luck with something like this, or can point me to a decent working example? Joe Cheng's example here -- which inspired this idea in the first place -- describes this usage abstractly, but doesn't mention how resource paths are then handled.