Skip to content

Commit

Permalink
Hide HEAD routes by default (#724)
Browse files Browse the repository at this point in the history
* Hide HEAD routes by default

Signed-off-by: Matteo Collina <hello@matteocollina.com>

* Update README.md

Co-authored-by: Frazer Smith <frazer.dev@outlook.com>

* move route exposeHeadRoute to config.swagger.exposeHeadRoute

Signed-off-by: Matteo Collina <hello@matteocollina.com>

---------

Signed-off-by: Matteo Collina <hello@matteocollina.com>
Co-authored-by: Frazer Smith <frazer.dev@outlook.com>
  • Loading branch information
mcollina and Fdawgs authored May 23, 2023
1 parent fc26e27 commit 4d068a8
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 26 deletions.
44 changes: 35 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,16 +209,17 @@ An example of using `@fastify/swagger` with `static` mode enabled can be found [

#### Options

| Option | Default | Description |
| ------------------ | ---------------- | ------------------------------------------------------------------------------------------------------------------------- |
| hiddenTag | X-HIDDEN | Tag to control hiding of routes. |
| hideUntagged | false | If `true` remove routes without tags from resulting Swagger/OpenAPI schema file. |
| initOAuth | {} | Configuration options for [Swagger UI initOAuth](https://swagger.io/docs/open-source-tools/swagger-ui/usage/oauth2/). |
| openapi | {} | [OpenAPI configuration](https://swagger.io/specification/#oasObject). |
| stripBasePath | true | Strips base path from routes in docs. |
| swagger | {} | [Swagger configuration](https://swagger.io/specification/v2/#swaggerObject). |
| transform | null | Transform method for the route's schema and url. [documentation](#register.options.transform). |
| Option | Default | Description |
| ------------------ | ---------------- | -------------------------------------------------------------------------------------------------------------------------- |
| hiddenTag | X-HIDDEN | Tag to control hiding of routes. |
| hideUntagged | false | If `true` remove routes without tags from resulting Swagger/OpenAPI schema file. |
| initOAuth | {} | Configuration options for [Swagger UI initOAuth](https://swagger.io/docs/open-source-tools/swagger-ui/usage/oauth2/). |
| openapi | {} | [OpenAPI configuration](https://swagger.io/specification/#oasObject). |
| stripBasePath | true | Strips base path from routes in docs. |
| swagger | {} | [Swagger configuration](https://swagger.io/specification/v2/#swaggerObject). |
| transform | null | Transform method for the route's schema and url. [documentation](#register.options.transform). | |
| refResolver | {} | Option to manage the `$ref`s of your application's schemas. Read the [`$ref` documentation](#register.options.refResolver) |
| exposeHeadRoutes | false | Include HEAD routes in the definitions |

<a name="register.options.transform"></a>
#### Transform
Expand Down Expand Up @@ -299,6 +300,31 @@ To deep down the `buildLocalReference` arguments, you may read the [documentatio
<a name="route.options"></a>
### Route options
It is possible to instruct `@fastify/swagger` to include specific `HEAD` routes in the definitions
by adding `exposeHeadRoute` in the route config, like so:
```js
fastify.get('/with-head', {
schema: {
operationId: 'with-head',
response: {
200: {
description: 'Expected Response',
type: 'object',
properties: {
foo: { type: 'string' }
}
}
}
},
config: {
swagger: {
exposeHeadRoute: true,
}
}
}, () => {})
```
<a name="route.response.options"></a>
#### Response Options
Expand Down
20 changes: 8 additions & 12 deletions lib/util/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,22 @@ function addHook (fastify, pluginOptions) {
const routes = []
const sharedSchemasMap = new Map()

const globalExposeHeadRoutes = fastify.initialConfig.exposeHeadRoutes

fastify.addHook('onRoute', (routeOptions) => {
// fastify will generate HEAD routes if either the global `exposeHeadRoutes`
// (default behavior since https://github.com/fastify/fastify/pull/2826) or
// `exposeHeadRoute` on route level flag is `true`. If two routes with
// operationId are added to the swagger object, it is no longer valid.
// therefore we suffix the operationId with `-head`.
const hasRouteExposeHeadRouteFlag = routeOptions.exposeHeadRoute != null
const exposesHeads = hasRouteExposeHeadRouteFlag
? routeOptions.exposeHeadRoute
: globalExposeHeadRoutes
const routeConfig = routeOptions.config || {}
const swaggerConfig = routeConfig.swagger || {}
if (routeOptions.method === 'HEAD' && pluginOptions.exposeHeadRoutes !== true && swaggerConfig.exposeHeadRoute !== true) {
return
}

if (
routeOptions.method === 'HEAD' &&
exposesHeads === true &&
routeOptions.schema !== undefined &&
routeOptions.schema.operationId !== undefined
) {
routes.push(
// If two routes with operationId are added to the swagger
// object, it is no longer valid.
// therefore we suffix the operationId with `-head`.
Object.assign({}, routeOptions, {
schema: Object.assign({}, routeOptions.schema, {
operationId: `${routeOptions.schema.operationId}-head`
Expand Down
52 changes: 47 additions & 5 deletions test/spec/swagger/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -482,15 +482,52 @@ test('support "const" keyword', async t => {
})
})

test('support "exposeHeadRoute" option', async (t) => {
const fastify = Fastify({ exposeHeadRoutes: false })
test('no head routes by default', async (t) => {
const fastify = Fastify({ exposeHeadRoutes: true })
await fastify.register(fastifySwagger, {
routePrefix: '/docs',
exposeRoute: true
})

fastify.get('/with-head', {
schema: {
operationId: 'with-head',
response: {
200: {
description: 'Expected Response',
type: 'object',
properties: {
foo: { type: 'string' }
}
}
}
}
}, () => {})

await fastify.ready()

const swaggerObject = fastify.swagger()
const api = await Swagger.validate(swaggerObject)

t.same(
api.paths['/with-head'].get.responses['200'].description,
'Expected Response'
)
t.same(
api.paths['/with-head'].head,
undefined
)
})

test('support "exposeHeadRoutes" option', async (t) => {
const fastify = Fastify()
await fastify.register(fastifySwagger, {
routePrefix: '/docs',
exposeHeadRoutes: true,
exposeRoute: true
})

fastify.get('/with-head', {
exposeHeadRoute: true,
schema: {
operationId: 'with-head',
response: {
Expand Down Expand Up @@ -520,8 +557,8 @@ test('support "exposeHeadRoute" option', async (t) => {
)
})

test('support "exposeHeadRoutes" option', async (t) => {
const fastify = Fastify({ exposeHeadRoutes: true })
test('support "exposeHeadRoutes" option at route level', async (t) => {
const fastify = Fastify()
await fastify.register(fastifySwagger, {
routePrefix: '/docs',
exposeRoute: true
Expand All @@ -539,6 +576,11 @@ test('support "exposeHeadRoutes" option', async (t) => {
}
}
}
},
config: {
swagger: {
exposeHeadRoute: true
}
}
}, () => {})

Expand Down

0 comments on commit 4d068a8

Please sign in to comment.