Middleware

Used to extend the built-in Web Server of Modern.js, unlike Hook, Middleware can directly operate Node's origin request and response, and can be extended using the framework plugin.

WARNING

Middleware will be removed in the next major version.

It is recommended to use UnstableMiddleware to handle page requests.

NOTE

For more detail, see Extend Web Server.

Usage

import { Middleware } from '@modern-js/runtime/server';

export const middleware: Middleware = async (context, next) => {};
export const middleware: Middleware[] = [
  async (context, next) => {},
  async (context, next) => {},
];
INFO

Before using this API, please execute pnpm run new to create a new "Custom Web Server" source code directory.

pnpm run new
? Please select the operation you want: Create Element
? Please select the type of element to create: New "Custom Web Server" source code directory

Function Signature

type Middleware = (
  context: MiddlewareContext,
  next: NextFunction,
) => Promise<void> | void;

type MiddlewareContext = {
  response: {
    set: (key: string, value: string) => void;
    status: (code: number) => void;
    getStatus: () => number;
    cookies: {
      set: (key: string, value: string, options?: any) => void;
      clear: () => void;
    };
    raw: (
      body: string,
      { status, headers }: { status: number; headers: Record<string, any> },
    ) => void;
    locals: Record<string, any>;
  };
  request: {
    host: string;
    pathname: string;
    query: Record<string, any>;
    cookie: string;
    cookies: {
      get: (key: string) => string;
    };
    headers: IncomingHttpHeaders;
  };
  source: {
    req: IncomingMessage;
    res: ServerResponse;
  };
};

Input

  • context: Middleware context.
    • response: provides a series of methods to process the response.
    • request: provides a series of methods to get request info.
    • source: provides Node.js native req and res object.
  • next: call next listener (not affect the server process, only current hook).
WARNING

The execution of the next function does not affect built-in processes, only controls whether the next middleware executes. Rendering processes are interrupted only when the response is written.

Example

Tracking

export const Middleware = () => async (ctx, next) => {
  const start = Date.now();
  ctx.source.res.once('finish', () => {
    console.log(Date.now() - start);
  });
};

Inject Tools & Data

Modern.js provides res.locals to store local variables for the current request.

export const Middleware = () => async (ctx, next) => {
  ctx.response.locals.id = 'Modern.js';
  ctx.response.locals.rpc = createRpcInstance();
};