Skip to main content

Routing

expressly provides the Router object which stores configuration for your routing. Create a new router like this:

import { Router } from "@fastly/expressly";

const router = new Router();

💡 Router supports additional configuration.

Creating a route​

Then add a route by calling router.HTTP_METHOD(PATH, handler). Adding a route for GET requests to /hello-world looks like this:

router.get("/hello-world", (req, res) => {
res.send("Hello world!");
});

In the example above, if a request is made to the /hello-world path, your handler will run and return "Hello world!"

What is a handler?​

A handler is the function expressly will call to get a response to send back to the client. It is passed two arguments, the request and the response.

router.post("/", (req, res) => {
res.send("<h1>This is the response!</h1>");
});

🚨 Unlike Express, handlers accept only two arguments, req and res. expressly does away with the next function; uncaught errors are passed to error middleware.

Listening for requests​

After you have configured your routing logic, you must call router.listen() to bind the router to incoming requests.

Hello world!​

import { Router } from "@fastly/expressly";

const router = new Router();

router.get("/", async (req, res) => {
return res.send("Hello world!");
});

router.listen();

Route matching​

HTTP methods​

expressly's router supports the following methods corresponding to HTTP verbs:

MethodHTTP verb
router.get()GET
router.post()POST
router.put()PUT
router.delete()DELETE
router.patch()PATCH
router.head()HEAD
router.options()OPTIONS
router.purge()PURGE

With expressly, you can handle multiple HTTP methods per route:

router.route(["GET", "POST"], "/my-page", async (req, res) => {
return res.send(`You made a ${req.method} request to my page!`);
});

If you want to handle all HTTP methods on one route you can use router.all:

router.all("/dead-end", (req, res) => {
res.end("Nothing to see here!");
});

Route matching​

expressly uses path-to-regexp for pattern-matching routes:

  • router.HTTP_METHOD(PATTERN, handler)
  • router.all(PATTERN, handler)
  • router.route(HTTP_METHOD[], PATTERN, handler)

Wildcards​

You can use wildcard parameters (.*) in order to match multiple URLs with one route.

router.get("/assets/(.*)", (req, res) => {
res.send(`You are visiting: ${req.path}`);
});

🚨 There is no wildcard asterisk (*) in expressly - use parameters instead ((.*) or :splat*).

router.get("(.*)", (req, res) => {
res.send("Hello world!");
});

The above will match GET requests to any path.

Regular expressions​

You can use regular expressions in order to match multiple URLs with one route.

router.get(/.*fly$/, (req, res) => {
res.send(`You are visiting: ${req.path}`);
});

The route path above will match butterfly and dragonfly, but not butterfly-net or flyer.

Path parameters​

You can specify parameters on your routes. The values of these parameters will be parsed and available inside your handler, in the req.params object.

router.get("/profile/:userId", (req, res) => {
let userId = req.params.userId;
res.send(`This is the profile for user ${userId}`);
});

You can use regular expressions to constrain matching rules for parameters.

router.get("/books/:id(\\d+)", (req, res) => {
let bookId = req.params.id;
res.send(`Book ID: ${bookId}`);
});

Custom 404​

For a custom 404 response, you can add a catch-all request handler after all other routes and middleware:

router.all(("(.*)", (req, res) => {
res.status = 404;
return res.send("Page not found!");
});

Alternatively, you can achieve the same using error middleware:

router.use((err, req, res) => {
if (err.status === 404) {
res.send("Page not found!");
}
});

💡 expressly decorates errors with a status property as follows:

  • 404 – when no route was matched for the request path
  • 405 – when a route was found, but the request's HTTP method did not match.