GraphQL Code-First Basics
GraphQL Code-First Basics
NestJS supports two approaches to building a GraphQL API: schema-first (you write SDL and generate types) and code-first (you write TypeScript decorators and the schema is auto-generated). The code-first approach keeps a single source of truth — your TypeScript classes — and eliminates the synchronisation headache between SDL files and TypeScript types. This lesson covers the essential building blocks: object types, resolvers, queries, mutations, and input types.
Installation and module setup
Register GraphQLModule in your root AppModule with the autoSchemaFile option pointing to the path where NestJS should write the generated SDL file (or pass true to keep it in memory only):
Defining an Object Type with @ObjectType and @Field
Any class decorated with @ObjectType() becomes a GraphQL type. Each property you want exposed in the schema must be annotated with @Field(). TypeScript's type inference handles scalars automatically for primitives, but you must be explicit for nullable fields and arrays:
@Field(() => Int) instead of relying on reflection for numbers — TypeScript's number maps to both Int and Float, so you must be explicit to avoid ambiguity.
Creating a Resolver with @Query and @Mutation
A class decorated with @Resolver() (or @Resolver(() => Post) to scope it) exposes query and mutation handlers. @Query() declares a read operation; @Mutation() declares a write operation. Arguments are injected with @Args():
Input Types with @InputType
Mutations receive structured data through input types. Decorate a class with @InputType() and its fields with @Field() — NestJS generates a GraphQL input block in the schema. Input types integrate seamlessly with class-validator decorators:
ValidationPipe globally (or on the GraphQL context) so class-validator decorators on @InputType classes are automatically enforced before your resolver runs.
Auto Schema Generation
Once the module is configured, NestJS reflects over all registered resolvers and object/input types at startup and writes the schema.gql file. Running the application produces something like:
Summary
The code-first GraphQL approach in NestJS keeps TypeScript as the single source of truth. Decorate model classes with @ObjectType/@Field, write resolver classes with @Query/@Mutation/@Args, and define input shapes with @InputType/@Field. GraphQLModule.forRoot with autoSchemaFile generates and maintains the SDL automatically, so you never write or sync raw GraphQL schema files by hand.