or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

decorators.mdfastify-adapter.mdindex.mdinterfaces.md

decorators.mddocs/

0

# Route Decorators

1

2

Specialized decorators for configuring Fastify-specific route behavior including constraints, schema validation, and configuration options.

3

4

## Capabilities

5

6

### RouteConfig Decorator

7

8

Sets Fastify route configuration metadata for enhanced route behavior and options.

9

10

```typescript { .api }

11

/**

12

* Decorator for setting Fastify route configuration

13

* Applies configuration options that will be passed to Fastify's route registration

14

* @param config - Route configuration object

15

*

16

* @see https://fastify.dev/docs/latest/Reference/Routes/#config

17

*/

18

function RouteConfig(config: any): MethodDecorator;

19

```

20

21

**Usage Examples:**

22

23

```typescript

24

import { Controller, Get } from '@nestjs/common';

25

import { RouteConfig } from '@nestjs/platform-fastify';

26

27

@Controller('users')

28

export class UsersController {

29

@Get(':id')

30

@RouteConfig({

31

// Custom route-specific configuration

32

rateLimit: {

33

max: 100,

34

timeWindow: '1 minute'

35

},

36

// Can include any Fastify route config

37

custom: {

38

authRequired: true,

39

roles: ['admin', 'user']

40

}

41

})

42

getUser(@Param('id') id: string) {

43

// Route handler implementation

44

return { id, name: 'John Doe' };

45

}

46

47

@Post()

48

@RouteConfig({

49

bodyLimit: 1024 * 1024, // 1MB limit for this route

50

preHandler: async (request, reply) => {

51

// Custom pre-handler logic

52

}

53

})

54

createUser(@Body() userData: any) {

55

// Route handler implementation

56

return userData;

57

}

58

}

59

```

60

61

### RouteConstraints Decorator

62

63

Sets Fastify route constraints for advanced routing based on request properties.

64

65

```typescript { .api }

66

/**

67

* Decorator for setting Fastify route constraints

68

* Enables advanced routing based on request properties like headers, host, etc.

69

* @param config - Route constraints configuration

70

*

71

* @see https://fastify.dev/docs/latest/Reference/Routes/#constraints

72

*/

73

function RouteConstraints(config: RouteShorthandOptions['config']): MethodDecorator;

74

```

75

76

**Usage Examples:**

77

78

```typescript

79

import { Controller, Get } from '@nestjs/common';

80

import { RouteConstraints } from '@nestjs/platform-fastify';

81

82

@Controller('api')

83

export class ApiController {

84

@Get('data')

85

@RouteConstraints({

86

// Route only matches for specific host

87

host: 'api.example.com'

88

})

89

getDataForApiDomain() {

90

return { message: 'API domain data' };

91

}

92

93

@Get('data')

94

@RouteConstraints({

95

// Route matches for different host

96

host: 'admin.example.com'

97

})

98

getDataForAdminDomain() {

99

return { message: 'Admin domain data' };

100

}

101

102

@Get('mobile-data')

103

@RouteConstraints({

104

// Route only matches for mobile user agents

105

headers: {

106

'user-agent': /Mobile|Android|iPhone/i

107

}

108

})

109

getMobileData() {

110

return { message: 'Mobile optimized data' };

111

}

112

113

@Get('version/:id')

114

@RouteConstraints({

115

// Route constraint based on custom logic

116

version: '2.0'

117

})

118

getVersionedData(@Param('id') id: string) {

119

return { id, version: '2.0', data: 'new format' };

120

}

121

}

122

```

123

124

### RouteSchema Decorator

125

126

Sets Fastify route schema for automatic request/response validation using JSON Schema.

127

128

