Run app
cd
into the05_router/
dir:cd 05_router/
There are 2 directories there:
box/
&r_pkg_structure/
.cd
into any of them, say,r_pkg_structure/
:cd r_pkg_structure/
Fire up R:
R
Restore package dependencies:
::restore() renv
Once done, exit R.
server.R
is the entry point. To start the app, run this on the terminal:Rscript index.R
Explanation
This app starts a server and listens on port 3000 for connections.
It has two endpoints:
/api/members
/api/members/:id
Routing refers to how an application’s endpoints (URIs) respond to client requests.
For an introduction to routing, see 03_basic_routing.
If you look at 04_simple_json_api you’ll notice that the routes we created all belong to /api/members
and we kept repeating that base/root route.
Wouldn’t it be nice to only have to use /
and /:id
and have ambiorix prepend the /api/members
automatically?
That would give you a better app structure making it manageable.
Enter ambiorix::Router()
.
Use the ambiorix::Router
class to create modular, mountable router handlers.
A Router
instance is a complete middleware and routing system; for this reason, it is often referred to as a “mini-app”.
Using the example 04_simple_json_api, this is how we would transform it:
# members.R
<- \() {
members_router <- Router$new("/members")
router
# get all members:
$get("/", \(req, res) {
router# ...
})
# get a single member:
$get("/:id", \(req, res) {
router# ...
})
# create a new member:
$post("/", \(req, res)) {
router# ...
}
# update member:
$put("/:id", \(req, res) {
router# ...
})
# delete member:
$delete("/:id", \(req, res) {
router# ...
})
router }
The server.R
file would now be:
library(ambiorix)
# <bring/import the members.R file>
<- 3000
PORT
<- Ambiorix$new()
app
# mount the router:
$use(members_router())
app
$start(port = PORT, open = FALSE) app
Keep this in mind:
Ambiorix is unopinionated. As such, it is up to you to decide how you want to bring/export the members.R
file into index.R
.
Some options are:
- Use box (Highly recommended, ⭐⭐⭐⭐⭐) especially if you develop large apps/systems, for two reasons:
- Allows nested files, folders & modules (a big win)
- Explicit name imports ie. you’re almost always sure from which package a function is from.
- Use R package structure (Recommended, ⭐⭐⭐⭐). Will not allow nested folders but will work really well for small to medium apps.
source()
files (NOT recommended, 1⭐). Haha. Iykyk.
Choose wisely.
Multiple routers
Learn how you can mount ✨multiple routers✨.