CodePark/ questions / GraphQL & WebSockets
START PRACTICINGPRACTICE
Backend question · NestJS › GraphQL & WebSockets

Compare the code-first and schema-first approaches in @nestjs/graphql, and show a simple code-first resolver.

@ObjectType()
export class Author {
  @Field(() => Int) id: number;
  @Field() name: string;
}

@Resolver(() => Author)
export class AuthorsResolver {
  constructor(private authors: AuthorsService) {}

  @Query(() => Author, { nullable: true })
  author(@Args("id", { type: () => Int }) id: number) {
    return this.authors.findOne(id);
  }
}

In code-first, you write TypeScript classes and Nest generates the schema. In schema-first, you write the schema and Nest can generate TypeScript types from it.

Code-first. You write classes with decorators like @ObjectType(), @Field(), @InputType() and @Resolver(). Nest generates the SDL schema from them. SDL is GraphQL's schema language. You turn it on with the autoSchemaFile option on GraphQLModule.forRoot(). Pros: types and schema can't get out of sync, and you stay in TypeScript.

Schema-first. You write .graphql SDL files and point typePaths at them. Nest can generate TypeScript definitions from the SDL. It suits teams that design the schema first as a contract, or share it with other services.

In both approaches, resolvers are providers.

  • @Query(), @Mutation() and @ResolveField() map operations to methods.
  • @Args() reads arguments.
  • You set a driver, such as Apollo or Mercurius, in forRoot.
  • In code-first, decorators generate the schema, using autoSchemaFile.
  • In schema-first, you write SDL files and point typePaths at them.
  • Resolvers are providers that use @Query, @Mutation and @ResolveField.
  • @Args() reads the arguments.
  • You set the driver, Apollo or Mercurius, in forRoot.