0
# Schema Definition Decorators
1
2
Comprehensive decorator system for defining GraphQL schemas using TypeScript classes. This decorator-based approach enables code-first GraphQL schema development where TypeScript classes and decorators automatically generate the GraphQL schema definition.
3
4
## Capabilities
5
6
### Class Decorators
7
8
Decorators for marking TypeScript classes as GraphQL types, resolvers, and schema elements.
9
10
```typescript { .api }
11
/**
12
* Marks a TypeScript class as a GraphQL Object Type
13
* @param name - Optional GraphQL type name (defaults to class name)
14
* @param options - Configuration options for the object type
15
*/
16
function ObjectType(name?: string, options?: ObjectTypeOptions): ClassDecorator;
17
18
/**
19
* Marks a TypeScript class as a GraphQL Input Type for mutations and field arguments
20
* @param name - Optional GraphQL input type name (defaults to class name)
21
* @param options - Configuration options for the input type
22
*/
23
function InputType(name?: string, options?: InputTypeOptions): ClassDecorator;
24
25
/**
26
* Marks a TypeScript class as a GraphQL Interface Type
27
* @param name - Optional GraphQL interface name (defaults to class name)
28
* @param options - Configuration options for the interface type
29
*/
30
function InterfaceType(name?: string, options?: InterfaceTypeOptions): ClassDecorator;
31
32
/**
33
* Marks a TypeScript class as a GraphQL Resolver for queries, mutations, and subscriptions
34
* @param typeOrName - Optional type function, string name, or class reference this resolver handles
35
* @param options - Configuration options for the resolver
36
*/
37
function Resolver<T = any>(typeOrName?: string | Function | ReturnTypeFunc, options?: ResolverOptions): ClassDecorator;
38
39
/**
40
* Marks a TypeScript class as a GraphQL Arguments Type for grouping resolver arguments
41
* @param options - Configuration options for the arguments type
42
*/
43
function ArgsType(options?: ArgsTypeOptions): ClassDecorator;
44
45
/**
46
* Marks a TypeScript class as a custom GraphQL Scalar Type
47
* @param name - The GraphQL scalar name
48
* @param typeFunc - Optional function returning the scalar type
49
*/
50
function Scalar(name: string, typeFunc?: () => GraphQLScalarType): ClassDecorator;
51
```
52
53
**Usage Examples:**
54
55
```typescript
56
import { ObjectType, InputType, InterfaceType, Resolver, ArgsType, Field, ID } from "@nestjs/graphql";
57
58
// Object Type
59
@ObjectType()
60
class User {
61
@Field(() => ID)
62
id: string;
63
64
@Field()
65
name: string;
66
67
@Field({ nullable: true })
68
email?: string;
69
}
70
71
// Input Type
72
@InputType()
73
class CreateUserInput {
74
@Field()
75
name: string;
76
77
@Field()
78
email: string;
79
}
80
81
// Interface Type
82
@InterfaceType()
83
abstract class Node {
84
@Field(() => ID)
85
id: string;
86
}
87
88
// Arguments Type
89
@ArgsType()
90
class GetUsersArgs {
91
@Field({ nullable: true })
92
limit?: number;
93
94
@Field({ nullable: true })
95
offset?: number;
96
}
97
98
// Resolver
99
@Resolver(() => User)
100
class UserResolver {
101
// resolver methods here
102
}
103
104
// Custom Scalar
105
@Scalar('DateTime')
106
class DateTimeScalar {
107
// scalar implementation
108
}
109
```
110
111
### Method Decorators
112
113
Decorators for defining GraphQL operations and field resolvers on methods.
114
115
```typescript { .api }
116
/**
117
* Marks a method as a GraphQL Query operation
118
* @param nameOrTypeFunc - Optional query name or return type function
119
* @param options - Configuration options for the query
120
*/
121
function Query(nameOrTypeFunc?: string | ReturnTypeFunc, options?: QueryOptions): MethodDecorator;
122
123
/**
124
* Marks a method as a GraphQL Mutation operation
125
* @param nameOrTypeFunc - Optional mutation name or return type function
126
* @param options - Configuration options for the mutation
127
*/
128
function Mutation(nameOrTypeFunc?: string | ReturnTypeFunc, options?: MutationOptions): MethodDecorator;
129
130
/**
131
* Marks a method as a GraphQL Subscription operation
132
* @param nameOrTypeFunc - Optional subscription name or return type function
133
* @param options - Configuration options for the subscription
134
*/
135
function Subscription(nameOrTypeFunc?: string | ReturnTypeFunc, options?: SubscriptionOptions): MethodDecorator;
136
137
/**
138
* Marks a property or method as a GraphQL Field
139
* @param typeFunc - Function returning the GraphQL type for this field
140
* @param options - Configuration options for the field
141
*/
142
function Field(typeFunc?: ReturnTypeFunc, options?: FieldOptions): PropertyDecorator & MethodDecorator;
143
144
/**
145
* Marks a method as a GraphQL Field Resolver for computed fields
146
* @param nameOrTypeFunc - Optional field name or return type function
147
* @param options - Configuration options for the field resolver
148
*/
149
function ResolveField(nameOrTypeFunc?: string | ReturnTypeFunc, options?: ResolveFieldOptions): MethodDecorator;
150
151
/**
152
* Marks a method as a GraphQL Reference Resolver for Apollo Federation
153
*/
154
function ResolveReference(): MethodDecorator;
155
156
/**
157
* Legacy alias for ResolveField (deprecated)
158
* @param name - Optional field name
159
* @param options - Configuration options
160
*/
161
function ResolveProperty(name?: string, options?: FieldOptions): MethodDecorator;
162
```
163
164
**Usage Examples:**
165
166
```typescript
167
import { Resolver, Query, Mutation, Subscription, Field, ResolveField, Args } from "@nestjs/graphql";
168
169
@Resolver(() => User)
170
class UserResolver {
171
// Query operation
172
@Query(() => [User])
173
users(): User[] {
174
return [];
175
}
176
177
// Mutation operation
178
@Mutation(() => User)
179
createUser(@Args('input') input: CreateUserInput): User {
180
return new User();
181
}
182
183
// Subscription operation
184
@Subscription(() => User)
185
userAdded() {
186
return this.pubSub.asyncIterator('userAdded');
187
}
188
189
// Field resolver for computed fields
190
@ResolveField(() => String)
191
fullName(@Parent() user: User): string {
192
return `${user.firstName} ${user.lastName}`;
193
}
194
195
// Federation reference resolver
196
@ResolveReference()
197
resolveReference(reference: { __typename: string; id: string }): User {
198
return this.findUserById(reference.id);
199
}
200
}
201
```
202
203
### Parameter Decorators
204
205
Decorators for extracting data from GraphQL resolver context and arguments.
206
207
```typescript { .api }
208
/**
209
* Extracts GraphQL arguments from resolver parameters
210
* @param name - Optional argument name (extracts all args if not specified)
211
* @param options - Configuration options for argument validation
212
* @param pipes - Optional validation pipes
213
*/
214
function Args(name?: string, options?: ArgsOptions, ...pipes: (Type<PipeTransform> | PipeTransform)[]): ParameterDecorator;
215
216
/**
217
* Injects the parent/root object in field resolvers
218
* @param pipes - Optional validation pipes
219
*/
220
function Parent(...pipes: (Type<PipeTransform> | PipeTransform)[]): ParameterDecorator;
221
222
/**
223
* Alias for Parent decorator
224
*/
225
function Root(): ParameterDecorator;
226
227
/**
228
* Injects GraphQL context or specific context properties
229
* @param property - Optional property path to extract from context
230
* @param pipes - Optional validation pipes
231
*/
232
function Context(property?: string, ...pipes: (Type<PipeTransform> | PipeTransform)[]): ParameterDecorator;
233
234
/**
235
* Injects GraphQL resolve info object containing field selection and metadata
236
* @param pipes - Optional validation pipes
237
*/
238
function Info(...pipes: (Type<PipeTransform> | PipeTransform)[]): ParameterDecorator;
239
```
240
241
**Usage Examples:**
242
243
```typescript
244
import { Resolver, Query, Args, Parent, Context, Info } from "@nestjs/graphql";
245
import { GraphQLResolveInfo } from "graphql";
246
247
@Resolver(() => User)
248
class UserResolver {
249
// Extract specific argument
250
@Query(() => User)
251
user(@Args('id') id: string): User {
252
return this.findUserById(id);
253
}
254
255
// Extract all arguments
256
@Query(() => [User])
257
users(@Args() args: GetUsersArgs): User[] {
258
return this.findUsers(args);
259
}
260
261
// Use parent object in field resolver
262
@ResolveField(() => [Post])
263
posts(@Parent() user: User): Post[] {
264
return this.findPostsByUserId(user.id);
265
}
266
267
// Access GraphQL context
268
@Query(() => User)
269
me(@Context() context: { user: User }): User {
270
return context.user;
271
}
272
273
// Access specific context property
274
@Query(() => User)
275
currentUser(@Context('user') user: User): User {
276
return user;
277
}
278
279
// Access resolve info
280
@Query(() => [User])
281
users(@Info() info: GraphQLResolveInfo): User[] {
282
const fields = this.getSelectedFields(info);
283
return this.findUsersWithFields(fields);
284
}
285
}
286
```
287
288
### Property Decorators
289
290
Decorators for schema metadata and field configuration.
291
292
```typescript { .api }
293
/**
294
* Applies GraphQL directives to schema elements
295
* @param sdl - GraphQL directive definition language string
296
*/
297
function Directive(sdl: string): PropertyDecorator;
298
299
/**
300
* Adds extensions metadata to schema elements
301
* @param value - Extension data to attach
302
*/
303
function Extensions(value: Record<string, any>): PropertyDecorator;
304
305
/**
306
* Excludes fields from GraphQL schema generation
307
*/
308
function HideField(): PropertyDecorator;
309
```
310
311
**Usage Examples:**
312
313
```typescript
314
import { ObjectType, Field, Directive, Extensions, HideField } from "@nestjs/graphql";
315
316
@ObjectType()
317
class User {
318
@Field()
319
@Directive('@deprecated(reason: "Use fullName instead")')
320
name: string;
321
322
@Field()
323
@Extensions({ complexity: 10 })
324
fullName: string;
325
326
@HideField()
327
internalId: string; // This field won't appear in GraphQL schema
328
}
329
```
330
331
### Decorator Options Interfaces
332
333
Configuration interfaces for customizing decorator behavior.
334
335
```typescript { .api }
336
/**
337
* Options for ObjectType decorator
338
*/
339
interface ObjectTypeOptions {
340
/** Custom description for the GraphQL type */
341
description?: string;
342
/** Interfaces this type implements */
343
implements?: Function | Function[] | (() => Function | Function[]);
344
/** Whether this type is abstract */
345
isAbstract?: boolean;
346
/** Whether to inherit description from interfaces */
347
inheritDescription?: boolean;
348
}
349
350
/**
351
* Options for InputType decorator
352
*/
353
interface InputTypeOptions {
354
/** Custom description for the GraphQL input type */
355
description?: string;
356
/** Whether this input type is abstract */
357
isAbstract?: boolean;
358
}
359
360
/**
361
* Options for InterfaceType decorator
362
*/
363
interface InterfaceTypeOptions {
364
/** Custom description for the GraphQL interface type */
365
description?: string;
366
/** Whether this interface type is abstract */
367
isAbstract?: boolean;
368
/** Custom resolve type function */
369
resolveType?: (value: any) => string | undefined;
370
/** Interfaces this interface implements */
371
implements?: Function | Function[] | (() => Function | Function[]);
372
}
373
374
/**
375
* Options for Field decorator
376
*/
377
interface FieldOptions {
378
/** Custom description for the field */
379
description?: string;
380
/** Deprecation reason */
381
deprecationReason?: string;
382
/** Whether the field can be null */
383
nullable?: boolean | 'items' | 'itemsAndList';
384
/** Default value for the field */
385
defaultValue?: any;
386
/** Field complexity for query analysis */
387
complexity?: number;
388
/** Field-specific middleware */
389
middleware?: FieldMiddleware[];
390
}
391
392
/**
393
* Options for Query/Mutation/Subscription decorators
394
*/
395
interface QueryOptions {
396
/** Custom name for the operation */
397
name?: string;
398
/** Description for the operation */
399
description?: string;
400
/** Deprecation reason */
401
deprecationReason?: string;
402
/** Query complexity */
403
complexity?: number;
404
/** Whether return type can be null */
405
nullable?: boolean;
406
}
407
408
type MutationOptions = QueryOptions;
409
type SubscriptionOptions = QueryOptions;
410
411
/**
412
* Options for ArgsType decorator
413
*/
414
interface ArgsTypeOptions {
415
/** Custom description for the arguments type */
416
description?: string;
417
/** Whether this arguments type is abstract */
418
isAbstract?: boolean;
419
}
420
421
/**
422
* Options for Args decorator
423
*/
424
interface ArgsOptions {
425
/** Custom name for the argument */
426
name?: string;
427
/** Description for the argument */
428
description?: string;
429
/** Whether the argument can be null */
430
nullable?: boolean | 'items' | 'itemsAndList';
431
/** Default value for the argument */
432
defaultValue?: any;
433
/** Validation pipes for the argument */
434
pipes?: PipeTransform[];
435
/** Deprecation reason */
436
deprecationReason?: string;
437
}
438
439
/**
440
* Options for ResolveField decorator
441
*/
442
interface ResolveFieldOptions {
443
/** Custom name for the field */
444
name?: string;
445
/** Description for the field */
446
description?: string;
447
/** Deprecation reason */
448
deprecationReason?: string;
449
/** Whether the field can be null */
450
nullable?: boolean | 'items' | 'itemsAndList';
451
/** Default value for the field */
452
defaultValue?: any;
453
/** Field complexity for query analysis */
454
complexity?: number;
455
/** Field-specific middleware */
456
middleware?: FieldMiddleware[];
457
}
458
459
/**
460
* Options for Resolver decorator
461
*/
462
interface ResolverOptions {
463
/** Whether this resolver is abstract (won't generate GraphQL operations) */
464
isAbstract?: boolean;
465
}
466
```
467
468
### Supporting Types and Interfaces
469
470
Core types used throughout the decorator system.
471
472
```typescript { .api }
473
/**
474
* Interface for NestJS pipe transforms used in parameter decorators
475
*/
476
interface PipeTransform<T = any, R = any> {
477
transform(value: T, metadata: ArgumentMetadata): R;
478
}
479
480
/**
481
* Interface for field middleware functions
482
*/
483
interface FieldMiddleware<TSource = any, TContext = any, TArgs = any, TOutput = any> {
484
use(params: MiddlewareContext<TSource, TContext, TArgs>): Promise<TOutput> | TOutput;
485
}
486
487
/**
488
* Middleware context passed to field middleware
489
*/
490
interface MiddlewareContext<TSource = any, TContext = any, TArgs = any> {
491
source: TSource;
492
args: TArgs;
493
context: TContext;
494
info: GraphQLResolveInfo;
495
next: NextFn;
496
}
497
498
/**
499
* Next function type for middleware
500
*/
501
type NextFn<T = any> = () => Promise<T> | T;
502
503
/**
504
* Argument metadata for pipe transforms
505
*/
506
interface ArgumentMetadata {
507
type: 'body' | 'query' | 'param' | 'custom';
508
metatype?: Type<unknown> | undefined;
509
data?: string | undefined;
510
}
511
```
512
513
### Type Reference Functions
514
515
Helper types for defining GraphQL type references in decorators.
516
517
```typescript { .api }
518
/**
519
* Function type for defining return types in decorators
520
*/
521
type ReturnTypeFunc = (returns?: void) => Function | object | symbol;
522
523
/**
524
* Type reference for GraphQL schema elements
525
*/
526
type GqlTypeReference = Function | object | symbol | [Function | object | symbol];
527
528
/**
529
* Class type reference
530
*/
531
type Type<T = any> = new (...args: any[]) => T;
532
```
533
534
**Usage Examples:**
535
536
```typescript
537
import { Field, ObjectType } from "@nestjs/graphql";
538
539
@ObjectType()
540
class User {
541
// Simple field with inferred type
542
@Field()
543
name: string;
544
545
// Field with explicit type function
546
@Field(() => String)
547
email: string;
548
549
// Array field
550
@Field(() => [String])
551
tags: string[];
552
553
// Optional field
554
@Field({ nullable: true })
555
bio?: string;
556
557
// Field with custom options
558
@Field(() => String, {
559
description: 'User display name',
560
nullable: true,
561
defaultValue: 'Anonymous',
562
})
563
displayName?: string;
564
}
565
```