Basepath in Valum
I have recently introduced a basepath
middleware and I thought it would be
relevant to describe it further.
It’s been possible, since a while, to compose routers using subrouting. This is very important to write modular applications.
var app = new Router ();
var user = new Router ();
user.get ("/user/<int:id>", (req, res, next, ctx) => {
var id = ctx["id"] as string;
var user = new User.from_id (id);
res.extend_utf8 ("Welcome %s", user.username);
});
app.rule ("/user", user.handle);
Now, using basepath
, it’s possible to design the user
router without
specifying the /user
prefix on rules.
This is very important, because we want to be able to design the user
router
as if it were the root and rebase it on need upon any prefix.
var app = new Router ();
var user = new Router ();
user.get ("/<int:id>", (req, res) => {
res.extend_utf8 ("Welcome %s".printf (ctx["id"].get_string ()))
});
app.use (basepath ("/user", user.handle));
How it works
When passing through the basepath
middleware, request which have
a prefix-match with the basepath are stripped and forwarded.
But there’s more!
That’s not all! The middleware also handle errors that set the Location
header from Success.CREATED
and Redirection.*
domains.
user.post ("/", (req, res) => {
throw new Success.CREATED ("/%d", 5); // rewritten as '/user/5'
});
It also rewrite the Location
header if it was set directly.
user.post ("/", (req, res) => {
res.status = Soup.Status.CREATED;
res.headers.replace ("Location", "/%d".printf (5));
});
Rewritting the Location
header is exclusively applied on absolute paths
starting with a leading slash /
.
It can easily be combined with the subdomain
middleware to provide
a path-based fallback:
app.subdomain ("api", api.handle);
app.use (basepath ("/api/v1", api.handle));