三个有用的 Express 中间件
当我使用 Express 和 Node 创建应用程序时,我了解了三个有用的中间件:
- 摩根
- 驼峰式
- 删除空属性
这三个中间件中,Morgan 是一个真正的中间件。你可以直接从 npm 下载Morgan。另外两个中间件是我分别用camelcase-keys和omit-empty创建的。
我想分享这三个中间件的功能,以及它们如何在我创建应用程序时让我的工作变得更轻松。
摩根4
Morgan 是一个请求记录器。当你的服务器收到请求时,它会告诉你一些信息。它可以记录以下内容:
- 日期
- HTTP 版本
- 方法
- 推荐人
- 远程地址
- 远程用户
- 请求头
- 响应标头
- 响应时间
- 状态码
- 请求的 URL
- 用户代理
Morgan 提供五种预定义格式供您选择:
- 合并
- 常见的
- 短的
- 开发
- 微小的
我只使用这个dev
格式。Morgandev
的日志如下:
我使用 Morgan 检查两件事:
- 方法和终点
- 状态代码
检查方法和端点
编写后端代码时,需要确保使用正确的方法和端点发送请求。如果方法或端点错误,您将无法触发预期的请求处理程序。
例如,如果您想requestHandler
在下面的代码中触发,您需要GET
向/testing
端点发送请求。
app.get("/testing", requestHandler);
如果我在编写后端应用程序时出现问题,我首先会检查是否发送了正确的方法和端点。首先检查这一点可以帮助我节省大量时间,避免出现拼写错误。
当我向服务器发送请求时,我会收到来自 Morgan 的日志。该日志会显示方法和端点。第一个值是方法,第二个值是端点。
检查状态代码
由于后端与通信有关,因此我希望确保将正确的状态代码发送回前端。如果用户尝试使用错误的用户名或密码登录,我希望发送 401 未授权错误,而不是 500 内部服务器错误。
这种格式最棒的地方dev
在于它用不同的颜色显示状态代码,这使得状态代码更容易被识别。
200+ 状态代码为绿色:
300+ 状态代码为青色:
400+ 状态代码为黄色:
500+ 状态代码为红色:
驼峰式命名法
假设您想从表单中获取用户的名字。为此,您需要<form>
在 HTML 中添加一个 。<form>
应该包含一个<input>
带有name
的first-name
。
<form>
<input name="first-name" />
</form>
first-name
要在后端接收,您需要使用括号表示法。这是因为-
JavaScript 中 is 是一个运算符,它不会被识别为连字符。
app.get("/endpoint", (req, res) => {
// Bracket notation to get the value of a property
const firstName = req.body["first-name"];
});
我不喜欢使用括号表示法。我更喜欢尽可能使用点表示法。
app.get("/endpoint", (req, res) => {
// Dot notation
const firstName = req.body.firstName;
});
我更喜欢点符号,因为我到处都用它。我习惯在 JavaScript 中用驼峰命名法。如果不用点符号,感觉会很奇怪。另外,如果能用点符号,我就能解构属性。
app.get("/endpoint", (req, res) => {
const { firstName } = req.body;
});
要使用点符号,我需要确保元素name
中的属性<input>
采用驼峰式命名法。
<input name="firstName">
但这感觉很奇怪,因为我们通常不在 HTML 中使用驼峰式命名!我们用连字符分隔单词!
<!-- This feels weird -->
<input name="firstName" />
<!-- This feels normal -->
<input name="first-name" />
我的解决方案是在到达请求处理程序之前将所有属性转换为驼峰式命名。我使用Sindre Sorhus 的 camelcase-keys包制作了一个中间件来实现这一点。
const camelcaseKeys = require("camelcase-keys");
const camelcase = () => {
return function(req, res, next) {
req.body = camelcaseKeys(req.body, { deep: true });
req.params = camelcaseKeys(req.params);
req.query = camelcaseKeys(req.query);
next();
};
};
您可以像这样使用中间件:
app.use(camelcase());
有了camelcase
,您不必担心first name
、first_name
、first-name
或FirstName
。它将始终为firstName
。
无论你从还是从 中获取req.body
,都无所谓。所有属性都将采用驼峰式命名法。req.params
req.query
删除空属性
让我们想象一下您期望拥有一系列技能的情况。
fetch('/endpoint', {
method: 'post',
headers: { 'Content-Type': 'application/json' }
body: JSON.stringify({
name: 'Zell',
skills: ['coding', 'designing', 'writing']
})
}
如果有一项或多项技能,您想将这些技能添加到数据库。
app.post("/endpoint", (req, res) => {
const { skills } = req.body;
if (skills.length !== 0) {
// Add skills to database
}
});
但我们有一个问题。用户可以向您发送以下请求的变体:
- 不包含任何
skills
属性 - 包含一个空
skills
属性 - 包含
skills
至少一项技能的属性
如果用户没有向您发送skills
属性,您就无法写入skills.length
。您将收到一条错误消息Cannot read property 'length' of undefined
。
要正确检查一项或多项技能,您需要两个条件:
- 检查是否有技能数组
- 检查数组中是否至少有一个项目
app.post("/endpoint", (req, res) => {
const { skills } = req.body;
if (skills && skills.length !== 0) {
// Add skills to database
}
});
有一种方法可以简化这些检查。我的解决方案是使用Jon Schlinkert 的 omit-empty包创建一个中间件。
omitEmpty
从对象中删除空属性。
const object = {
null: null,
undefined: undefined,
emptyString: "",
emptyArray: [],
emptyObject: {},
filled: "yay"
};
console.log(omitEmpty(object));
// {
// filled: 'yay'
// }
这是我制作的中间件:
const omitEmpty = require("omitEmpty");
const removeEmptyProperties = () => {
return function(req, res, next) {
req.body = omitEmpty(req.body);
req.params = omitEmpty(req.params);
req.query = omitEmpty(req.query);
next();
};
};
您可以使用removeEmptyProperties
这种方式:
app.use(removeEmptyProperties());
一旦使用removeEmptyProperties
中间件,就无需检查的长度。如果存在,skills
您可以确定它包含一个或多个项目。skills
所以代码变成:
app.post("/endpoint", (req, res) => {
const { skills } = req.body;
if (skills) {
// Add skills to database
}
});
简单多了!
感谢阅读。本文最初发布在我的博客上。如果您想阅读更多文章来帮助您成为更优秀的前端开发人员,请订阅我的新闻通讯。
文章来源:https://dev.to/zellwk/ Three-useful-express-middleware-1di