Skip to main content
Version: 4.0.0

参数校验

这一节说明 Functional API 里的参数校验方式,以及它和 class + decorator + pipeline 的关系。

结论先说

  • Class 写法通常用参数装饰器 + pipe 机制做校验。
  • Functional 写法用 input(...) / output(...) 做校验。
  • 两者都能保证运行时安全,只是声明方式不同。

Functional 的校验入口

defineApi 里:

  • input(...):校验请求输入(params/query/body/headers
  • output(...):校验响应输出

示例:

import { defineApi } from '@midwayjs/core/functional';
import { z } from 'zod';

export const userApi = defineApi('/users', api => ({
getUser: api
.get('/:id')
.input({
params: z.object({
id: z.string().min(1),
}),
query: z.object({
verbose: z.string().optional(),
}),
})
.output(
z.object({
id: z.string(),
name: z.string(),
})
)
.handle(async ({ input }) => {
return {
id: input.params?.id ?? '',
name: 'harry',
};
}),
}));

失败时会发生什么

  • input(...) 校验失败:请求会在进入业务逻辑前失败。
  • output(...) 校验失败:handler 返回后、响应前失败。

这样可以避免不合法数据进入服务层,也能避免错误响应结构流出。

支持什么 schema

Functional 内部会调用 schema 的解析接口(如 safeParse/safeParseAsync/parse/parseAsync),因此像 zod 这类 schema 库可以直接使用。

常见实践建议

  1. 先给核心接口加 input(...),特别是写操作接口。
  2. 再补 output(...),保证前后端返回结构稳定。
  3. 把业务校验(如权限、业务规则)留在 service 层,不要全堆在 schema。