Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: rendering the syntax of different content types responses #665

Merged
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,32 @@ You can decorate your own response headers by following the below example:
Note: You need to specify `type` property when you decorate the response headers, otherwise the schema will be modified by Fastify.

<a name="route.response.empty_body"></a>
##### Different content types responses
**Note:** not supported by Swagger (OpenAPI v2), [only OpenAPI v3](https://swagger.io/docs/specification/describing-responses/)
<br>
iifawzi marked this conversation as resolved.
Show resolved Hide resolved
<br>
iifawzi marked this conversation as resolved.
Show resolved Hide resolved
Different content types responses are supported by `@fastify/swagger` and `@fastify`.
Please use `contentTypes` for the response otherwise Fastify itself will fail to compile the schema:

```js
{
response: {
200: {
description: 'Description and all status-code based properties are working',
contentTypes: [
{
content: 'application/json',
schema: { name: { type: 'string' }, image: { type: 'string' }, address: { type: 'string' } }
},
{
content: 'application/vnd.v1+json',
schema: { fullName: { type: 'string' }, phone: { type: 'string' } }
}
]
}
}
}
```
##### Empty Body Responses
Empty body responses are supported by `@fastify/swagger`.
Please specify `type: 'null'` for the response otherwise Fastify itself will fail to compile the schema:
Expand Down
30 changes: 19 additions & 11 deletions lib/spec/openapi/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,20 +323,28 @@ function resolveResponse (fastifyResponseJson, produces, ref) {

// add schema when type is not 'null'
if (rawJsonSchema.type !== 'null') {
const content = {}

if ((Array.isArray(produces) && produces.length === 0) || typeof produces === 'undefined') {
produces = ['application/json']
}
if (Array.isArray(resolved.contentTypes)) {
const content = {}
for (const contnetTypeResponse of resolved.contentTypes) {
const media = schemaToMedia(contnetTypeResponse.schema)
content[contnetTypeResponse.content] = media
response.content = content
}
iifawzi marked this conversation as resolved.
Show resolved Hide resolved
} else {
const content = {}

delete resolved[xResponseDescription]
if ((Array.isArray(produces) && produces.length === 0) || typeof produces === 'undefined') {
produces = ['application/json']
}

const media = schemaToMedia(resolved)
produces.forEach((produce) => {
content[produce] = media
})
delete resolved[xResponseDescription]

response.content = content
const media = schemaToMedia(resolved)
produces.forEach((produce) => {
iifawzi marked this conversation as resolved.
Show resolved Hide resolved
content[produce] = media
})
response.content = content
}
}

responsesContainer[statusCode] = response
Expand Down
55 changes: 55 additions & 0 deletions test/spec/openapi/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,61 @@ test('support 2xx response', async t => {
t.same(definedPath.responses['3XX'].description, 'Default Response')
})

test('support multiple content types responses', async t => {
iifawzi marked this conversation as resolved.
Show resolved Hide resolved
const fastify = Fastify()
await fastify.register(fastifySwagger, {
openapi: true,
routePrefix: '/docs',
exposeRoute: true
})

const opt = {
schema: {
response: {
200: {
iifawzi marked this conversation as resolved.
Show resolved Hide resolved
description: 'Description and all status-code based properties are working',
contentTypes: [
{
content: 'application/json',
schema: { name: { type: 'string' }, image: { type: 'string' }, address: { type: 'string' } }
},
{
content: 'application/vnd.v1+json',
schema: { fullName: { type: 'string' }, phone: { type: 'string' } }
}
]
}
}
}
}
fastify.get('/', opt, () => {})

await fastify.ready()

const swaggerObject = fastify.swagger()
const api = await Swagger.validate(swaggerObject)
const definedPath = api.paths['/'].get
t.same(definedPath.responses['200'].description, 'Description and all status-code based properties are working')
t.same(definedPath.responses['200'].content, {
iifawzi marked this conversation as resolved.
Show resolved Hide resolved
'application/json': {
schema: {
type: 'object',
properties: {
name: { type: 'string' }, image: { type: 'string' }, address: { type: 'string' }
}
}
},
'application/vnd.v1+json': {
schema: {
type: 'object',
properties: {
fullName: { type: 'string' }, phone: { type: 'string' }
}
}
}
})
})

test('support status code 204', async t => {
const opt = {
schema: {
Expand Down