From 996440126373165b4c88e8f054fa3b88588b3287 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 11 Jun 2020 19:24:36 +0200 Subject: [PATCH] packages/core-api: temporary solution for giving access to config when creating APIs --- packages/app/src/App.tsx | 2 +- packages/app/src/apis.ts | 99 ++++++++++++++++-------------- packages/core-api/src/app/App.tsx | 22 +++++-- packages/core-api/src/app/types.ts | 7 ++- 4 files changed, 76 insertions(+), 54 deletions(-) diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index d348049157..ed0518485a 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -18,7 +18,7 @@ import { createApp, AlertDisplay, OAuthRequestDialog } from '@backstage/core'; import React, { FC } from 'react'; import Root from './components/Root'; import * as plugins from './plugins'; -import apis from './apis'; +import { apis } from './apis'; import { hot } from 'react-hot-loader/root'; const app = createApp({ diff --git a/packages/app/src/apis.ts b/packages/app/src/apis.ts index 4d78ef1431..9bfc618216 100644 --- a/packages/app/src/apis.ts +++ b/packages/app/src/apis.ts @@ -15,11 +15,11 @@ */ import { - ApiHolder, ApiRegistry, alertApiRef, errorApiRef, AlertApiForwarder, + ConfigApi, ErrorApiForwarder, ErrorAlerter, featureFlagsApiRef, @@ -46,59 +46,64 @@ import { catalogApiRef, CatalogClient } from '@backstage/plugin-catalog'; import { gitOpsApiRef, GitOpsRestApi } from '@backstage/plugin-gitops-profiles'; -const builder = ApiRegistry.builder(); +export const apis = (config: ConfigApi) => { + // eslint-disable-next-line no-console + console.log(`Creating APIs for ${config.getString('app.title')}`); -const alertApi = builder.add(alertApiRef, new AlertApiForwarder()); -const errorApi = builder.add( - errorApiRef, - new ErrorAlerter(alertApi, new ErrorApiForwarder()), -); + const builder = ApiRegistry.builder(); -builder.add(storageApiRef, WebStorage.create({ errorApi })); -builder.add(circleCIApiRef, new CircleCIApi()); -builder.add(featureFlagsApiRef, new FeatureFlags()); + const alertApi = builder.add(alertApiRef, new AlertApiForwarder()); + const errorApi = builder.add( + errorApiRef, + new ErrorAlerter(alertApi, new ErrorApiForwarder()), + ); -builder.add(lighthouseApiRef, new LighthouseRestApi('http://localhost:3003')); + builder.add(storageApiRef, WebStorage.create({ errorApi })); + builder.add(circleCIApiRef, new CircleCIApi()); + builder.add(featureFlagsApiRef, new FeatureFlags()); -const oauthRequestApi = builder.add( - oauthRequestApiRef, - new OAuthRequestManager(), -); + builder.add(lighthouseApiRef, new LighthouseRestApi('http://localhost:3003')); -builder.add( - googleAuthApiRef, - GoogleAuth.create({ - apiOrigin: 'http://localhost:7000', - basePath: '/auth/', - oauthRequestApi, - }), -); + const oauthRequestApi = builder.add( + oauthRequestApiRef, + new OAuthRequestManager(), + ); -builder.add( - githubAuthApiRef, - GithubAuth.create({ - apiOrigin: 'http://localhost:7000', - basePath: '/auth/', - oauthRequestApi, - }), -); + builder.add( + googleAuthApiRef, + GoogleAuth.create({ + apiOrigin: 'http://localhost:7000', + basePath: '/auth/', + oauthRequestApi, + }), + ); -builder.add( - techRadarApiRef, - new TechRadar({ - width: 1500, - height: 800, - }), -); + builder.add( + githubAuthApiRef, + GithubAuth.create({ + apiOrigin: 'http://localhost:7000', + basePath: '/auth/', + oauthRequestApi, + }), + ); -builder.add( - catalogApiRef, - new CatalogClient({ - apiOrigin: 'http://localhost:3000', - basePath: '/catalog/api', - }), -); + builder.add( + techRadarApiRef, + new TechRadar({ + width: 1500, + height: 800, + }), + ); -builder.add(gitOpsApiRef, new GitOpsRestApi('http://localhost:3008')); + builder.add( + catalogApiRef, + new CatalogClient({ + apiOrigin: 'http://localhost:3000', + basePath: '/catalog/api', + }), + ); -export default builder.build() as ApiHolder; + builder.add(gitOpsApiRef, new GitOpsRestApi('http://localhost:3008')); + + return builder.build(); +}; diff --git a/packages/core-api/src/app/App.tsx b/packages/core-api/src/app/App.tsx index 7cc37c2544..972acbd8ea 100644 --- a/packages/core-api/src/app/App.tsx +++ b/packages/core-api/src/app/App.tsx @@ -17,7 +17,7 @@ import React, { ComponentType, FC, useMemo } from 'react'; import { Route, Switch, Redirect } from 'react-router-dom'; import { AppContextProvider } from './AppContext'; -import { BackstageApp, AppComponents, AppConfigLoader } from './types'; +import { BackstageApp, AppComponents, AppConfigLoader, Apis } from './types'; import { BackstagePlugin } from '../plugin'; import { FeatureFlagsRegistryItem } from './FeatureFlags'; import { featureFlagsApiRef } from '../apis/definitions'; @@ -38,7 +38,7 @@ import { ApiAggregator } from '../apis/ApiAggregator'; import { useAsync } from 'react-use'; type FullAppOptions = { - apis: ApiHolder; + apis: Apis; icons: SystemIcons; plugins: BackstagePlugin[]; components: AppComponents; @@ -47,15 +47,17 @@ type FullAppOptions = { }; export class PrivateAppImpl implements BackstageApp { - private readonly apis: ApiHolder; + private apis?: ApiHolder = undefined; private readonly icons: SystemIcons; private readonly plugins: BackstagePlugin[]; private readonly components: AppComponents; private readonly themes: AppTheme[]; private readonly configLoader?: AppConfigLoader; + private apisOrFactory: Apis; + constructor(options: FullAppOptions) { - this.apis = options.apis; + this.apisOrFactory = options.apis; this.icons = options.icons; this.plugins = options.plugins; this.components = options.components; @@ -64,6 +66,9 @@ export class PrivateAppImpl implements BackstageApp { } getApis(): ApiHolder { + if (!this.apis) { + throw new Error('Tried to access APIs before app was loaded'); + } return this.apis; } @@ -196,6 +201,15 @@ export class PrivateAppImpl implements BackstageApp { [appThemeApiRef, AppThemeSelector.createWithStorage(this.themes)], [configApiRef, configReader], ]); + + if (!this.apis) { + if ('get' in this.apisOrFactory) { + this.apis = this.apisOrFactory; + } else { + this.apis = this.apisOrFactory(configReader); + } + } + const apis = new ApiAggregator(this.apis, appApis); const { Router } = this.components; diff --git a/packages/core-api/src/app/types.ts b/packages/core-api/src/app/types.ts index 664c5238bc..44201d1464 100644 --- a/packages/core-api/src/app/types.ts +++ b/packages/core-api/src/app/types.ts @@ -18,7 +18,7 @@ import { ComponentType } from 'react'; import { IconComponent, SystemIconKey, SystemIcons } from '../icons'; import { BackstagePlugin } from '../plugin'; import { ApiHolder } from '../apis'; -import { AppTheme } from '../apis/definitions'; +import { AppTheme, ConfigApi } from '../apis/definitions'; import { AppConfig } from '@backstage/config'; export type BootErrorPageProps = { @@ -41,13 +41,16 @@ export type AppComponents = { */ export type AppConfigLoader = () => Promise; +// TODO(Rugvip): Temporary workaround for accessing config when instantiating APIs, we might want to do this differently +export type Apis = ApiHolder | ((config: ConfigApi) => ApiHolder); + export type AppOptions = { /** * A holder of all APIs available in the app. * * Use for example ApiRegistry or ApiTestRegistry. */ - apis?: ApiHolder; + apis?: Apis; /** * Supply icons to override the default ones.