```typescript { .api }

129

/**

130

* Decorator for setting Fastify route schema validation

131

* Enables automatic validation of request body, query parameters, route parameters, and response

132

* @param schema - JSON Schema definition for route validation

133

*

134

* @see https://fastify.dev/docs/latest/Reference/Routes/#routes-options

135

*/

136

function RouteSchema(schema: FastifySchema): MethodDecorator;

137

138

interface FastifySchema {

139

/** JSON Schema for request body validation */

140

body?: JsonSchema;

141

/** JSON Schema for query string validation */

142

querystring?: JsonSchema;

143

/** JSON Schema for query string validation (alias) */

144

query?: JsonSchema;

145

/** JSON Schema for route parameters validation */

146

params?: JsonSchema;

147

/** JSON Schema for response validation by status code */

148

response?: Record<number, JsonSchema>;

149

/** JSON Schema for request headers validation */

150

headers?: JsonSchema;

151

}

152

153

interface JsonSchema {

154

type?: string | string[];

155

properties?: Record<string, JsonSchema>;

156

required?: string[];

157

additionalProperties?: boolean;

158

items?: JsonSchema;

159

minimum?: number;

160

maximum?: number;

161

minLength?: number;

162

maxLength?: number;

163

pattern?: string;

164

enum?: any[];

165

format?: string;

166

[key: string]: any;

167

}

168

```

169

170

**Usage Examples:**

171

172

```typescript

173

import { Controller, Get, Post, Body, Param, Query } from '@nestjs/common';

174

import { RouteSchema } from '@nestjs/platform-fastify';

175

176

@Controller('products')

177

export class ProductsController {

178

@Get(':id')

179

@RouteSchema({

180

// Validate route parameters

181

params: {

182

type: 'object',

183

required: ['id'],

184

properties: {

185

id: {

186

type: 'string',

187

pattern: '^[0-9]+$' // Only numeric IDs

188

}

189

}

190

},

191

// Validate response format

192

response: {

193

200: {

194

type: 'object',

195

required: ['id', 'name', 'price'],

196

properties: {

197

id: { type: 'string' },

198

name: { type: 'string' },

199

price: { type: 'number', minimum: 0 },

200

description: { type: 'string' },

201

category: { type: 'string' }

202

}

203

},

204

404: {

205

type: 'object',

206

required: ['error', 'message'],

207

properties: {

208

error: { type: 'string' },

209

message: { type: 'string' }

210

}

211

}

212

}

213

})

214

getProduct(@Param('id') id: string) {

215

return {

216

id,

217

name: 'Product Name',

218

price: 29.99,

219

description: 'Product description',

220

category: 'electronics'

221

};

222

}

223

224

@Get()

225

@RouteSchema({

226

// Validate query parameters

227

querystring: {

228

type: 'object',

229

properties: {

230

page: {

231

type: 'integer',

232

minimum: 1,

233

default: 1

234

},

235

limit: {

236

type: 'integer',

237

minimum: 1,

238

maximum: 100,

239

default: 10

240

},

241

category: {

242

type: 'string',

243

enum: ['electronics', 'clothing', 'books', 'home']

244

},

245

minPrice: {

246

type: 'number',

247

minimum: 0

248

},

249

maxPrice: {

250

type: 'number',

251

minimum: 0

252

}

253

}

254

},

255

// Validate response

256

response: {

257

200: {

258

type: 'object',

259

required: ['products', 'total', 'page'],

260

properties: {

261

products: {

262

type: 'array',

263

items: {

264

type: 'object',

265

required: ['id', 'name', 'price'],

266

properties: {

267

id: { type: 'string' },

268

name: { type: 'string' },

269

price: { type: 'number' }

270

}

271

}

272

},

273

total: { type: 'integer' },

274

page: { type: 'integer' },

275

totalPages: { type: 'integer' }

276

}

277

}

278

}

279

})

280

getProducts(

281

@Query('page') page = 1,

282

@Query('limit') limit = 10,

283

@Query('category') category?: string,

284

@Query('minPrice') minPrice?: number,

285

@Query('maxPrice') maxPrice?: number

286

) {

287

return {

288

products: [],

289

total: 0,

290

page,

291

totalPages: 0

292

};

293

}

294

295

@Post()

296

@RouteSchema({

297

// Validate request body

298

body: {

299

type: 'object',

300

required: ['name', 'price', 'category'],

301

additionalProperties: false,

302

properties: {

303

name: {

304

type: 'string',

305

minLength: 1,

306

maxLength: 100

307

},

308

price: {

309

type: 'number',

310

minimum: 0,

311

maximum: 10000

312

},

313

category: {

314

type: 'string',

315

enum: ['electronics', 'clothing', 'books', 'home']

316

},

317

description: {

318

type: 'string',

319

maxLength: 1000

320

},

321

tags: {

322

type: 'array',

323

items: {

324

type: 'string',

325

minLength: 1

326

},

327

maxItems: 10

328

}

329

}

330

},

331

// Validate request headers

332

headers: {

333

type: 'object',

334

required: ['content-type'],

335

properties: {

336

'content-type': {

337

type: 'string',

338

enum: ['application/json']

339

}

340

}

341

},

342

// Validate response

343

response: {

344

201: {

345

type: 'object',

346

required: ['id', 'name', 'price', 'category', 'createdAt'],

347

properties: {

348

id: { type: 'string' },

349

name: { type: 'string' },

350

price: { type: 'number' },

351

category: { type: 'string' },

352

description: { type: 'string' },

353

tags: {

354

type: 'array',

355

items: { type: 'string' }

356

},

357

createdAt: { type: 'string', format: 'date-time' }

358

}

359

},

360

400: {

361

type: 'object',

362

required: ['error', 'message'],

363

properties: {

364

error: { type: 'string' },

365

message: { type: 'string' },

366

details: {

367

type: 'array',

368

items: {

369

type: 'object',

370

properties: {

371

field: { type: 'string' },

372

message: { type: 'string' }

373

}

374

}

375

}

376

}

377

}

378

}

379

})

380

createProduct(@Body() productData: any) {

381

return {

382

id: 'new-product-id',

383

...productData,

384

createdAt: new Date().toISOString()

385

};

386

}

387

}

388

```

