使用 Yup 和 Express.js 进行模式验证
让我们开始编程吧
你呢?
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
我很幸运生活在这样一个时代,我们有这么多方法可以完成同一件事。很多人对此持批评态度,但我认为拥有能够以不同方式实现相同功能的库是一件非常棒的事情。我认为这有助于程序员根据自己的思路来开发项目。
但今天这篇文章的主题并非如此。今天我将教大家如何使用Yup和Express.js构建一个验证系统。
过去我曾写过一篇文章,介绍如何做我们今天要做的事情,只不过是用Joi来实现。如果您想阅读这篇文章,请点击这里。
如果你以前用过 Joi,那么使用 Yup 也会感觉很顺手,这两个库非常相似。
但我发现 Yup 更直观,API 更简洁,同时还能提供很棒的开发体验。
如果你非常在意项目包的大小,那么让我告诉你,Yup 比 Joi 轻得多。
希望我已经引起了您的注意,那么现在让我们继续看代码。
让我们开始编程吧
和往常一样,我们先来安装必要的依赖项。
npm i express yup --save
现在我们需要用 Express 创建一个简单的 API,类似于这样:
const express = require("express");
const app = express();
app.use(express.json());
app.get("/", (req, res) => {
return res.json({ message: "Validation with Yup 👊" });
});
const start = (port) => {
try {
app.listen(port, () => {
console.log(`Api running at: http://localhost:${port}`);
});
} catch (err) {
console.error(err);
process.exit();
}
};
start(3333);
现在我们已经有了项目的基础架构,可以开始使用 Yup 了。首先,我们将基于以下 JSON 创建一个模式(这将是我们 HTTP 请求的主体):
{
"title": "This is the title",
"content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
"contact": "author@outlook.com",
"url": "https://safe-link.me"
}
现在让我们在 API 中创建一个新路由,我们将从 HTTP 请求正文返回对象数据,并且我们仍然会从参数中返回 id。
app.post("/create/:id", (req, res) => {
return res.json({ body: req.body, id: req.params.id });
});
现在路由已经创建好了,我们只需要两样东西:一个用于验证模式的中间件和模式本身。所以首先我们要创建模式,别忘了将 Yup 导入到我们的项目中。
const yup = require("yup");
// Hidden for simplicity
const linkSchema = yup.object({
body: yup.object({
url: yup.string().url().required(),
title: yup.string().min(8).max(32).required(),
content: yup.string().min(8).max(255).required(),
contact: yup.string().email().required(),
}),
params: yup.object({
id: yup.number().required(),
}),
});
如我们所见,我们将验证 HTTP 请求的主体及其参数。但是,如果您的项目中也需要使用查询字符串,您也可以对其进行验证。
这次我打算换个方法,因为 Yup 允许我这么做。这是因为我需要多次复用中间件,而我只想让它验证我传入参数的模式。
这样一来,我们只需要编写一次中间件,并且只需要创建几个单独的模式(就像我们使用linkSchema一样)。
现在开始创建中间件,这样我之前说的所有内容才能变得有意义。我们将这个中间件命名为validate。
const validate = (schema) => async (req, res, next) => {
// logic goes here
};
如您所见,在中间件中,我们将接收模式作为函数参数,之后我们将对其进行验证,如果一切正确,我们将可以访问控制器。
const validate = (schema) => async (req, res, next) => {
try {
await schema.validate({
body: req.body,
query: req.query,
params: req.params,
});
return next();
} catch (err) {
// More logic goes here
}
};
正如你在代码中看到的,中间件将准备好验证请求体、参数和查询字符串,这使得它在这方面非常灵活。
现在,为了完成中间件,只需返回模式验证期间发生的相应错误,如下所示:
const validate = (schema) => async (req, res, next) => {
try {
await schema.validate({
body: req.body,
query: req.query,
params: req.params,
});
return next();
} catch (err) {
return res.status(500).json({ type: err.name, message: err.message });
}
};
现在模式和中间件都已创建完成,只需将其添加到路由中,如下所示:
app.post("/create/:id", validate(linkSchema), (req, res) => {
return res.json({ body: req.body, id: req.params.id });
});
现在,如果您要向端点发送 HTTP 请求,您可以看到 Yup 已经根据我们在模式中规定的规则对每个字段进行相应的验证。
如果一切正常,我们将在端点的响应中看到通过 HTTP 请求发送的数据。但是,如果某个字段填写错误,我们将只看到发生的错误信息。
最终代码如下:
const express = require("express");
const yup = require("yup");
const app = express();
app.use(express.json());
const linkSchema = yup.object({
body: yup.object({
url: yup.string().url().required(),
title: yup.string().min(8).max(32).required(),
content: yup.string().min(8).max(255).required(),
contact: yup.string().email().required(),
}),
params: yup.object({
id: yup.number().required(),
}),
});
const validate = (schema) => async (req, res, next) => {
try {
await schema.validate({
body: req.body,
query: req.query,
params: req.params,
});
return next();
} catch (err) {
return res.status(500).json({ type: err.name, message: err.message });
}
};
app.get("/", (req, res) => {
return res.json({ message: "Validation with Yup 👊" });
});
app.post("/create/:id", validate(linkSchema), (req, res) => {
return res.json({ body: req.body, id: req.params.id });
});
const start = (port) => {
try {
app.listen(port, () => {
console.log(`Api running at: http://localhost:${port}`);
});
} catch (err) {
console.error(err);
process.exit();
}
};
start(3333);
我希望我的解释简单易懂,并且对你的项目有所帮助。
你呢?
你们在项目中使用哪种模式验证方法?
文章来源:https://dev.to/franciscomendes10866/schema-validation-with-yup-and-express-js-3l19