feat(apidocs): add resolvers prop to AsyncApiDefinitionWidget
Signed-off-by: Simon Stamm <simon.stamm@tui.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-api-docs': patch
|
||||
---
|
||||
|
||||
Added `resolvers` prop to `AsyncApiDefinitionWidget`. This allows to override the default http/https resolvers, for example to add authentication to requests to internal schema registries.
|
||||
@@ -50,6 +50,7 @@ To link that a component provides or consumes an API, see the [`providesApis`](h
|
||||
- [Custom Api Renderings](#custom-api-renderings)
|
||||
- [Adding Swagger UI Interceptor](#adding-requestinterceptor-to-swagger-ui)
|
||||
- [Providing Swagger UI Specific Supported Methods](#provide-specific-supported-methods-to-swagger-ui)
|
||||
- [Custom Resolvers for AsyncApi](#custom-resolvers-for-asyncapi)
|
||||
- [Integrations](#integrations)
|
||||
- [Implementing OAuth 2 Authorization Code flow with Swagger UI](#implementing-oauth-2-authorization-code-flow-with-swagger-ui)
|
||||
|
||||
@@ -1092,6 +1093,61 @@ export default createExtensionOverrides({
|
||||
|
||||
N.B. if you wish to disable the `Try It Out` feature for your API, you can provide an empty list to the `supportedSubmitMethods` parameter.
|
||||
|
||||
##### Custom Resolvers for AsyncApi
|
||||
|
||||
You can override the default http/https resolvers, for example to add authentication to requests to internal schema registries by providing the `resolvers` prop to the `AsyncApiDefinitionWidget`. This is an example:
|
||||
|
||||
```tsx
|
||||
...
|
||||
import {
|
||||
AsyncApiDefinitionWidget,
|
||||
apiDocsConfigRef,
|
||||
defaultDefinitionWidgets,
|
||||
} from '@backstage/plugin-api-docs';
|
||||
import { ApiEntity } from '@backstage/catalog-model';
|
||||
|
||||
export const apis: AnyApiFactory[] = [
|
||||
...
|
||||
createApiFactory({
|
||||
api: apiDocsConfigRef,
|
||||
deps: {},
|
||||
factory: () => {
|
||||
const myCustomResolver = {
|
||||
schema: 'https',
|
||||
order: 1,
|
||||
canRead: true,
|
||||
async read(uri: any) {
|
||||
const response = await fetch(request, {
|
||||
headers: {
|
||||
X-Custom: 'Custom',
|
||||
},
|
||||
});
|
||||
return response.text();
|
||||
},
|
||||
};
|
||||
|
||||
const definitionWidgets = defaultDefinitionWidgets().map(obj => {
|
||||
if (obj.type === 'asyncapi') {
|
||||
return {
|
||||
...obj,
|
||||
component: (definition) => (
|
||||
<AsyncApiDefinitionWidget definition={definition} resolvers={[myCustomResolver]} />
|
||||
),
|
||||
};
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
|
||||
return {
|
||||
getApiDefinitionWidget: (apiEntity: ApiEntity) => {
|
||||
return definitionWidgets.find(d => d.type === apiEntity.spec.type);
|
||||
},
|
||||
};
|
||||
}
|
||||
})
|
||||
]
|
||||
```
|
||||
|
||||
### Integrations
|
||||
|
||||
#### Implementing OAuth 2 Authorization Code flow with Swagger UI
|
||||
|
||||
@@ -222,10 +222,6 @@ security:
|
||||
- [read_pets, write_pets]
|
||||
```
|
||||
|
||||
## Links
|
||||
|
||||
- [The Backstage homepage](https://backstage.io)
|
||||
|
||||
### Adding `requestInterceptor` to Swagger UI
|
||||
|
||||
To configure a [`requestInterceptor` for Swagger UI](https://github.com/swagger-api/swagger-ui/tree/master/flavors/swagger-ui-react#requestinterceptor-proptypesfunc) you'll need to add the following to your `api.tsx`:
|
||||
@@ -319,3 +315,62 @@ export const apis: AnyApiFactory[] = [
|
||||
|
||||
N.B. if you wish to disable the `Try It Out` feature for your API, you can provide an empty list to
|
||||
the `supportedSubmitMethods` parameter.
|
||||
|
||||
### Custom Resolvers for AsyncApi
|
||||
|
||||
You can override the default http/https resolvers, for example to add authentication to requests to internal schema registries by providing the `resolvers` prop to the `AsyncApiDefinitionWidget`. This is an example:
|
||||
|
||||
```tsx
|
||||
...
|
||||
import {
|
||||
AsyncApiDefinitionWidget,
|
||||
apiDocsConfigRef,
|
||||
defaultDefinitionWidgets,
|
||||
} from '@backstage/plugin-api-docs';
|
||||
import { ApiEntity } from '@backstage/catalog-model';
|
||||
|
||||
export const apis: AnyApiFactory[] = [
|
||||
...
|
||||
createApiFactory({
|
||||
api: apiDocsConfigRef,
|
||||
deps: {},
|
||||
factory: () => {
|
||||
const myCustomResolver = {
|
||||
schema: 'https',
|
||||
order: 1,
|
||||
canRead: true,
|
||||
async read(uri: any) {
|
||||
const response = await fetch(request, {
|
||||
headers: {
|
||||
X-Custom: 'Custom',
|
||||
},
|
||||
});
|
||||
return response.text();
|
||||
},
|
||||
};
|
||||
|
||||
const definitionWidgets = defaultDefinitionWidgets().map(obj => {
|
||||
if (obj.type === 'asyncapi') {
|
||||
return {
|
||||
...obj,
|
||||
component: (definition) => (
|
||||
<AsyncApiDefinitionWidget definition={definition} resolvers={[myCustomResolver]} />
|
||||
),
|
||||
};
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
|
||||
return {
|
||||
getApiDefinitionWidget: (apiEntity: ApiEntity) => {
|
||||
return definitionWidgets.find(d => d.type === apiEntity.spec.type);
|
||||
},
|
||||
};
|
||||
}
|
||||
})
|
||||
]
|
||||
```
|
||||
|
||||
## Links
|
||||
|
||||
- [The Backstage homepage](https://backstage.io)
|
||||
|
||||
@@ -83,6 +83,15 @@ export const AsyncApiDefinitionWidget: (
|
||||
// @public (undocumented)
|
||||
export type AsyncApiDefinitionWidgetProps = {
|
||||
definition: string;
|
||||
resolvers?: AsyncApiResolver[];
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export type AsyncApiResolver = {
|
||||
schema: string;
|
||||
order: number;
|
||||
canRead: boolean;
|
||||
read(uri: any): Promise<string>;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
|
||||
@@ -19,6 +19,7 @@ import '@asyncapi/react-component/styles/default.css';
|
||||
import { makeStyles, alpha, darken } from '@material-ui/core/styles';
|
||||
import React from 'react';
|
||||
import { useTheme } from '@material-ui/core/styles';
|
||||
import { AsyncApiResolver } from './AsyncApiDefinitionWidget';
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
root: {
|
||||
@@ -143,7 +144,7 @@ const useStyles = makeStyles(theme => ({
|
||||
},
|
||||
}));
|
||||
|
||||
const httpsFetchResolver = {
|
||||
const httpsFetchResolver: AsyncApiResolver = {
|
||||
schema: 'https',
|
||||
order: 1,
|
||||
canRead: true,
|
||||
@@ -153,7 +154,7 @@ const httpsFetchResolver = {
|
||||
},
|
||||
};
|
||||
|
||||
const httpFetchResolver = {
|
||||
const httpFetchResolver: AsyncApiResolver = {
|
||||
schema: 'http',
|
||||
order: 1,
|
||||
canRead: true,
|
||||
@@ -175,15 +176,24 @@ const config = {
|
||||
|
||||
type Props = {
|
||||
definition: string;
|
||||
resolvers?: AsyncApiResolver[];
|
||||
};
|
||||
|
||||
export const AsyncApiDefinition = ({ definition }: Props): JSX.Element => {
|
||||
export const AsyncApiDefinition = ({
|
||||
definition,
|
||||
resolvers,
|
||||
}: Props): JSX.Element => {
|
||||
const classes = useStyles();
|
||||
const theme = useTheme();
|
||||
const classNames = `${classes.root} ${
|
||||
theme.palette.type === 'dark' ? classes.dark : ''
|
||||
}`;
|
||||
|
||||
// Overwrite default resolvers if custom ones are set
|
||||
if (resolvers) {
|
||||
config.parserOptions.__unstable.resolver.resolvers = resolvers;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classNames}>
|
||||
<AsyncApi schema={definition} config={config} />
|
||||
|
||||
@@ -25,9 +25,18 @@ const LazyAsyncApiDefinition = React.lazy(() =>
|
||||
})),
|
||||
);
|
||||
|
||||
/** @public */
|
||||
export type AsyncApiResolver = {
|
||||
schema: string;
|
||||
order: number;
|
||||
canRead: boolean;
|
||||
read(uri: any): Promise<string>;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export type AsyncApiDefinitionWidgetProps = {
|
||||
definition: string;
|
||||
resolvers?: AsyncApiResolver[];
|
||||
};
|
||||
|
||||
/** @public */
|
||||
|
||||
@@ -15,4 +15,7 @@
|
||||
*/
|
||||
|
||||
export { AsyncApiDefinitionWidget } from './AsyncApiDefinitionWidget';
|
||||
export type { AsyncApiDefinitionWidgetProps } from './AsyncApiDefinitionWidget';
|
||||
export type {
|
||||
AsyncApiDefinitionWidgetProps,
|
||||
AsyncApiResolver,
|
||||
} from './AsyncApiDefinitionWidget';
|
||||
|
||||
Reference in New Issue
Block a user