389

390

## Metadata Constants

391

392

Constants used internally by the decorators for storing metadata.

393

394

```typescript { .api }

395

/** Metadata key for route configuration */

396

const FASTIFY_ROUTE_CONFIG_METADATA: string;

397

398

/** Metadata key for route constraints */

399

const FASTIFY_ROUTE_CONSTRAINTS_METADATA: string;

400

401

/** Metadata key for route schema */

402

const FASTIFY_ROUTE_SCHEMA_METADATA: string;

403

```

404

405

These constants are used internally by the decorators and the FastifyAdapter to retrieve and apply the metadata to routes. They are exported for advanced use cases where manual metadata manipulation might be needed.

406

407

## Integration with NestJS

408

409

The decorators work seamlessly with standard NestJS decorators and can be combined for comprehensive route configuration:

410

411

```typescript

412

import { Controller, Get, Post, UseGuards, UseInterceptors } from '@nestjs/common';

413

import { RouteConfig, RouteConstraints, RouteSchema } from '@nestjs/platform-fastify';

414

import { AuthGuard } from './auth.guard';

415

import { LoggingInterceptor } from './logging.interceptor';

416

417

@Controller('secure')

418

@UseGuards(AuthGuard)

419

@UseInterceptors(LoggingInterceptor)

420

export class SecureController {

421

@Get('data')

422

@RouteConfig({

423

rateLimit: { max: 10, timeWindow: '1 minute' }

424

})

425

@RouteConstraints({

426

headers: { 'x-api-key': /^[a-f0-9]{32}$/ }

427

})

428

@RouteSchema({

429

headers: {

430

type: 'object',

431

required: ['x-api-key'],

432

properties: {

433

'x-api-key': { type: 'string', pattern: '^[a-f0-9]{32}$' }

434

}

435

},

436

response: {

437

200: {

438

type: 'object',

439

properties: {

440

data: { type: 'array' },

441

timestamp: { type: 'string' }

442

}

443

}

444

}

445

})

446

getSecureData() {

447

return {

448

data: ['sensitive', 'information'],

449

timestamp: new Date().toISOString()

450

};

451

}

452

}

453

```