Routing
Adding Routes
H3 app instance has a built in router system to register routes matching patterns with parameter or specific HTTP method.
Example: Register a route to match requests to the /hello
endpoint with HTTP GET method:
// Method 1: using app.[method]
app.get("/hello", () => "Hello world!");
// Method 2: using app.on(method)
app.on("GET", "/hello", () => "Hello world!");
You can register multiple event handlers for the same route with different methods:
app
.get("/hello", () => "GET Hello world!")
.post("/hello", () => "POST Hello world!");
You can also use app.all
method to register a route accepting any HTTP method:
app.all("/hello", (event) => `This is a ${event.req.method} request!`);
Route Params
You can define parameters in your routes using :
prefix:
app.get("/hello/:name", (event) => {
return `Hello ${event.context.params.name}!`;
});
In this example, the name
parameter will be available in the event.context.params
object.
If you send a request to /hello/world
, the event handler will respond Hello world!
.
Instead of named params, you can use *
for unnamed and optional params:
app.get("/hello/*", (event) => `Hello!`);
Catch-all param
Adding /hello/:name
route will match /hello/world
or /hello/123
. But it will not match /hello/foo/bar
.
If you need to match multiple levels of sub routes, you can use **
prefix:
app.get("/hello/**", (event) => `Hello ${event.context.params._}!`);
This will match /hello
, /hello/world
, /hello/123
, /hello/world/123
, etc.
_
will store the full wildcard content as a single string.Adding Middleware
You can register middleware handlers to app instance using the app.use
.
Example: Register global middleware that calls on every route.
app.use((event) => {
console.log(event);
});
Example: Register routed middleware that matches specific routes only starting with the prefix /blog
(i.e. /blog
, /blog/world
, /blog/123
, etc.).
app.use("/blog/**", (event) => {
console.log(event);
});
- Global
onRequest
hook will be always called before - Global middleware registered without route pattern will always be called by the order of registration before any other handler.
- Routed middleware with route pattern, will be called after global middleware by the order of less to the most specific pattern.
- If no middleware handles response, normal router method matcher will be used.
You can define multiple middleware.
app.use(() => "First");
app.use(() => "Second");
In the example above, the first event handler will be called for every request and the second one will never be called.
However, if you do not return a response from the first event handler, the second one will be called. This is useful to have a middleware pattern.
app.use((event) => {
console.log("First");
});
app.use((event) => {
console.log("Second");
});
If all handlers get called and no response is returned, h3 will continue with the main router handlers.