From 996440126373165b4c88e8f054fa3b88588b3287 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 11 Jun 2020 19:24:36 +0200 Subject: [PATCH 1/2] 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. From 7c088c5595232c6d67d026f9b622b02badbb1f0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20=C3=85lund?= Date: Thu, 11 Jun 2020 21:03:38 +0200 Subject: [PATCH 2/2] Fix incorrect backend path in docs (#1258) --- packages/backend/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/README.md b/packages/backend/README.md index e9bf4199ff..64078006e7 100644 --- a/packages/backend/README.md +++ b/packages/backend/README.md @@ -40,7 +40,7 @@ to the backend. These are places where the backend can find some entity descript data to consume and serve. To get started, you can issue the following after starting the backend, from inside -the `packages/catalog-backend` directory: +the `plugins/catalog-backend` directory: ```bash yarn mock-catalog-data