验证响应是 express 还是 fastify
Verify if response is express or fastify
在 NodeJS 中,使用 Javascript 我有一个“res”对象,它可以是 Express 或 Fastify 响应,有什么方法可以检查这两个响应中的哪一个?
有 3 种方法可以解决此问题:糟糕的方法、less-awful 方法以及产生实际干净代码的方法。
1.坏方法:鸭子打字
最直观的方法是使用一种称为“鸭子打字”的技术来判断您正在处理的是哪种 object。查看 res
,检查它具有哪些属性,并据此推断类型。特别是,您会对 object 之间的 差异 感兴趣,以便能够区分它们,因此搜索其他框架没有的特殊功能.
示例检查:
function isExpress(res) {
return (typeof res === 'object' && typeof res.sendFile === 'function');
}
function isFastify(res) {
return (typeof res === 'object' && typeof res.hasHeader === 'function');
}
但是,有一个问题:如果你得到一个 res
由中间件扩展 express.js 或 fastify,它添加了 属性 怎么办?然后,根据您 if-elses 的顺序,您可能会混淆其中一个。
2。 less-awful方式:自己装饰object
如果我们能够区分 object,而不管应用什么中间件,那就更好了——这样添加的功能就不会破坏我们的类型识别逻辑。
相反,我们可以使用特殊的附加 属性 有目的地扩展 res
object,这样一来 属性 就很明显我们是否处理 express 或 fastify。为此,我们需要确保:
- express 将用 属性 装饰
res
,上面写着“I'm express”
- fastify 将用 属性 装饰
res
,上面写着“我正在 fastify”
字面意思:
const FRAMEWORK_TYPE = Symbol('type of framework that res comes from');
expressApp.use(function(req, res, next) {
res[FRAMEWORK_TYPE] = 'express';
next();
});
fastifyApp.decorateReply(FRAMEWORK_TYPE, 'fastify');
然后,您可以参考res[FRAMEWORK_TYPE]
,直接查看您给自己留下的提示。
3。干净的方式:设计模式
您表述原始问题的方式是:如何检查我们正在处理的实例类型。但是,此检查的目的很可能是能够将不同的框架(express 和 fastify)与执行其他操作(处理程序)的单段代码集成。
这个问题通常用 Adapter design pattern 来解决 - 有一个层说一个共同的 API 并隐藏具有不同可能实现的复杂性。例如,假设您的处理程序需要请求 body 和 headers,并且无论框架如何,您都需要能够通过 JSON 进行响应。然后,您可以将处理程序签名定义为:
({ body, headers }) => responseObject
接下来,从两个框架调用该处理程序。您会注意到,在 express 和 fastify 的情况下,您需要引用 req
和 res
的不同部分才能正确调用处理程序。此外,在 fastify 的情况下,您可以 Promise.resolve(responseObject)
,但对于 express,您可能需要 res.json(responseObject)
。
这样,您就可以将业务逻辑(处理程序)与基础架构层(Web 服务器)分离。
在 NodeJS 中,使用 Javascript 我有一个“res”对象,它可以是 Express 或 Fastify 响应,有什么方法可以检查这两个响应中的哪一个?
有 3 种方法可以解决此问题:糟糕的方法、less-awful 方法以及产生实际干净代码的方法。
1.坏方法:鸭子打字
最直观的方法是使用一种称为“鸭子打字”的技术来判断您正在处理的是哪种 object。查看 res
,检查它具有哪些属性,并据此推断类型。特别是,您会对 object 之间的 差异 感兴趣,以便能够区分它们,因此搜索其他框架没有的特殊功能.
示例检查:
function isExpress(res) {
return (typeof res === 'object' && typeof res.sendFile === 'function');
}
function isFastify(res) {
return (typeof res === 'object' && typeof res.hasHeader === 'function');
}
但是,有一个问题:如果你得到一个 res
由中间件扩展 express.js 或 fastify,它添加了 属性 怎么办?然后,根据您 if-elses 的顺序,您可能会混淆其中一个。
2。 less-awful方式:自己装饰object
如果我们能够区分 object,而不管应用什么中间件,那就更好了——这样添加的功能就不会破坏我们的类型识别逻辑。
相反,我们可以使用特殊的附加 属性 有目的地扩展 res
object,这样一来 属性 就很明显我们是否处理 express 或 fastify。为此,我们需要确保:
- express 将用 属性 装饰
res
,上面写着“I'm express” - fastify 将用 属性 装饰
res
,上面写着“我正在 fastify”
字面意思:
const FRAMEWORK_TYPE = Symbol('type of framework that res comes from');
expressApp.use(function(req, res, next) {
res[FRAMEWORK_TYPE] = 'express';
next();
});
fastifyApp.decorateReply(FRAMEWORK_TYPE, 'fastify');
然后,您可以参考res[FRAMEWORK_TYPE]
,直接查看您给自己留下的提示。
3。干净的方式:设计模式
您表述原始问题的方式是:如何检查我们正在处理的实例类型。但是,此检查的目的很可能是能够将不同的框架(express 和 fastify)与执行其他操作(处理程序)的单段代码集成。
这个问题通常用 Adapter design pattern 来解决 - 有一个层说一个共同的 API 并隐藏具有不同可能实现的复杂性。例如,假设您的处理程序需要请求 body 和 headers,并且无论框架如何,您都需要能够通过 JSON 进行响应。然后,您可以将处理程序签名定义为:
({ body, headers }) => responseObject
接下来,从两个框架调用该处理程序。您会注意到,在 express 和 fastify 的情况下,您需要引用 req
和 res
的不同部分才能正确调用处理程序。此外,在 fastify 的情况下,您可以 Promise.resolve(responseObject)
,但对于 express,您可能需要 res.json(responseObject)
。
这样,您就可以将业务逻辑(处理程序)与基础架构层(Web 服务器)分离。