Как повторно использовать службы Angular 6 API в сценарии узла?

Я хотел бы повторно использовать некоторые службы Angular 6 API в сценарии узлов и столкнулся с некоторыми проблемами, которые все правильно инициализируют.

Сервисы API создаются с использованием Swagger Codegen (-l typescript-angular), который дает мне, например:

@Injectable()
export class UserService {

    constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) { 
      ... 
    }

}

Эти сервисы отлично работают в моем приложении Angular 6, и теперь я хотел бы использовать их в узле для некоторых сценариев. Я знаю, что Swagger Codegen также может генерировать чистый клиент Typcript, но все равно предпочитает повторно использовать существующие услуги Angular, чтобы поддерживать базовую базу кода в очереди.

Проблема, с которой я столкнулся, - это вызов этого конструктора без инъекции зависимостей.

Кажется, очень сложно получить действительный объект HttpClient без инъекции зависимостей. В AngularJS я использовал для этого HttpClient, но эта библиотека не предоставляет такой же интерфейс, как HttpClient как кажется (все еще обещает вместо новых наблюдаемых в Angular 6).

Мне кажется, что есть два варианта:

  1. Как-то получить объект HttpClient → не может заставить это работать.
  2. Внедрить другой объект HTTP-клиента, который предоставляет тот же интерфейс ->, похоже, не может найти его.

Кто-нибудь знает, как правильно справиться с этим?

Ура,

М.

Ответ 1

HttpClient не должен создаваться вручную, и это не простой процесс, поскольку он имеет множество зависимостей. Угловой инжектор выполняет всю работу по инъекции зависимостей и должен использоваться для получения экземпляра.

Как показано в этом ответе, можно получить экземпляр Углового провайдера (HttpClient), настроив модуль и загрузив его.

Для UserService должен использоваться очень похожий подход. Вот упрощенный, но работоспособный пример:

import 'zone.js/dist/zone-node';
import 'reflect-metadata';

import {Injector, Injectable, NgModule } from '@angular/core'
import {HttpClient, HttpClientModule} from '@angular/common/http'
import {ServerModule, platformDynamicServer} from '@angular/platform-server';

@Injectable()
export class UserService {
  constructor(protected httpClient: HttpClient) { 
    httpClient.get('https://google.com/').subscribe(console.log, console.error);
  }
}

@NgModule({
  imports: [ServerModule, HttpClientModule],
  providers: [UserService]
})
export class AppModule {
  ngDoBootstrap() {}
}

(async () => {
    const platform = platformDynamicServer();
    const appModule = await platform.bootstrapModule(AppModule);
    const userService = appModule.injector.get(UserService);
})()
.catch(console.error);

Для этого требуется совместимая конфигурация TypeScript, например:

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "strict": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}