nestjs之适配器模式的应用

NestJS 是一个用于构建高效、可靠和可扩展的服务器端应用程序的框架。在 NestJS 中,适配器模式(Adapter Pattern)主要体现在其对不同类型的 HTTP 服务端框架的适配上。NestJS 本身是建立在 Express 或者 Fastify 这样的底层 HTTP 框架之上的,但它提供了一个抽象层,使得开发者可以不必关心底层框架的具体实现。

适配器模式是一种结构型设计模式,它允许对象以兼容的方式协同工作,即便它们的接口不兼容。在 NestJS 中,这意味着你可以在不改变应用程序核心逻辑的情况下,切换不同的 HTTP 框架。

如何工作的?

  1. 抽象层:NestJS 定义了一组抽象的 HTTP 接口,这些接口描述了处理 HTTP 请求所需的基本操作,如处理请求、响应等。
// @nestjs\core\adapters\http-adapter.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AbstractHttpAdapter = void 0;
/**
 * @publicApi
 */
class AbstractHttpAdapter {
    constructor(instance) {
        this.instance = instance;
    }
    // eslint-disable-next-line @typescript-eslint/no-empty-function
    async init() { }
    use(...args) {
        return this.instance.use(...args);
    }
    get(...args) {
        return this.instance.get(...args);
    }
    post(...args) {
        return this.instance.post(...args);
    }
    head(...args) {
        return this.instance.head(...args);
    }
    delete(...args) {
        return this.instance.delete(...args);
    }
    put(...args) {
        return this.instance.put(...args);
    }
    patch(...args) {
        return this.instance.patch(...args);
    }
    all(...args) {
        return this.instance.all(...args);
    }
    search(port, hostname, callback) {
        return this.instance.search(port, hostname, callback);
    }
    options(...args) {
        return this.instance.options(...args);
    }
    listen(port, hostname, callback) {
        return this.instance.listen(port, hostname, callback);
    }
    getHttpServer() {
        return this.httpServer;
    }
    setHttpServer(httpServer) {
        this.httpServer = httpServer;
    }
    setInstance(instance) {
        this.instance = instance;
    }
    getInstance() {
        return this.instance;
    }
}
exports.AbstractHttpAdapter = AbstractHttpAdapter;

  1. 适配器:对于每种支持的底层 HTTP 框架(如 Express 或 Fastify),NestJS 提供了一个适配器。这个适配器实现了 NestJS 定义的 HTTP 抽象接口,但在内部使用特定框架的方法。
// @nestjs\platform-express\adapters\express-adapter.js
const http_adapter_1 = require("@nestjs/core/adapters/http-adapter");
class ExpressAdapter extends http_adapter_1.AbstractHttpAdapter {
    ...
}
exports.ExpressAdapter = ExpressAdapter;

FastifyAdapter 的实现。

// @nestjs\platform-fastify\adapters\fastify-adapter.js
const http_adapter_1 = require("@nestjs/core/adapters/http-adapter");
class FastifyAdapter extends http_adapter_1.AbstractHttpAdapter {
    ...
}
exports.FastifyAdapter = FastifyAdapter;

  1. 灵活切换:因为 NestJS 应用程序是针对这些抽象接口编写的,所以可以通过简单地更换适配器来切换底层的 HTTP 框架,而不需要重写应用逻辑。
    执行await NestFactory.create(AppModule)的时候,会判断serverOrOptions传进去是不是一个Adapter
class NestFactoryStatic {
    constructor() {
        this.logger = new logger_service_1.Logger('NestFactory', {
            timestamp: true,
        });
        this.abortOnError = true;
        this.autoFlushLogs = false;
    }
    async create(moduleCls, serverOrOptions, options) {
        const [httpServer, appOptions] = this.isHttpServer(serverOrOptions)
            ? [serverOrOptions, options]
            : [this.createHttpAdapter(), serverOrOptions];
        ...
    }
  }

示例

例如,如果你想将你的 NestJS 应用从 Express 切换到 Fastify,你只需要更换相应的适配器。在 NestJS 中,这通常通过更改 main.ts 文件中的一行代码来完成:

const app = await NestFactory.create(AppModule, new FastifyAdapter());

相比之下,如果使用 Express 适配器,代码将会是:

const app = await NestFactory.create(AppModule); // 默认是 ExpressAdapter

expressFastify都实现了AbstractHttpAdapter方法,于是无论用户传入哪一种都可以实现http模块的解耦。

优势

  • 灵活性:允许开发者根据项目需求或个人偏好选择合适的 HTTP 框架。
  • 解耦:应用核心逻辑与底层 HTTP 框架解耦,提高了代码的可维护性。
  • 易于测试:由于底层框架被抽象化,使得对应用逻辑的单元测试更加容易。

总之,适配器模式在 NestJS 中的应用提供了一种优雅的方式来支持不同的 HTTP 框架,同时保持应用核心逻辑的一致性和可维护性。

你可能感兴趣的:(nestjs原理,适配器模式)