简体   繁体   English

验证响应是 express 还是 fastify

[英]Verify if response is express or fastify

In NodeJS, using Javascript I have a "res" object that can be either an Express or Fastify response, is there any way to check which of the two is this response?在 NodeJS 中,使用 Javascript 我有一个“res” object 可以是 Express 或 Fastify 响应,有没有办法检查这两个响应中的哪一个?

There are 3 ways to solve this problem: the bad way, the less-awful way, and the way that results in actual clean code.有 3 种方法可以解决这个问题:不好的方法,不太糟糕的方法,以及产生实际干净代码的方法。

1. The bad way: duck typing 1. 坏方法:鸭式打字

The most intiutive way is using a technique called "duck typing" to tell what kind of object you're dealing with.最直观的方法是使用一种称为“鸭子打字”的技术来判断您正在处理的是哪种 object。 Look at res , check what properties it has, and infer the type based on that.查看res ,检查它具有哪些属性,并据此推断类型。 In particular, you'll be interested in the differences between the objects to be able to tell them apart, so search for special features that the other framework doesn't have.特别是,您将对对象之间的差异感兴趣以便能够将它们区分开来,因此请搜索其他框架没有的特殊功能。

Example checks:示例检查:

function isExpress(res) {
  return (typeof res === 'object' && typeof res.sendFile === 'function');
}
function isFastify(res) {
  return (typeof res === 'object' && typeof res.hasHeader === 'function');
}

However, there's a problem: what if you get a res that is extended by a middleware for express.js or for fastify, which adds the property?但是,有一个问题:如果你得到一个由 express.js 或 fastify 的中间件扩展的res ,它添加了属性怎么办? Then, depending on the ordering of your if-elses, you may confuse one for the other.然后,根据您的 if-else 的顺序,您可能会混淆另一个。

2. The less-awful way: decorating the object yourself 2. 不那么糟糕的方法:自己装饰 object

It would be better if we could tell the objects apart regardless of what middlewares are applied - so that a feature being added doesn't break our type recognition logic.如果无论应用什么中间件,我们都能区分对象会更好——这样添加的特性就不会破坏我们的类型识别逻辑。

Instead, we can purposefully extend the res object using a special, additional property, so that it's obvious from looking at that property whether we're dealing with express or fastify.相反,我们可以有目的地使用特殊的附加属性扩展res object,这样无论我们是在处理 express 还是 fastify,通过查看该属性就很明显了。 To do this, we need to make sure that:为此,我们需要确保:

  • express will decorate res with a property that says "I'm express" express 将用“I'm express”的属性装饰res
  • fastify will decorate res with a property that says "I'm fastify" fastify 会用一个“我是 fastify”的属性来装饰res

Quite literally:毫不夸张的说:

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');

Then, you can refer to res[FRAMEWORK_TYPE] and check the hint that you've left for yourself directly.然后,您可以参考res[FRAMEWORK_TYPE]并直接检查您为自己留下的提示。

3. The clean way: design patterns 3. 干净的方式:设计模式

The way you've formulated the original problem is: how to check what type of instance we're dealing with.您制定原始问题的方式是:如何检查我们正在处理的实例类型。 However, the purpose of this check is most likely to be able to integrate different frameworks (express and fastify) with a single piece of code that does something else (a handler).但是,此检查的目的很可能是能够将不同的框架(express 和 fastify)与执行其他操作的单个代码(处理程序)集成。

This problem is usually solved with the Adapter design pattern - have a layer that speaks a common API and hides the complexity of having different possible implementations.这个问题通常通过适配器设计模式来解决 - 有一个层使用常见的 API 并隐藏具有不同可能实现的复杂性。 For instance, say your handler needs the request body and headers, and you need to be able to respond via JSON regardless of framework.例如,假设您的处理程序需要请求正文和标头,并且无论框架如何,您都需要能够通过 JSON 进行响应。 Then, you could define the handler signature to be:然后,您可以将处理程序签名定义为:

({ body, headers }) => responseObject

Next, call that handler from both frameworks.接下来,从两个框架中调用该处理程序。 You'll notice that you need to refer to different parts of req and res in case of express and fastify in order to call the handler properly.您会注意到,在 express 和 fastify 的情况下,您需要引用reqres的不同部分才能正确调用处理程序。 Also, in case of fastify, you'll be able to just Promise.resolve(responseObject) , but for express, you may need to do res.json(responseObject) instead.此外,在 fastify 的情况下,您可以只Promise.resolve(responseObject) ,但对于 express,您可能需要改为res.json(responseObject)

This way, you decouple your business logic (handler) from the infrastructure layer (web server).这样,您就可以将业务逻辑(处理程序)与基础设施层(Web 服务器)分离。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM