javascript - Express.js 中间件可以依赖链中先前的中间件吗?
问题描述
假设我POST /api/comments
在创建评论的 API 中有一个 POST 请求。评论以数组树结构接收(每个评论都有一个 children 属性,可以有子评论)。我在发送响应之前发生了多个“事件”。
我可以像这样将所有需要的代码放入一个中间件函数中。
function postComments(req, res, next) {
// handle general authentication
if (!isAuthenticated()) {
next("not authenticated ...");
}
// handle more specific authentication (ex. admin)
if (!isAdmin()) {
next("not admin ...")
}
// validate req.body.comments so that each comment has allowed form
if (!areCommentsValid()) {
next("not valid ...");
}
// modify comments for database insertion
const modifiedComments = modifyComments();
// database insertion
db.insert(modifiedComments)
res.sendStatus(201);
}
在上面的示例中,通用身份验证和管理员身份验证可用于多个路由,并且下一个中间件不依赖它们,代码仍在工作。所以对这两个进行编码是有道理的。
在这个例子中,我的中间件做了很多事情。
我认为我可以做的是将以下代码拆分为多个中间件。
function userAuth(req, res, next) {
// handle user authentication
}
function adminAuth(req, res, next) {
// handle admin auth
}
function validateComments(req, res, next) {
// handle req.body.comments validation
}
function modifyComments(req, res, next) {
// modify comments
// req.commentsForDb = modifiedComments;
}
function postComments(req, res, next) {
// insert req.commentsForDb into database
}
所以现在我将我的中间件分成 4 个不同的中间件,但问题是中间件相互依赖。
postComments
需要modifyComments
设置req.commentsForDb
,modifyComments
需要validateComments
等
哪个是首选方法?
解决方案
这是完全有效的,它实际上是中间件的使用方式。只要您在中间件出现问题时使用错误代码正确调用 next,您应该停止转发到下一个。
这里的附加价值是您可以在许多不同的路线中重用您的中间件。您可以做的另一件事是中间件闭包生成器,例如基于角色的身份验证中间件:
function auth(role) {
return function(req, res, next) {
// get my user
// ...
// check user role
if user.role != role {
return next(new Error("Auth failed"))
}
return next()
}
}
// this route is for admins
app.get(
"/foo",
auth("admin"),
foo
)
// this one for users
app.get(
"/bar",
auth("user"),
foo
)
推荐阅读
- python - 在 Tkinter 中循环并没有按我的预期工作
- r - R:使用 dcast 或 pivot_wider 进行整形的问题
- reactjs - Create React App 上的 Service Worker 不会在 safari 上加载视频
- javascript - 如何向节点/表达 mySQL 函数添加错误处理
- python - Numpy 替换值
- javascript - 禁用右键单击 html5 音频元素
- nativescript - Nativescript 选项卡:想要路由到不是选项卡的模板/组件
- sql - Django - 如果另一列不同,则求和
- amazon-web-services - 确定和更新 AWS Lambda 上的 openssl 版本
- c - 为什么要使用函数指针?