如何加载运行时配置并在 angular 模块中使用它?
How to load runtime configuration and use it in an angular module?
src/app/graphql.module.ts
import { NgModule } from '@angular/core';
import { APOLLO_OPTIONS } from 'apollo-angular';
import { ApolloClientOptions, InMemoryCache, createHttpLink } from '@apollo/client/core';
import { HttpLink } from 'apollo-angular/http';
const uri = 'http://localhost:3000/graphql'; // <-- add the URL of the GraphQL server here
export function createApollo(httpLink: HttpLink): ApolloClientOptions<any> {
return {
link: httpLink.create({ uri }),
cache: new InMemoryCache(),
};
}
@NgModule({
providers: [
{
provide: APOLLO_OPTIONS,
useFactory: createApollo,
deps: [HttpLink],
},
],
})
export class GraphQLModule {}
这为我们提供了一个硬编码的 URI 变量,显然在本地开发之外无法使用。我希望能够通过在运行时加载配置文件来更改 URI,而不是构建时(即不使用 environment.ts)。阅读 Runtime environment configuration with Angular 后,这似乎是一个合理的方法。
assets/config.json
本地开发的默认配置将在部署时被覆盖
{
"apiUrl": "http://localhost:3000/graphql"
}
src/app/app-config.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
interface AppConfig {
apiUri: string;
}
@Injectable({
providedIn: 'root'
})
export class AppConfigService {
private appConfig: AppConfig;
private http: HttpClient;
constructor(http: HttpClient) {
this.http = http;
}
async loadAppConfig() {
this.appConfig = await this.http.get('/assets/config.json')
.toPromise() as AppConfig;
}
public get apiUri() {
return this.appConfig.apiUri;
}
}
src/app/app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { GraphQLModule } from './graphql.module';
import { AppConfigService } from './app-config.service';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, AppRoutingModule, GraphQLModule, HttpClientModule],
providers: [
{
provide : APP_INITIALIZER,
multi : true,
deps : [AppConfigService],
useFactory : (appConfigService : AppConfigService) => () => appConfigService.loadAppConfig()
}
],
bootstrap: [AppComponent],
})
export class AppModule {}
所以我的问题是,如何使用 GraphQLModule
中的 AppConfigService
获取 apiUrl
并将其设置为 [=19] 中的 uri
=] 工厂函数?
您尝试过使用代理吗?这将允许您在 运行 您的应用程序之前设置您要指向的主机。
APP_INITIALIZER 令牌在您的应用程序开始时被调用,这是设置 apollo 客户端的最佳位置,但尽管官方 apollo-angular documentation 建议使用 APOLLO_OPTIONS令牌,如果您需要以异步方式设置客户端,我建议在您的承诺的映射函数中使用 apollo.create 方法:
src/app/app.module.ts
@NgModule({
...
providers: [
{
provide: APP_INITIALIZER,
useFactory: (appConfigService: AppConfigService, apollo: Apollo, httpLink: HttpLink) =>
() => appConfigService.loadAppConfig()
.pipe(
map((appConfig: AppConfig) => {
apollo.create({
link: httpLink.create({
uri: appConfig.apiUrl,
}),
cache: new InMemoryCache(),
});
})
).toPromise(),
deps: [AppConfigService, Apollo, HttpLink],
multi: true
},
],
...
})
export class AppModule {
}
import {NgModule} from '@angular/core';
import {APOLLO_OPTIONS} from 'apollo-angular';
import {ApolloClientOptions, InMemoryCache} from '@apollo/client/core';
import {HttpLink} from 'apollo-angular/http';
import {ConfigService} from './config.service';
export function createApollo(
httpLink: HttpLink,
configService: ConfigService
): ApolloClientOptions<any> {
return {
link: httpLink.create({uri: configService.apiUri}),
cache: new InMemoryCache(),
};
}
@NgModule({
providers: [
{
provide: APOLLO_OPTIONS,
useFactory: createApollo,
deps: [HttpLink, ConfigService],
},
],
})
export class GraphQLModule {}
src/app/graphql.module.ts
import { NgModule } from '@angular/core';
import { APOLLO_OPTIONS } from 'apollo-angular';
import { ApolloClientOptions, InMemoryCache, createHttpLink } from '@apollo/client/core';
import { HttpLink } from 'apollo-angular/http';
const uri = 'http://localhost:3000/graphql'; // <-- add the URL of the GraphQL server here
export function createApollo(httpLink: HttpLink): ApolloClientOptions<any> {
return {
link: httpLink.create({ uri }),
cache: new InMemoryCache(),
};
}
@NgModule({
providers: [
{
provide: APOLLO_OPTIONS,
useFactory: createApollo,
deps: [HttpLink],
},
],
})
export class GraphQLModule {}
这为我们提供了一个硬编码的 URI 变量,显然在本地开发之外无法使用。我希望能够通过在运行时加载配置文件来更改 URI,而不是构建时(即不使用 environment.ts)。阅读 Runtime environment configuration with Angular 后,这似乎是一个合理的方法。
assets/config.json
本地开发的默认配置将在部署时被覆盖
{
"apiUrl": "http://localhost:3000/graphql"
}
src/app/app-config.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
interface AppConfig {
apiUri: string;
}
@Injectable({
providedIn: 'root'
})
export class AppConfigService {
private appConfig: AppConfig;
private http: HttpClient;
constructor(http: HttpClient) {
this.http = http;
}
async loadAppConfig() {
this.appConfig = await this.http.get('/assets/config.json')
.toPromise() as AppConfig;
}
public get apiUri() {
return this.appConfig.apiUri;
}
}
src/app/app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { GraphQLModule } from './graphql.module';
import { AppConfigService } from './app-config.service';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, AppRoutingModule, GraphQLModule, HttpClientModule],
providers: [
{
provide : APP_INITIALIZER,
multi : true,
deps : [AppConfigService],
useFactory : (appConfigService : AppConfigService) => () => appConfigService.loadAppConfig()
}
],
bootstrap: [AppComponent],
})
export class AppModule {}
所以我的问题是,如何使用 GraphQLModule
中的 AppConfigService
获取 apiUrl
并将其设置为 [=19] 中的 uri
=] 工厂函数?
您尝试过使用代理吗?这将允许您在 运行 您的应用程序之前设置您要指向的主机。
APP_INITIALIZER 令牌在您的应用程序开始时被调用,这是设置 apollo 客户端的最佳位置,但尽管官方 apollo-angular documentation 建议使用 APOLLO_OPTIONS令牌,如果您需要以异步方式设置客户端,我建议在您的承诺的映射函数中使用 apollo.create 方法:
src/app/app.module.ts
@NgModule({
...
providers: [
{
provide: APP_INITIALIZER,
useFactory: (appConfigService: AppConfigService, apollo: Apollo, httpLink: HttpLink) =>
() => appConfigService.loadAppConfig()
.pipe(
map((appConfig: AppConfig) => {
apollo.create({
link: httpLink.create({
uri: appConfig.apiUrl,
}),
cache: new InMemoryCache(),
});
})
).toPromise(),
deps: [AppConfigService, Apollo, HttpLink],
multi: true
},
],
...
})
export class AppModule {
}
import {NgModule} from '@angular/core';
import {APOLLO_OPTIONS} from 'apollo-angular';
import {ApolloClientOptions, InMemoryCache} from '@apollo/client/core';
import {HttpLink} from 'apollo-angular/http';
import {ConfigService} from './config.service';
export function createApollo(
httpLink: HttpLink,
configService: ConfigService
): ApolloClientOptions<any> {
return {
link: httpLink.create({uri: configService.apiUri}),
cache: new InMemoryCache(),
};
}
@NgModule({
providers: [
{
provide: APOLLO_OPTIONS,
useFactory: createApollo,
deps: [HttpLink, ConfigService],
},
],
})
export class GraphQLModule {}