diff --git a/packages/platform-fastify/adapters/fastify-adapter.ts b/packages/platform-fastify/adapters/fastify-adapter.ts index 37263991772..fb9ef41a30f 100644 --- a/packages/platform-fastify/adapters/fastify-adapter.ts +++ b/packages/platform-fastify/adapters/fastify-adapter.ts @@ -53,6 +53,7 @@ import { parse as querystringParse } from 'fast-querystring'; import { FASTIFY_ROUTE_CONFIG_METADATA, FASTIFY_ROUTE_CONSTRAINTS_METADATA, + FASTIFY_ROUTE_SCHEMA_METADATA, } from '../constants'; import { NestFastifyBodyParserOptions } from '../interfaces'; import { @@ -752,9 +753,14 @@ export class FastifyAdapter< handlerRef, ); + const routeSchema = Reflect.getMetadata( + FASTIFY_ROUTE_SCHEMA_METADATA, + handlerRef, + ); + const hasConfig = !isUndefined(routeConfig); const hasConstraints = !isUndefined(routeConstraints); - + const hasSchema = !isUndefined(routeSchema); const routeToInject: RouteOptions & RouteShorthandOptions = { method: routerMethodKey, @@ -766,7 +772,7 @@ export class FastifyAdapter< this.instance.addHttpMethod(routerMethodKey, { hasBody: true }); } - if (isVersioned || hasConstraints || hasConfig) { + if (isVersioned || hasConstraints || hasConfig || hasSchema) { const isPathAndRouteTuple = args.length === 2; if (isPathAndRouteTuple) { const constraints = { @@ -783,6 +789,9 @@ export class FastifyAdapter< ...routeConfig, }, }), + ...(hasSchema && { + schema: routeSchema, + }), }; const routeToInjectWithOptions = { ...routeToInject, ...options }; diff --git a/packages/platform-fastify/constants.ts b/packages/platform-fastify/constants.ts index 2f00d8077f5..616f83bc942 100644 --- a/packages/platform-fastify/constants.ts +++ b/packages/platform-fastify/constants.ts @@ -1,3 +1,4 @@ export const FASTIFY_ROUTE_CONFIG_METADATA = '__fastify_route_config__'; export const FASTIFY_ROUTE_CONSTRAINTS_METADATA = '__fastify_route_constraints__'; +export const FASTIFY_ROUTE_SCHEMA_METADATA = '__fastify_route_schema__'; diff --git a/packages/platform-fastify/decorators/index.ts b/packages/platform-fastify/decorators/index.ts index 67cc9d3d817..fce3ca1f746 100644 --- a/packages/platform-fastify/decorators/index.ts +++ b/packages/platform-fastify/decorators/index.ts @@ -1,2 +1,3 @@ export * from './route-config.decorator'; export * from './route-constraints.decorator'; +export * from './route-schema.decorator'; diff --git a/packages/platform-fastify/decorators/route-schema.decorator.ts b/packages/platform-fastify/decorators/route-schema.decorator.ts new file mode 100644 index 00000000000..de22c46caf4 --- /dev/null +++ b/packages/platform-fastify/decorators/route-schema.decorator.ts @@ -0,0 +1,15 @@ +import { SetMetadata } from '@nestjs/common'; +import { FASTIFY_ROUTE_SCHEMA_METADATA } from '../constants'; +import { FastifySchema } from 'fastify'; + +/** + * @publicApi + * Allows setting the schema for the route. Schema is an object that can contain the following properties: + * - body: JsonSchema + * - querystring or query: JsonSchema + * - params: JsonSchema + * - response: Record + * @param schema See {@link https://fastify.dev/docs/latest/Reference/Routes/#routes-options} + */ +export const RouteSchema = (schema: FastifySchema) => + SetMetadata(FASTIFY_ROUTE_SCHEMA_METADATA, schema); diff --git a/packages/platform-fastify/test/decorators/router-schema.decorator.spec.ts b/packages/platform-fastify/test/decorators/router-schema.decorator.spec.ts new file mode 100644 index 00000000000..22ff3471cb6 --- /dev/null +++ b/packages/platform-fastify/test/decorators/router-schema.decorator.spec.ts @@ -0,0 +1,17 @@ +import { expect } from 'chai'; +import { FASTIFY_ROUTE_SCHEMA_METADATA } from '../../constants'; +import { RouteSchema } from '../../decorators/route-schema.decorator'; + +describe('@RouteSchema', () => { + const routeSchema = { body: 'testValue' }; + class Test { + config; + @RouteSchema(routeSchema) + public static test() {} + } + + it('should enhance method with expected fastify route schema', () => { + const path = Reflect.getMetadata(FASTIFY_ROUTE_SCHEMA_METADATA, Test.test); + expect(path).to.be.eql(routeSchema); + }); +});