从头开始创建一个自动产生文档/类型安全的现代API(9) 建立校验规则/按id读取任务

下面我们给 API 参数添加校验功能。

在Schema中添加规则

修改 db/schema.ts:

1
2
3
4
5
6
7
8
9
10
11
12
...
export const insertTasksSchema = createInsertSchema(
tasks,
{
name: z.string().min(1).max(255),
done: z.boolean(),
},
).omit({
id: true,
createdAt: true,
updatedAt: true,
});

这里我添加了规则,name的长度只能在1到255之间,规避了0长度和过长的name。

访问 localhost:3000/reference, 可以看到API已更新:

添加根据 ID 读取任务

添加路径

添加路径,修改app/api/[[...route]]/routes/tasks/tasks.routes.ts:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
...
import { IdParamsSchema, notFoundSchema } from "@/utility/constants";
...
export const getById = createRoute({
tags: ["Tasks"],
path: "/tasks/{id}",
method: "get",
request: {
params: IdParamsSchema,
},
responses: {
[HttpStatusCodes.OK]: jsonContent(
selectTasksSchema,
"The requested task which matches the id",
),
[HttpStatusCodes.NOT_FOUND]: jsonContent(
notFoundSchema,
"The task was not found",
),
[HttpStatusCodes.UNPROCESSABLE_ENTITY]: jsonContent(
createErrorSchema(IdParamsSchema),
"Invalid id error",
),
},
});
...
export type GetByIdRoute = typeof getById;

同时添加类型,添加utility/constants.ts:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import * as HttpStatusPhrases from "stoker/http-status-phrases";
import { z } from "@hono/zod-openapi";
import { createMessageObjectSchema } from "stoker/openapi/schemas";

export const IdParamsSchema = z.object({
id: z.coerce.number().openapi({
param: {
name: "id",
in: "path",
required: true,
},
required: ["id"],
example: 12,
}),
});

export const notFoundSchema = createMessageObjectSchema(HttpStatusPhrases.NOT_FOUND);

添加实现

添加实现,修改 app/api/[[...route]]/routes/tasks/tasks.handlers.ts :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
export const getById: AppRouteHandler<GetByIdRoute> = async (c) => {
const { id } = c.req.valid("param");

const task = await db.query.tasks.findFirst({
where: (q, { eq }) => eq(q.id, id),
});

if ( !task ) {
return c.json({ message: HttpstatusPhase.NOT_FOUND }, HttpStatusCodes.NOT_FOUND);
};

return c.json(task, HttpStatusCodes.OK);
};
...

添加引用

添加引用,修改 `` :

1
2
3
4
5
6
...
const router = createRouter()
.openapi(routes.list, handlers.list)
.openapi(routes.create, handlers.create)
.openapi(routes.getById, handlers.getById);
...

测试

访问 localhost:3000/reference, 可以看到API已更新:

测试一下,用 1 去访问接口,可以正确的返回值:


作者:Bearalise
出处:从头开始创建一个自动产生文档/类型安全的现代API(9) 建立校验规则/按id读取任务
版权:本文版权归作者所有
转载:欢迎转载,但未经作者同意,必须保留此段声明,必须在文章中给出原文链接。

请我喝杯咖啡吧~

支付宝
微信