mirror of
https://github.com/Redocly/redoc.git
synced 2025-08-08 14:14:56 +03:00
feat: support x-response-samples to render code responses
This commit is contained in:
parent
3c8d6b623c
commit
5ea3dc68dd
|
@ -194,6 +194,7 @@ ReDoc makes use of the following [vendor extensions](http://swagger.io/specifica
|
||||||
* [`x-logo`](docs/redoc-vendor-extensions.md#x-logo) - is used to specify API logo
|
* [`x-logo`](docs/redoc-vendor-extensions.md#x-logo) - is used to specify API logo
|
||||||
* [`x-traitTag`](docs/redoc-vendor-extensions.md#x-traitTag) - useful for handling out common things like Pagination, Rate-Limits, etc
|
* [`x-traitTag`](docs/redoc-vendor-extensions.md#x-traitTag) - useful for handling out common things like Pagination, Rate-Limits, etc
|
||||||
* [`x-code-samples`](docs/redoc-vendor-extensions.md#x-code-samples) - specify operation code samples
|
* [`x-code-samples`](docs/redoc-vendor-extensions.md#x-code-samples) - specify operation code samples
|
||||||
|
* [`x-response-samples`](docs/redoc-vendor-extensions.md#x-response-samples) - specify operation response code samples
|
||||||
* [`x-examples`](docs/redoc-vendor-extensions.md#x-examples) - specify JSON example for requests
|
* [`x-examples`](docs/redoc-vendor-extensions.md#x-examples) - specify JSON example for requests
|
||||||
* [`x-nullable`](docs/redoc-vendor-extensions.md#nullable) - mark schema param as a nullable
|
* [`x-nullable`](docs/redoc-vendor-extensions.md#nullable) - mark schema param as a nullable
|
||||||
* [`x-displayName`](docs/redoc-vendor-extensions.md#x-displayname) - specify human-friendly names for the menu categories
|
* [`x-displayName`](docs/redoc-vendor-extensions.md#x-displayname) - specify human-friendly names for the menu categories
|
||||||
|
|
|
@ -17,14 +17,14 @@ info:
|
||||||
It was **extended** to illustrate features of [generator-openapi-repo](https://github.com/Rebilly/generator-openapi-repo)
|
It was **extended** to illustrate features of [generator-openapi-repo](https://github.com/Rebilly/generator-openapi-repo)
|
||||||
tool and [ReDoc](https://github.com/Rebilly/ReDoc) documentation. In addition to standard
|
tool and [ReDoc](https://github.com/Rebilly/ReDoc) documentation. In addition to standard
|
||||||
OpenAPI syntax we use a few [vendor extensions](https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md).
|
OpenAPI syntax we use a few [vendor extensions](https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md).
|
||||||
|
|
||||||
# OpenAPI Specification
|
# OpenAPI Specification
|
||||||
This API is documented in **OpenAPI format** and is based on
|
This API is documented in **OpenAPI format** and is based on
|
||||||
[Petstore sample](http://petstore.swagger.io/) provided by [swagger.io](http://swagger.io) team.
|
[Petstore sample](http://petstore.swagger.io/) provided by [swagger.io](http://swagger.io) team.
|
||||||
It was **extended** to illustrate features of [generator-openapi-repo](https://github.com/Rebilly/generator-openapi-repo)
|
It was **extended** to illustrate features of [generator-openapi-repo](https://github.com/Rebilly/generator-openapi-repo)
|
||||||
tool and [ReDoc](https://github.com/Rebilly/ReDoc) documentation. In addition to standard
|
tool and [ReDoc](https://github.com/Rebilly/ReDoc) documentation. In addition to standard
|
||||||
OpenAPI syntax we use a few [vendor extensions](https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md).
|
OpenAPI syntax we use a few [vendor extensions](https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md).
|
||||||
|
|
||||||
# Cross-Origin Resource Sharing
|
# Cross-Origin Resource Sharing
|
||||||
This API features Cross-Origin Resource Sharing (CORS) implemented in compliance with [W3C spec](https://www.w3.org/TR/cors/).
|
This API features Cross-Origin Resource Sharing (CORS) implemented in compliance with [W3C spec](https://www.w3.org/TR/cors/).
|
||||||
And that allows cross-domain communication from the browser.
|
And that allows cross-domain communication from the browser.
|
||||||
|
@ -38,7 +38,7 @@ info:
|
||||||
OAuth2 - an open protocol to allow secure authorization in a simple
|
OAuth2 - an open protocol to allow secure authorization in a simple
|
||||||
and standard method from web, mobile and desktop applications.
|
and standard method from web, mobile and desktop applications.
|
||||||
|
|
||||||
<security-definitions />
|
<security-definitions />
|
||||||
|
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
title: Swagger Petstore
|
title: Swagger Petstore
|
||||||
|
@ -187,6 +187,27 @@ paths:
|
||||||
description: Invalid ID supplied
|
description: Invalid ID supplied
|
||||||
'404':
|
'404':
|
||||||
description: Pet not found
|
description: Pet not found
|
||||||
|
x-code-samples:
|
||||||
|
- lang: 'Javascript'
|
||||||
|
source: |
|
||||||
|
const pet = new PetStore.v1.Pet();
|
||||||
|
await pet.get(1, (err, pet);
|
||||||
|
x-response-samples:
|
||||||
|
- lang: 'Javascript'
|
||||||
|
source: |
|
||||||
|
Pet {
|
||||||
|
id: number;
|
||||||
|
name: String;
|
||||||
|
|
||||||
|
getName(): String;
|
||||||
|
}
|
||||||
|
- lang: 'Javascript'
|
||||||
|
label: 'Javascript error'
|
||||||
|
source: |
|
||||||
|
ServerResponse {
|
||||||
|
status: number;
|
||||||
|
message: String;
|
||||||
|
}
|
||||||
security:
|
security:
|
||||||
- api_key: []
|
- api_key: []
|
||||||
post:
|
post:
|
||||||
|
|
|
@ -183,15 +183,54 @@ Operation code sample
|
||||||
###### Code Sample Object example
|
###### Code Sample Object example
|
||||||
json
|
json
|
||||||
```json
|
```json
|
||||||
{
|
[
|
||||||
"lang": "JavaScript",
|
{
|
||||||
"source": "console.log('Hello World');"
|
"lang": "JavaScript",
|
||||||
}
|
"source": "console.log('Hello World');"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
```
|
```
|
||||||
yaml
|
yaml
|
||||||
```yaml
|
```yaml
|
||||||
lang: JavaScript
|
-
|
||||||
source: console.log('Hello World');
|
lang: JavaScript
|
||||||
|
source: console.log('Hello World');
|
||||||
|
```
|
||||||
|
|
||||||
|
#### x-response-samples
|
||||||
|
| Field Name | Type | Description |
|
||||||
|
| :----------------- | :------: | :---------- |
|
||||||
|
| x-response-samples | [ [Code Sample Object](#responseSampleObject) ] | A list of response samples associated with operation, useful when your SDK renders different structure of your API |
|
||||||
|
|
||||||
|
###### Usage in ReDoc
|
||||||
|
`x-response-samples` are rendered on the right panel of ReDoc, after response tabs.
|
||||||
|
|
||||||
|
#### <a name="codeSampleObject"></a>Code Sample Object
|
||||||
|
Operation code sample
|
||||||
|
###### Fixed fields
|
||||||
|
| Field Name | Type | Description |
|
||||||
|
| :---------- | :------: | :----------- |
|
||||||
|
| lang | string | Code sample language. Value should be one of the following [list](https://github.com/github/linguist/blob/master/lib/linguist/popular.yml) |
|
||||||
|
| label | string? | Code sample label e.g. `Node` or `Python2.7`, _optional_, `lang` will be used by default |
|
||||||
|
| source | string | Code sample source code |
|
||||||
|
|
||||||
|
|
||||||
|
###### Response Sample Object example
|
||||||
|
json
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"lang": "JavaScript",
|
||||||
|
"source": "console.log('Hello World');"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
yaml
|
||||||
|
```yaml
|
||||||
|
-
|
||||||
|
lang: JavaScript
|
||||||
|
source: console.log('Hello World');
|
||||||
```
|
```
|
||||||
|
|
||||||
### Parameter Object vendor extensions
|
### Parameter Object vendor extensions
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { OperationModel } from '../../services/models';
|
||||||
|
|
||||||
import { RightPanelHeader, Tab, TabList, TabPanel, Tabs } from '../../common-elements';
|
import { RightPanelHeader, Tab, TabList, TabPanel, Tabs } from '../../common-elements';
|
||||||
import { PayloadSamples } from '../PayloadSamples/PayloadSamples';
|
import { PayloadSamples } from '../PayloadSamples/PayloadSamples';
|
||||||
|
import { SourceCodeWithCopy } from '../SourceCode/SourceCode';
|
||||||
|
|
||||||
export interface ResponseSamplesProps {
|
export interface ResponseSamplesProps {
|
||||||
operation: OperationModel;
|
operation: OperationModel;
|
||||||
|
@ -16,6 +17,8 @@ export class ResponseSamples extends React.Component<ResponseSamplesProps> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { operation } = this.props;
|
const { operation } = this.props;
|
||||||
|
const samples = operation.responseSamples;
|
||||||
|
|
||||||
const responses = operation.responses.filter(response => {
|
const responses = operation.responses.filter(response => {
|
||||||
return response.content && response.content.hasSample;
|
return response.content && response.content.hasSample;
|
||||||
});
|
});
|
||||||
|
@ -32,6 +35,11 @@ export class ResponseSamples extends React.Component<ResponseSamplesProps> {
|
||||||
{response.code}
|
{response.code}
|
||||||
</Tab>
|
</Tab>
|
||||||
))}
|
))}
|
||||||
|
{samples.map(sample => (
|
||||||
|
<Tab key={`response-${sample.label || sample.lang}`}>
|
||||||
|
{sample.label || sample.lang}
|
||||||
|
</Tab>
|
||||||
|
))}
|
||||||
</TabList>
|
</TabList>
|
||||||
{responses.map(response => (
|
{responses.map(response => (
|
||||||
<TabPanel key={response.code}>
|
<TabPanel key={response.code}>
|
||||||
|
@ -40,6 +48,11 @@ export class ResponseSamples extends React.Component<ResponseSamplesProps> {
|
||||||
</div>
|
</div>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
))}
|
))}
|
||||||
|
{samples.map(sample => (
|
||||||
|
<TabPanel key={`response-${sample.label || sample.lang}`}>
|
||||||
|
<SourceCodeWithCopy lang={sample.lang} source={sample.source} />
|
||||||
|
</TabPanel>
|
||||||
|
))}
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
)) ||
|
)) ||
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
OpenAPIPath,
|
OpenAPIPath,
|
||||||
OpenAPIServer,
|
OpenAPIServer,
|
||||||
OpenAPIXCodeSample,
|
OpenAPIXCodeSample,
|
||||||
|
OpenAPIXResponseSample,
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -62,6 +63,7 @@ export class OperationModel implements IMenuItem {
|
||||||
servers: OpenAPIServer[];
|
servers: OpenAPIServer[];
|
||||||
security: SecurityRequirementModel[];
|
security: SecurityRequirementModel[];
|
||||||
codeSamples: OpenAPIXCodeSample[];
|
codeSamples: OpenAPIXCodeSample[];
|
||||||
|
responseSamples: OpenAPIXResponseSample[];
|
||||||
extensions: Dict<any>;
|
extensions: Dict<any>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -89,6 +91,7 @@ export class OperationModel implements IMenuItem {
|
||||||
this.deprecated = !!operationSpec.deprecated;
|
this.deprecated = !!operationSpec.deprecated;
|
||||||
this.operationId = operationSpec.operationId;
|
this.operationId = operationSpec.operationId;
|
||||||
this.codeSamples = operationSpec['x-code-samples'] || [];
|
this.codeSamples = operationSpec['x-code-samples'] || [];
|
||||||
|
this.responseSamples = operationSpec['x-response-samples'] || [];
|
||||||
this.path = operationSpec.pathName;
|
this.path = operationSpec.pathName;
|
||||||
|
|
||||||
const pathInfo = parser.byRef<OpenAPIPath>(
|
const pathInfo = parser.byRef<OpenAPIPath>(
|
||||||
|
|
7
src/types/open-api.d.ts
vendored
7
src/types/open-api.d.ts
vendored
|
@ -63,6 +63,12 @@ export interface OpenAPIXCodeSample {
|
||||||
source: string;
|
source: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface OpenAPIXResponseSample {
|
||||||
|
lang: string;
|
||||||
|
label?: string;
|
||||||
|
source: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface OpenAPIOperation {
|
export interface OpenAPIOperation {
|
||||||
tags?: string[];
|
tags?: string[];
|
||||||
summary?: string;
|
summary?: string;
|
||||||
|
@ -77,6 +83,7 @@ export interface OpenAPIOperation {
|
||||||
security?: OpenAPISecurityRequirement[];
|
security?: OpenAPISecurityRequirement[];
|
||||||
servers?: OpenAPIServer[];
|
servers?: OpenAPIServer[];
|
||||||
'x-code-samples'?: OpenAPIXCodeSample[];
|
'x-code-samples'?: OpenAPIXCodeSample[];
|
||||||
|
'x-response-samples'?: OpenAPIXResponseSample[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OpenAPIParameter {
|
export interface OpenAPIParameter {
|
||||||
|
|
|
@ -291,6 +291,7 @@ export function isRedocExtension(key: string): boolean {
|
||||||
const redocExtensions = {
|
const redocExtensions = {
|
||||||
'x-circular-ref': true,
|
'x-circular-ref': true,
|
||||||
'x-code-samples': true,
|
'x-code-samples': true,
|
||||||
|
'x-response-samples': true,
|
||||||
'x-displayName': true,
|
'x-displayName': true,
|
||||||
'x-examples': true,
|
'x-examples': true,
|
||||||
'x-ignoredHeaderParameters': true,
|
'x-ignoredHeaderParameters': true,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user