Fastify JSON Schema 验证路由
Author:zhoulujun Date:
JSON Schema 在 Fastify 中与路由结合使用,主要是用于验证客户端请求的数据和格式化响应数据。通过定义 JSON Schema,可以确保传入的请求数据满足特定格式和类型要求,同时还可以控制响应数据的结构。这样做有助于提高 API 的健壮性和安全性。
以下是一个如何在 Fastify 路由中使用 JSON Schema 来验证请求和响应的示例:
const fastify = require("fastify")(); // 定义 JSON Schema const userSchema = { type: "object", required: ["username", "email", "age"], properties: { username: { type: "string" }, email: { type: "string", format: "email" }, age: { type: "number", minimum: 1 }, }, }; fastify.route({ method: "POST", url: "/create-user", schema: { body: userSchema, // 使用 JSON Schema 验证请求体 response: { 200: { type: "object", properties: { success: { type: "boolean" }, id: { type: "string" }, }, }, }, }, handler: (request, reply) => { // 处理请求逻辑 // 假设创建用户成功,返回用户 ID reply.send({ success: true, id: "12345" }); }, }); fastify.listen(3000, (err) => { if (err) throw err; console.log("Server is running on http://localhost:3000"); });
定义了一个
userSchema
,描述了预期的请求体格式,包括必需字段和各字段的类型。在路由配置中,通过
schema
属性将userSchema
应用于请求体(body
),这样 Fastify 会自动验证传入的请求数据是否符合定义的 schema。同样,也定义了响应的 schema,确保响应数据结构符合预期。
通过这种方式,可以确保所有进入的请求都经过严格的验证,并且所有的响应都符合预定的格式,从而增强了 API 的健壮性和用户的可预测性。
Hooks 处理登录态问题
const fastify = require("fastify")({ logger: true }); const secureSession = require("fastify-secure-session"); // 注册 session 插件 fastify.register(secureSession, { secret: "averylognsecretkey", // 应使用一个长而复杂的密钥 cookie: { path: "/", // 配置其他 cookie 选项根据需要 }, }); // 仅对/api/a 和/api/c 应用 preHandler 钩子 fastify.addHook("preHandler", (request, reply, done) => { if ( (request.routerPath === "/api/a" || request.routerPath === "/api/c") && !request.session.user ) { request.session.redirectTo = request.raw.url; reply.redirect(302, "/login"); done(); } else { done(); } }); // 不需要 session 验证的路由 fastify.get("/api/b", (req, reply) => { reply.send({ message: "Access granted for /api/b" }); }); // 需要 session 验证的路由 fastify.get("/api/a", (req, reply) => { reply.send({ message: "Access granted for /api/a" }); }); fastify.get("/api/c", (req, reply) => { reply.send({ message: "Access granted for /api/c" }); }); // 登录页面的路由 fastify.get("/login", (req, reply) => { reply.send(`Login form goes here. POST to /login to authenticate.`); }); // 登录逻辑 fastify.post("/login", (req, reply) => { const { username, password } = req.body; if (username === "user" && password === "password") { req.session.user = username; const redirectTo = req.session.redirectTo || "/"; delete req.session.redirectTo; reply.redirect(302, redirectTo); } else { reply.code(401).send({ error: "Unauthorized" }); } }); // 启动服务器 fastify.listen(3000, (err) => { if (err) { fastify.log.error(err); process.exit(1); } console.log(`Server listening on http://localhost:3000`); });
限定参数
下面是 post 必须传 a 和 b 参数:
const fastify = require("fastify")(); const postSchema = { schema: { body: { type: "object", required: ["a", "b"], properties: { a: { type: "string" }, b: { type: "string" }, }, }, response: { // 如果缺失,默认返回 400 错误,可在此处修改 400 的返回类型 400: { type: "object", properties: { statusCode: { type: "number" }, error: { type: "string" }, message: { type: "string" }, }, }, }, }, // 此处可以拦截上面的默认拦截策略 preValidation: (request, reply, done) => { if (!request.body || !request.body.a || !request.body.b) { reply .code(400) .send({ error: "Bad Request", message: "Missing required parameters" }); return; } done(); }, }; fastify.post("/api/data", postSchema, (request, reply) => { // 如果到这里,说明 a 和 b 参数都已经通过验证 reply.send({ message: "Success" }); }); fastify.listen(3000, (err) => { if (err) { console.error(err); process.exit(1); } console.log("Server listening on port 3000"); });
如果不在路由中定义 preValidation 钩子和自定义的 response schema,当 POST 请求的 body 不符合定义的 JSON Schema 时,Fastify 默认会返回一个 400 错误(Bad Request)。这个错误的响应体会包含关于哪些字段不符合要求的信息,但这个信息是由 Fastify 自动生成的,可能不会像自定义错误消息那样具体或清晰。
转载本站文章《Fastify JSON Schema 验证路由》,
请注明出处:https://www.zhoulujun.cn/html/webfront/server/Fastify/9303.html