diff --git a/docs/tutorials/using-backstage-proxy-within-plugin.md b/docs/tutorials/using-backstage-proxy-within-plugin.md index f171f951c4..c82db9ff6c 100644 --- a/docs/tutorials/using-backstage-proxy-within-plugin.md +++ b/docs/tutorials/using-backstage-proxy-within-plugin.md @@ -22,10 +22,11 @@ If your plugin requires access to an API, backstage offers - [Setting up the backstage proxy](#setting-up-the-backstage-proxy) - [Calling an API using the backstage proxy](#calling-an-api-using-the-backstage-proxy) - - [Defining the API client interface](#defining-the-api-client-interface) - - [Creating the API client](#creating-the-api-client) - - [Bundling your ApiRef with your plugin](#bundling-your-apiref-with-your-plugin) - - [Using the API in your components](#using-your-plugin-in-your-components) + - [Option 1: Calling the proxy directly from the frontend plugin](#option-1-calling-the-proxy-directly-from-the-frontend-plugin) + - [Option 2: Defining the API client interface](#defining-the-api-client-interface) + - [Creating the API client](#creating-the-api-client) + - [Bundling your ApiRef with your plugin](#bundling-your-apiref-with-your-plugin) + - [Using the API in your components](#using-your-plugin-in-your-components) ## Setting up the backstage proxy @@ -55,9 +56,44 @@ the proxy. Backstage is structured in such a way that you could run the backstage frontend independently of the backend. So when calling your API you need to prepend the backend URL to your http call. -The recommended pattern for calling out to services is to wrap your calls in a -[Utility API](../api/utility-apis.md). This section describes the steps to wrap -your API client in a Utility API, which are: +There are two recommended patterns for calling out to services: using +`discoveryApi` and +`fetchApi` directly from your frontend plugin or wrapping your calls in a [Utility API](../api/utility-apis.md). + +## Option 1: Calling the proxy directly from the frontend plugin + +From you frontend plugin use the `fetchApi` and `discoveryApi` to call the proper +proxy endpoint: + +```tsx title="plugins/my-awesome-plugin/src/components/AwesomeUsersTable.tsx" +import { + useApi, + discoveryApiRef, + fetchApiRef, +} from '@backstage/core-plugin-api'; +import { Progress, Alert } from '@backstage/core-components'; +import useAsync from 'react-use/esm/useAsync'; +import { myAwesomeApiRef } from '../../api'; + +export const AwesomeUsersTable = () => { + const fetchApi = useApi(fetchApiRef); + const discoveryApi = useApi(discoveryApiRef); + + const { value, loading, error } = useAsync(async () => { + const baseUrl = await discoveryApi.getBaseUrl('proxy'); + // As configured previously for the backend proxy + const resp = await fetchApi.fetch(`${baseUrl}/`); + if (!resp.ok) throw new Error(resp.statusText); + return resp.json(); + }, [fetchApi, discoveryApi]); + + // ... +}; +``` + +## Option 2: Defining the API client interface + +This section describes the steps to wrap your API client in a [Utility API](../api/utility-apis.md), which are: - use [`createApiRef`](../reference/core-plugin-api.createapiref.md) to create a new [`ApiRef`](../reference/core-plugin-api.apiref.md) @@ -69,7 +105,7 @@ your API client in a Utility API, which are: - finally, you can use your API in your components by calling [`useApi`](../reference/core-plugin-api.useapi.md) -## Defining the API client interface +### Defining the API client interface Continuing from the previous example, let's assume that _https://api.myawesomeservice.com/v1_ has the following endpoints: @@ -103,7 +139,7 @@ export const myAwesomeApiRef = createApiRef({ }); ``` -## Creating the API client +### Creating the API client The `myAwesomeApiRef` is what you will use within backstage to reference the API client in your plugin. The API ref itself is a global singleton object that @@ -155,7 +191,7 @@ export class MyAwesomeApiClient implements MyAwesomeApi { > [DiscoveryApi](../reference/core-plugin-api.discoveryapi.md) or the > [FetchApi](../reference/core-plugin-api.fetchapi.md) -## Bundling your ApiRef with your plugin +### Bundling your ApiRef with your plugin The final piece in the puzzle is bundling the `myAwesomeApiRef` with a factory for `MyAwesomeApiClient` objects. This is usually done in the `plugin.ts` file @@ -195,22 +231,24 @@ export const myCustomPlugin = createPlugin({ }); ``` -## Using the API in your components +### Using the API in your components Now you should be able to access your API using the backstage hook [`useApi`](../reference/core-plugin-api.useapi.md) from within your plugin code. -```ts -/* plugins/my-awesome-plugin/src/components/AwesomeUsersTable.tsx */ +```ts title="plugins/my-awesome-plugin/src/components/AwesomeUsersTable.tsx" import { useApi } from '@backstage/core-plugin-api'; import { myAwesomeApiRef } from '../../api'; +import useAsync from 'react-use/esm/useAsync'; export const AwesomeUsersTable = () => { const apiClient = useApi(myAwesomeApiRef); - apiClient.listUsers() - .then( - ... - ) -} + const { value, loading, error } = useAsync(async () => { + const users = await apiClient.listUsers(); + return users; + }, [apiClient]); + + // ... +}; ```