Updating the Headers
The following middleware demonstrate how to interact with or modify a Response.
NOTE
Contrary to some middleware patterns out there, universal middlewares do not use a next()
function. Instead, a middleware can return a function that will take the response as its first parameter.
ts
// src/middlewares/headers.middleware.ts
import type { Get, UniversalMiddleware } from "@universal-middleware/core";
// This middleware will add a `X-Universal-Hello` header to all responses
const headersMiddleware = (() => (request, ctx) => {
return (response) => {
// `ctx.hello` exists if it has been set by another middleware
response.headers.set("X-Universal-Hello", ctx.hello ?? "world");
return response;
};
// Using `satisfies` to not lose return type
}) satisfies Get<[], UniversalMiddleware<{ hello?: string }>>;
// export default is mandatory
export default headersMiddleware;
After bundling and publishing this middleware, one can then use this middleware as follows:
ts
import handler from "@universal-middleware-examples/tool/dummy-handler-hono";
import contextMiddleware from "@universal-middleware-examples/tool/middlewares/context-middleware-hono";
import headersMiddleware from "@universal-middleware-examples/tool/middlewares/headers-middleware-hono";
import paramsHandler from "@universal-middleware-examples/tool/params-handler-hono";
import compress from "@universal-middleware/compress/hono";
import { Hono } from "hono";
const app = new Hono();
// Now the universal context contains `{ hello: "World!!!" }`.
// See /examples/context-middleware
app.use(contextMiddleware("World!!!"));
// After a Response has been returned by the handler below,
// the `{ "X-Universal-Hello": "World!!!" }` header is appended to it
app.use(headersMiddleware());
app.use(compress());
app.get("/user/:name", paramsHandler());
app.get("/", handler());
export default app;
ts
import handler from "@universal-middleware-examples/tool/dummy-handler-h3";
import contextMiddleware from "@universal-middleware-examples/tool/middlewares/context-middleware-h3";
import headersMiddleware from "@universal-middleware-examples/tool/middlewares/headers-middleware-h3";
import paramsHandler from "@universal-middleware-examples/tool/params-handler-h3";
import compress from "@universal-middleware/compress/h3";
import { universalOnBeforeResponse } from "@universal-middleware/h3";
import { createApp, createRouter, toNodeListener } from "h3";
import { args } from "./utils";
const app = createApp({
// /!\ This is required for universal-middleware to operate properly
onBeforeResponse: universalOnBeforeResponse,
});
// Now the universal context contains `{ hello: "World!!!" }`.
// See /examples/context-middleware
app.use(contextMiddleware("World!!!"));
// After a Response has been returned by the handler below,
// the `{ "X-Universal-Hello": "World!!!" }` header is appended to it
app.use(headersMiddleware());
app.use(compress());
const router = createRouter();
router.get("/user/:name", paramsHandler());
router.get("/", handler());
app.use(router);
const port = args.port ? Number.parseInt(args.port) : 3000;
const { createServer } = await import("node:http");
createServer(toNodeListener(app)).listen(port, "localhost", () => {
console.log(`Server listening on http://localhost:${port}`);
});
ts
import { createServer } from "@hattip/adapter-node";
import { createRouter } from "@hattip/router";
import handler from "@universal-middleware-examples/tool/dummy-handler-hattip";
import contextMiddleware from "@universal-middleware-examples/tool/middlewares/context-middleware-hattip";
import headersMiddleware from "@universal-middleware-examples/tool/middlewares/headers-middleware-hattip";
import paramsHandler from "@universal-middleware-examples/tool/params-handler-hattip";
import compress from "@universal-middleware/compress/hattip";
import { args } from "./utils";
const app = createRouter();
// Now the universal context contains `{ hello: "World!!!" }`.
// See /examples/context-middleware
app.use(contextMiddleware("World!!!"));
// After a Response has been returned by the handler below,
// the `{ "X-Universal-Hello": "World!!!" }` header is appended to it
app.use(headersMiddleware());
app.use(compress());
app.get("/user/:name", paramsHandler());
app.get("/", handler());
const hattipHandler = app.buildHandler();
const port = args.port ? Number.parseInt(args.port) : 3000;
createServer(hattipHandler).listen(port, () => {
console.log(`Server listening on http://localhost:${port}`);
});
ts
import handler from "@universal-middleware-examples/tool/dummy-handler";
import contextMiddleware from "@universal-middleware-examples/tool/middlewares/context-middleware";
import headersMiddleware from "@universal-middleware-examples/tool/middlewares/headers-middleware";
import paramsHandler from "@universal-middleware-examples/tool/params-handler";
import { createHandler } from "@universal-middleware/cloudflare";
import { pipe } from "@universal-middleware/core";
const paramsHandlerInstance = paramsHandler({
route: "/user/:name",
});
// Cloudflare Workers have no internal way of representing a middleware
// Instead, we use the universal `pipe` operator
const wrapped = pipe(
contextMiddleware("World!!!"),
headersMiddleware(),
(request, ctx, runtime) => {
const url = new URL(request.url);
if (url.pathname.startsWith("/user/")) {
return paramsHandlerInstance(request, ctx, runtime);
}
},
handler(),
);
export default createHandler(() => wrapped)();
ts
// functions/index.ts
import handler from "@universal-middleware-examples/tool/dummy-handler-cloudflare-pages";
export const onRequest = handler();
// functions/_middlewares.ts
// See https://developers.cloudflare.com/pages/functions/middleware/
import contextMiddleware from "@universal-middleware-examples/tool/middlewares/context-middleware-cloudflare-pages";
import headersMiddleware from "@universal-middleware-examples/tool/middlewares/headers-middleware-cloudflare-pages";
export const onRequest = [contextMiddleware("World!!!"), headersMiddleware()];
ts
import handler from "@universal-middleware-examples/tool/dummy-handler-express";
import contextMiddleware from "@universal-middleware-examples/tool/middlewares/context-middleware-express";
import headersMiddleware from "@universal-middleware-examples/tool/middlewares/headers-middleware-express";
import paramsHandler from "@universal-middleware-examples/tool/params-handler-express";
import compress from "@universal-middleware/compress/express";
import express from "express";
import { args } from "./utils";
const app = express();
// Now the universal context contains `{ hello: "World!!!" }`.
// See /examples/context-middleware
app.use(contextMiddleware("World!!!"));
// After a Response has been returned by the handler below,
// the `{ "X-Universal-Hello": "World!!!" }` header is appended to it
app.use(headersMiddleware());
app.use(compress());
app.get("/user/:name", paramsHandler());
app.get("/", handler());
const port = args.port ? Number.parseInt(args.port) : 3000;
app.listen(port, "localhost", () => {
console.log(`Server listening on http://localhost:${port}`);
});
ts
import handler from "@universal-middleware-examples/tool/dummy-handler-fastify";
import contextMiddleware from "@universal-middleware-examples/tool/middlewares/context-middleware-fastify";
import headersMiddleware from "@universal-middleware-examples/tool/middlewares/headers-middleware-fastify";
import paramsHandler from "@universal-middleware-examples/tool/params-handler-fastify";
import compress from "@universal-middleware/compress/fastify";
import fastify from "fastify";
import rawBody from "fastify-raw-body";
import { args } from "./utils";
const app = fastify();
// /!\ Mandatory if you need to access the request body in any Universal Middleware or Handler
await app.register(rawBody);
// Now the universal context contains `{ hello: "World!!!" }`.
// See /examples/context-middleware
app.register(contextMiddleware("World!!!"));
// After a Response has been returned by the handler below,
// the `{ "X-Universal-Hello": "World!!!" }` header is appended to it
app.register(headersMiddleware());
app.register(compress());
app.get("/user/:name", paramsHandler());
app.get("/", handler());
const port = args.port ? Number.parseInt(args.port) : 3000;
app.listen(
{
port,
host: "localhost",
},
() => {
console.log(`Server listening on http://localhost:${port}`);
},
);
ts
import handler from "@universal-middleware-examples/tool/dummy-handler-elysia";
import contextMiddleware from "@universal-middleware-examples/tool/middlewares/context-middleware-elysia";
import headersMiddleware from "@universal-middleware-examples/tool/middlewares/headers-middleware-elysia";
import paramsHandler from "@universal-middleware-examples/tool/params-handler-elysia";
import compress from "@universal-middleware/compress/elysia";
import Elysia from "elysia";
import { args } from "./utils";
const port = args.port ? Number.parseInt(args.port) : 3000;
new Elysia()
.use(contextMiddleware("World!!!"))
.use(headersMiddleware())
.use(compress())
.get("/user/:name", paramsHandler())
.get("/", handler())
.listen(port, () => {
console.log(`Server listening on http://localhost:${port}`);
});