将Nest.js应用程序作为简单的Express中间件导入

本教程将介绍将Nest.js应用程序作为简单的Express中间件导入的处理方法,这篇教程是从别的地方看到的,然后加了一些国外程序员的疑问与解答,希望能对你有所帮助,好了,下面开始学习吧。

将Nest.js应用程序作为简单的Express中间件导入 教程 第1张

问题描述

我有一个Nestjs应用程序(睡觉API),我想将其作为简单的Express中间件(不是Nest中间件)导入到另一个节点模块中。实际上我还是不能使它工作。

// main.ts// => The main file of my Nest app, this one is working properly.

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();

// app.middleware.ts

import {Injectable, NestMiddleware} from '@nestjs/common';
import {NestFactory} from '@nestjs/core';
import {AppModule} from './app.module';
import {ExpressAdapter} from '@nestjs/platform-express';
import express, {Request, Response} from 'express';

const bootstrap = async () => {
  const expressApp = express();
  const adapter = new ExpressAdapter(expressApp);
  const app = await NestFactory.create(AppModule, adapter);
  await app.init();
  return app;
};

@Injectable()
export class AppMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: Function) {
 return bootstrap();
  }
}
// express-app.ts// => Here I'm trying to load my app through a simple Express middleware, but it doesn't works.

import express from 'express';
import { AppMiddleware } from './app.middleware';

const app = express();
const PORT = process.env.PORT || 3000;

app.use((req, res, next) => {
  const app = new AppMiddleware().use(req, res, next);
  app.then(next);
});

app.listen(PORT, () => {
  console.log(`app running on port ${PORT}`);
});

main.ts运行我的应用程序时,它工作正常(所有路由都工作正常,我正在获取正确的数据)。但是,当我尝试通过express-app.ts运行应用程序时,所有路由似乎都在工作(它们显示在终端中),但是在任何情况下,我都会收到以下错误,而不是返回JSON对象:

<!DOCTYPE html>
<html lang="en">

<head>
 <meta charset="utf-8">
 <title>Error</title>
</head>

<body>
 <pre>[object Object]</pre>
</body>

</html>

嵌套组件版本:

- @nestjs/common: "^6.10.14"
- @nestjs/core: "^6.10.14"
- @nestjs/platform-express: "^6.10.14"
- express: "^4.16.4"

推荐答案

虽然我不允许将Nest用作中间件本身,但这是可能的。使用nest new express-server -p npm中的基本设置创建新的NestJS应用程序,并使用src/server.ts设置一个小型Express服务器,我能够运行以下代码。

app.midleware.ts

import { Injectable, NestMiddleware } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { ExpressAdapter } from '@nestjs/platform-express';
import { AppModule } from './app.module';

const bootstrap = async (express: Express.Application) => {
  const app = await NestFactory.create(AppModule, new ExpressAdapter(express));
  await app.init();
  return app;
}

@Injectable()
export class AppMiddleware implements NestMiddleware {

  constructor(private expressInstance: Express.Application) {}

  use(req: any, res: any, next: () => void) {
 console.log('In Nest middleware');
 return bootstrap(this.expressInstance);
  }
}

app.control er.ts

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
 return this.appService.getHello();
  }
}

app.service.ts

import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): string {
 return 'Hello World!';
  }
}

app.module e.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

server.ts

import * as express from 'express';

import { AppMiddleware } from './app.middleware';

const app = express();

app.use((req, res, next) => {
  const nest = new AppMiddleware(app).use(req, res, next);
  nest.then(() => {
 next();
  }).catch(err => {
 console.log(JSON.stringify(err));
 next();
  });
});

app.listen(3000, () => {
  console.log('Listening on port 3000');
});

生成命令

npm run build
# mapped to nest build

启动命令

node dist/server.js

测试命令

▶ curl http://localhost:3000
Hello World!

控制台日志

Listening on port 3000
In Nest middleware
[Nest] 24235- 02/18/2020, 8:05:44 PM[NestFactory] Starting Nest application...
[Nest] 24235- 02/18/2020, 8:05:44 PM[InstanceLoader] AppModule dependencies initialized +15ms
[Nest] 24235- 02/18/2020, 8:05:44 PM[RoutesResolver] AppController {/}: +3ms
[Nest] 24235- 02/18/2020, 8:05:44 PM[RouterExplorer] Mapped {/, GET} route +2ms
[Nest] 24235- 02/18/2020, 8:05:44 PM[NestApplication] Nest application successfully started +2ms

请记住以下几点:

1)使用此方法时,除非您缓存Nest服务器,否则将根据每个请求构建一个新的Nest服务器,这只会随着您与Nest方面的发展而进一步降低您的项目速度。

2)您可以将现有的Express服务器传递给ExpressAdapter,就像您在现有代码中所做的那样,并从Nestapp.listen()函数启动服务器。只需确保删除任何错误处理中间件,因为它将开始与Nest处理响应的方式冲突。您应该将这些函数移动到ExceptionFilters。

3)app.middleware中的错误之一是,您不仅在每次调用时创建了一个新的Nest实例,而且还创建了一个新的Express实例,这可能真的会使节点服务器感到困惑。

4)如果您想知道,作为[Object object]传入的错误是标准Express错误Cannot GET /。不知道为什么它被奇怪地序列化,但是捕获中的JSON.stringify()帮助解决了这个问题。

总的来说,我不建议使用此方法但可以这样做。

好了关于将Nest.js应用程序作为简单的Express中间件导入的教程就到这里就结束了,希望趣模板源码网找到的这篇技术文章能帮助到大家,更多技术教程可以在站内搜索。