6.2.4. Middlewares

In this chapter, you’ll learn about middlewares and how to create them.

What is a Middleware?#

A middleware is a function executed when a request is sent to an API Route. It's executed before the route handler function.

Middlwares are used to guard API routes, parse request content types other than application/json, manipulate request data, and more.

Tip: As Local Protocol's server is based on Express, you can use any Express middleware .

How to Create a Middleware?#

Middlewares are defined in the special file src/api/middlewares.ts. Use the defineMiddlewares function imported from @localprotojs/localproto to define the middlewares, and export its value.

For example:

src/api/middlewares.ts
1import { defineMiddlewares } from "@localprotojs/localproto"2import type { 3  LocalProtoNextFunction, 4  LocalProtoRequest, 5  LocalProtoResponse, 6} from "@localprotojs/framework/http"7
8export default defineMiddlewares({9  routes: [10    {11      matcher: "/custom*",12      middlewares: [13        (14          req: LocalProtoRequest, 15          res: LocalProtoResponse, 16          next: LocalProtoNextFunction17        ) => {18          console.log("Received a request!")19
20          next()21        },22      ],23    },24  ],25})

The defineMiddlewares function accepts a middleware configurations object that has the property routes. routes's value is an array of middleware route objects, each having the following properties:

  • matcher: a string or regular expression indicating the API route path to apply the middleware on. The regular expression must be compatible with path-to-regexp.
  • middlewares: An array of middleware functions.

In the example above, you define a middleware that logs the message Received a request! whenever a request is sent to an API route path starting with /custom.


Test the Middleware#

To test the middleware:

  1. Start the application:
  1. Send a request to any API route starting with /custom.
  2. See the following message in the terminal:
Terminal
❯Received a request!

When to Use Middlewares#

Use middlewares when: 
  • You want to protect API routes by a custom condition.
  • You're modifying the request body.

Middleware Function Parameters#

The middleware function accepts three parameters:

  1. A request object of type LocalProtoRequest.
  2. A response object of type LocalProtoResponse.
  3. A function of type LocalProtoNextFunction that executes the next middleware in the stack.
Important: You must call the next function in the middleware. Otherwise, other middlewares and the API route handler won’t execute.

Middleware for Routes with Path Parameters#

To indicate a path parameter in a middleware's matcher pattern, use the format :{param-name}.

For example:

src/api/middlewares.ts
6} from "@localprotojs/framework/http"7
8export default defineMiddlewares({9  routes: [10    {11      matcher: "/custom/:id",12      middlewares: [13        // ...14      ],15    },16  ],17})

This applies a middleware to the routes defined in the file src/api/custom/[id]/route.ts.


Restrict HTTP Methods#

Restrict which HTTP methods the middleware is applied to using the method property of the middleware route object.

For example:

src/api/middlewares.ts
6} from "@localprotojs/framework/http"7
8export default defineMiddlewares({9  routes: [10    {11      matcher: "/custom*",12      method: ["POST", "PUT"],13      middlewares: [14        // ...15      ],16    },17  ],18})

method's value is one or more HTTP methods to apply the middleware to.

This example applies the middleware only when a POST or PUT request is sent to an API route path starting with /custom.


Request URLs with Trailing Backslashes#

A middleware whose matcher pattern doesn't end with a backslash won't be applied for requests to URLs with a trailing backslash.

For example, consider you have the following middleware:

Code
6} from "@localprotojs/framework/http"7
8export default defineMiddlewares({9  routes: [10    {11      matcher: "/custom",12      middlewares: [13        (14          req: LocalProtoRequest, 15          res: LocalProtoResponse, 16          next: LocalProtoNextFunction17        ) => {18          console.log("Received a request!")19
20          next()21        },22      ],23    },24  ],25})

If you send a request to http://localhost:9000/custom, the middleware will run.

However, if you send a request to http://localhost:9000/custom/, the middleware won't run.

In general, avoid adding trailing backslashes when sending requests to API routes.

Was this chapter helpful?