docs: tweaks proxy usage

Signed-off-by: Vincenzo Scamporlino <vincenzos@spotify.com>
This commit is contained in:
Vincenzo Scamporlino
2025-05-09 21:05:21 +02:00
parent b89550526e
commit dbfab1fa9e
@@ -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}/<your-proxy-uri>`);
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<MyAwesomeApi>({
});
```
## 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]);
// ...
};
```