Nest.js 从另一个服务动态调用控制器

问题描述 投票:0回答:1

在我的 Nest.js 设置中有一个

mod.service.ts
,我想在其中调用
project.controller.ts
的 api 端点,我可以通过执行类似的操作来调用它

// mod.service.ts

class MockRequest implements Partial<Request> {
  headers: Headers;

  constructor(headers: Record<string, string> ) {
    for (const[key, value] of Object.entries(headers)) {
      // this.headers.set(key, value); // this fails
    }
  }
}

const requestConfig = new MockRequest({
  ...mod.headers,
  'activity': 4235534,
  'access_token': xxxxxxxxxx,
});

const response = await projectsController['abandonedProjects'].apply(projectsController, requestConfig);

我能够得到响应,但

headers.set()
呼叫失败,
Cannot read properties of undefined (reading 'set')
导致整体呼叫失败(因为未经授权,因此被 JWT 防护阻止)。

知道如何向其注入标头和参数吗?

我有数百个控制器功能,我想避免重构所有这些逻辑以采用正确的服务方法。 (动态调用服务方法并不像看起来那么困难)

目前我通过向自己的服务器发出http请求来实现这一点,这不是一个好方法,我想避免发出http网络请求,所以我正在考虑任何更好的想法。

node.js typescript controller nestjs
1个回答
0
投票

使用NestJS强大的依赖注入系统!

将逻辑重构为可供控制器和其他服务使用的服务。这样您就可以避免向自己的服务器发出不必要的 HTTP 请求。

下面我写了如何用代码实现这一点:

project.service.ts

@Injectable() //decorator used to mark a class as a provider managed by DIS
export class ProjectService {
  constructor(private readonly httpService: HttpService) {}  // Injecting HttpService

  async getAbandondProjects(headers: Record<string, string>) {
    const response = await this.httpService.get('foobarEndpoint', { headers }).toPromise();
    return response.data;
  }
}

project.controller.ts

@Controller('projects')
export class ProjectController {
  constructor(private readonly projectService: ProjectService) {}  // Injecting ProjectService

  @Get('abandoned')
  async abandondProjects(@Headers() headers: Record<string, string>) {
    return this.projectService.getAbandonedProjects(headers);
  }
}

ProjectService
也可以通过其构造函数注入
ModService
,这就是服务之间的DI

mod.service.ts

@Injectable()
export class ModService {
  constructor(private readonly projectService: ProjectService) {}  // Injecting ProjectService

  async someMethod() {
    const headers = {
      ...this.headers,
      'activity': '4235534',
      'access_token': 'xxxxxxxxxx',
    };
    const abandonedProjects = await this.projectService.getAbandonedProjects(headers);
    return abandonedProjects;
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.