@api-ts/typed-express-router

中文文档
2.0.7发布于 2026/08/05Apache-2.0TypeScriptCommonJS构建来源已验证近 30 天下载 7.2万

Implement an HTTP specification with Express

原始使用文档
文档目录10 节
  1. Goals
  2. Non-Goals
  3. Usage
  4. Creating a router
  5. Adding routes
  6. Route aliases
  7. Hooks and error handlers
  8. Unchecked routes
  9. Router middleware
  10. Other usage

@api-ts/typed-express-router

A thin wrapper around Express's Router

Goals

  • Define Express routes that are associated with routes in an api-ts apiSpec
  • Augment the existing Express request with the decoded request object and api-ts route metadata
  • Augment the existing Express response with a type-checked encode function
  • Allow customization of what to do on decode/encode errors, per-route if desired
  • Allow action to be performed after an encoded response is sent, per-route if desired
  • Allow routes to define alias routes with path that is different than the one specified in the httpRoute
  • Follow the express router api as closely as possible otherwise

Non-Goals

  • Enforce that all routes listed in an apiSpec have an associated route handler
  • Layer anything on top of the express.RequestHandler[] chain beyond the additional properties described in Goals (projects and other libraries can do this)

Usage

Creating a router

Two very similar functions are provided by this library that respectively create or wrap an Express router:

import { createRouter, wrapRouter } from '@api-ts/typed-express-router';
import express from 'express';

import { MyApi } from 'my-api-package';

const app = express();

const typedRouter = createRouter(MyApi);
app.use(typedRouter);

Adding routes

Once you have the typedRouter, you can start adding routes by the api-ts api name:

typedRouter.get('hello.world', [HelloWorldHandler]);

Here, HelloWorldHandler is a almost like an Express request handler, but req and res have an extra property. req.decoded contains the validated and decoded request. On the response side, there is an extra res.sendEncoded(status, payload) function that will enforce types on the payload and encode types appropriately (e.g. BigIntFromString will be converted to a string). The exported TypedRequestHandler type may be used to infer the parameter types for these functions.

Route aliases

If more flexibility is needed in the route path, a routeAliases function may be provided to match multiple paths. These paths may use the full Express matching syntax, but take care to preserve any path parameters or else you will likely get decode errors.

typedRouter.get('hello.world', [HelloWorldHandler], {
  routeAliases: ['/oldDeprecatedHelloWorld'],
});

Hooks and error handlers

The createRouter, wrapRouter, and individual route methods all take an optional last parameter where a post-response and error handling function may be provided. Ones specified for a specific route take precedence over the top-level ones. These may be used to customize error responses and perform other actions like metrics collection or logging.

const typedRouter = createRouter(MyApi, {
  decodeErrorFormatter: (errs, req) => {
    // Format `errs` however you want
    return { message: 'Bad request' };
  },
  getDecodeErrorStatusCode: (errs, req) => {
    return 400;
  },
  encodeErrorFormatter: (err, req) => {
    return { message: 'Internal server error' };
  },
  getEncodeErrorStatusCode: (err, req) => {
    // Ideally won't happen unless type safety is violated, so it's a 500
    return 500;
  },
  afterEncodedResponseSent: (status, payload, req, res) => {
    // Perform side effects or other things, `res` should be ended by this point
    endRequestMetricsCollection(req);
  },
});

// Override the decode error handler on one route
typedRouter.get('hello.world', [HelloWorldHandler], {
  decodeErrorFormatter: customHelloDecodeErrorFormatter,
});

Unchecked routes

If you need custom behavior on decode errors that is more involved than just sending an error response, then the unchecked variant of the router functions can be used. They do not fail and send a http response using decodeErrorFormatter and getDecodeErrorStatusCode when a request is invalid. Instead, they will still populate req.decoded, except this time it'll contain the Either<Errors, DecodedRequest> type for route handlers to inspect.

// Just a normal express route
typedRouter.getUnchecked('hello.world', (req, res) => {
  if (E.isLeft(req.decoded)) {
    console.warn('Route failed to decode! Continuing anyway');
  })

  res.send(200).end();
});

Router middleware

Middleware added with typedRouter.use() is ran just after the request is decoded but before it is validated, even on checked routes. It'll have access to req.decoded in the same way that unchecked routes do.

Other usage

Other than what is documented above, a wrapped router should behave like a regular Express one, so things like typedRouter.use() should behave the same.

版本与发布记录

@api-ts/typed-express-router 共发布 46 个版本,首次发布于 2022/08/11;过去 12 个月发布了 7 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
2.0.7latest2026/08/053 个月前
2.0.62026/08/013 个月前
2.0.52026/08/013 个月前
2.0.42026/07/283 个月前
2.0.32026/07/273 个月前
2.0.22026/07/253 个月前

其他发布通道:beta → 2.0.0-beta.1。

关于 @api-ts/typed-express-router 的常见问题

@api-ts/typed-express-router 是什么?

Implement an HTTP specification with Express

如何安装 @api-ts/typed-express-router?

在项目目录运行 npm install @api-ts/typed-express-router,或使用 pnpm add / yarn add / bun add。

@api-ts/typed-express-router 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@api-ts/typed-express-router 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@api-ts/typed-express-router 可以商用吗?

@api-ts/typed-express-router 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@api-ts/typed-express-router 的下载量有多少?

根据 npm 官方下载统计,@api-ts/typed-express-router 在 2026/10/06 – 2026/11/04 这 30 天内被下载 72,424 次,日均约 2,414 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@api-ts/typed-express-router 还在维护吗?

最新版本 2.0.7 发布于 2026/08/05(3 个月前);至今共发布 46 个版本,其中过去 12 个月发布了 7 个;首次发布于 2022/08/11。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。