验证响应是 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 的情况下,您需要引用 reqres 的不同部分才能正确调用处理程序。此外,在 fastify 的情况下,您可以 Promise.resolve(responseObject),但对于 express,您可能需要 res.json(responseObject)

这样,您就可以将业务逻辑(处理程序)与基础架构层(Web 服务器)分离。