Хотя я не одобряю использование Nest в качестве промежуточного программного обеспечения, это возможно. Используя базовые настройки c из nest new express-server -p npm
для создания нового приложения Nest JS и настройку небольшого express сервера с src/server.ts
, я смог заставить работать следующий код.
app.middleware.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.controller.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.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!
Console Log
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
частично делают это в существующем коде и вместо этого запускают сервер с помощью функции Nest app.listen()
. Просто убедитесь, что удалили все промежуточные программы обработки ошибок, так как они начнут конфликтовать с тем, как Nest обрабатывает ответы. Вместо этого вам следует переместить эти функции в ExceptionFilters.
3) Одна из ошибок в вашем app.middleware
заключается в том, что вы создаете не только новый экземпляр Nest для каждого вызова, но и новый express экземпляр, что действительно может сбить с толку сервер узлов.
4) Ошибка, которая, если вам интересно, пришла как [Object object]
, была стандартной Express ошибкой Cannot GET /
. Не знаю, почему он был сериализован странным образом, но JSON.stringify()
в улове помогло его решить.
В целом, я бы не рекомендовал такой подход , но возможно сделать.