Skip to content

Commit

Permalink
feat: response headers and empty body (#346)
Browse files Browse the repository at this point in the history
* feat: response headers and empty body

* docs: response headers

* docs: status code 204
  • Loading branch information
climba03003 committed Feb 3, 2021
1 parent 3c2a38e commit 284c024
Show file tree
Hide file tree
Showing 5 changed files with 231 additions and 12 deletions.
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,37 @@ Example:
}
```

##### response headers
You can decorate your own response headers by follow the below example.
```js
{
response: {
200: {
type: 'object',
headers: {
'X-Foo': {
type: 'string'
}
}
}
}
}
```
Note: You need to specify `type` property when you decorate the response headers, otherwise the schema will be modify by `fastify`.

##### status code 204
We support status code 204 and return empty body. Please specify `type: 'null'` for the response otherwise `fastify` itself will fail to compile the schema.
```js
{
response: {
204: {
type: 'null',
description: 'No Content'
}
}
}
```

##### static
`static` mode should be configured explicitly. In this mode `fastify-swagger` serves given specification, you should craft it yourself.
```js
Expand Down
45 changes: 35 additions & 10 deletions lib/spec/openapi/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,22 +172,47 @@ function resolveResponse (fastifyResponseJson, produces, ref) {
// 2xx require to be all upper-case
statusCode = statusCode.toUpperCase()

const content = {}
const response = {
description: rawJsonSchema.description || 'Default Response'
}

// add headers when there are any.
if (rawJsonSchema.headers) {
response.headers = {}
Object.keys(rawJsonSchema.headers).forEach(function (key) {
const header = {
schema: rawJsonSchema.headers[key]
}

if (rawJsonSchema.headers[key].description) {
header.description = rawJsonSchema.headers[key].description
// remove invalid field
delete header.schema.description
}

if ((Array.isArray(produces) && produces.length === 0) || typeof produces === 'undefined') {
produces = ['application/json']
response.headers[key] = header
})
// remove invalid field
delete resolved.headers
}

produces.forEach((produce) => {
content[produce] = {
schema: resolved
if (statusCode.toString() !== '204') {
const content = {}

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

responsesContainer[statusCode] = {
content,
description: rawJsonSchema.description || 'Default Response'
produces.forEach((produce) => {
content[produce] = {
schema: resolved
}
})

response.content = content
}

responsesContainer[statusCode] = response
})

return responsesContainer
Expand Down
17 changes: 15 additions & 2 deletions lib/spec/swagger/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,23 @@ function resolveResponse (fastifyResponseJson, ref) {
}
statusCode = deXXStatusCode

responsesContainer[statusCode] = {
schema: resolved,
const response = {
description: rawJsonSchema.description || 'Default Response'
}

// add headers when there are any.
if (rawJsonSchema.headers) {
response.headers = rawJsonSchema.headers
// remove invalid field
delete resolved.headers
}

// add schema when status code is not 204
if (statusCode.toString() !== '204') {
response.schema = resolved
}

responsesContainer[statusCode] = response
})

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

test('support status code 204', async t => {
const opt = {
schema: {
response: {
204: {
type: 'null',
description: 'No Content'
}
}
}
}

const fastify = Fastify()
fastify.register(fastifySwagger, {
openapi: true,
routePrefix: '/docs',
exposeRoute: true
})
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['204'].description, 'No Content')
t.notOk(definedPath.responses['204'].content)
})

test('support response headers', async t => {
const opt = {
schema: {
response: {
200: {
type: 'object',
properties: {
hello: {
type: 'string'
}
},
headers: {
'X-WORLD': {
type: 'string'
},
'X-DESCRIPTION': {
description: 'Foo',
type: 'string'
}
}
}
}
}
}

const fastify = Fastify()
fastify.register(fastifySwagger, {
openapi: true,
routePrefix: '/docs',
exposeRoute: true
})
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'].headers['X-WORLD'], {
schema: {
type: 'string'
}
})
t.same(definedPath.responses['200'].headers['X-DESCRIPTION'], {
description: 'Foo',
schema: {
type: 'string'
}
})
t.notOk(definedPath.responses['200'].content['application/json'].schema.headers)
})
67 changes: 67 additions & 0 deletions test/spec/swagger/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,70 @@ test('response conflict 2xx and 200', async t => {
t.same(definedPath.responses['200'].description, '200')
t.notOk(definedPath.responses['2XX'])
})

test('support status code 204', async t => {
const opt = {
schema: {
response: {
204: {
type: 'null',
description: 'No Content'
}
}
}
}

const fastify = Fastify()
fastify.register(fastifySwagger, {
routePrefix: '/docs',
exposeRoute: true
})
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['204'].description, 'No Content')
t.notOk(definedPath.responses['204'].schema)
})

test('support response headers', async t => {
const opt = {
schema: {
response: {
200: {
type: 'object',
properties: {
hello: {
type: 'string'
}
},
headers: {
'X-WORLD': {
type: 'string'
}
}
}
}
}
}

const fastify = Fastify()
fastify.register(fastifySwagger, {
routePrefix: '/docs',
exposeRoute: true
})
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'].headers, opt.schema.response['200'].headers)
t.notOk(definedPath.responses['200'].schema.headers)
})

0 comments on commit 284c024

Please sign in to comment.