Импортируйте приложение Nest. js как простое промежуточное ПО Express - PullRequest
2 голосов
/ 16 февраля 2020

У меня есть приложение Nest js (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>



    
    Error



    [object Object]

Версии компонентов гнезда:

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

1 Ответ

1 голос
/ 19 февраля 2020

Хотя я не одобряю использование 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() в улове помогло его решить.

В целом, я бы не рекомендовал такой подход , но возможно сделать.

...