Skip to main content

Code Around Every Handler

Middleware is code that runs around your handlers: before the request reaches them, after the response leaves them, or instead of them. Logging, authentication, rate limiting, compression — all middleware.

The same idea travels under three names: web frameworks say middleware, gRPC says interceptor, some ecosystems say filter. One concept, three vocabularies.

In TypeScript, middleware is a function that takes a handler and returns a wrapped handler — exactly the Decorator pattern from the design patterns group, and a stack of them behaves like a Chain of Responsibility.


A Logging Middleware

withLogging wraps any handler: it prints the request coming in, lets the handler work, and prints again on the way out. The handler itself stays completely unaware.

Real logging usually adds a timestamp and a duration. These examples leave both out on purpose, so the printed output is the same on every run.

Wrap once, log everything

One wrapper around the whole router, and both paths get logged — the logging is written once, in the wrapper, not in every handler.

Prompt
Write a TypeScript program with a withLogging middleware that takes a handler and returns a wrapped handler, printing an arrow line with the method and path before calling the next handler and a done line after. Wrap a small router with two routes, serve it on port 0, request both paths with fetch and print the responses.
Output: TypeScript file and captured output
Wrap once, log everything

Middleware That Stops the Request

Middleware can also refuse: an auth check that finds no valid key writes 401 Unauthorized and never calls the next handler.

Chained as withLogging(withAuth(handler)), the request passes through the layers in order — and the response bubbles back out through them.

An auth layer in the chain

The request without the X-API-Key header is stopped by the auth layer with 401 — the handler never runs. With the key, the request passes the whole chain and reaches the data.

Prompt
Write a TypeScript program with two chained middlewares: withLogging printing the request, and withAuth checking the X-API-Key header and answering 401 without calling the next handler when the key is missing or wrong. Wrap a data handler as withLogging(withAuth(handler)), serve it on port 0, then send one request without the key and one with it, printing both statuses and bodies.
Output: TypeScript file and captured output