31.8.2022 |

Simple NestJS GraphQL API

introduction

I've had the challenge to create an GrapQL API using Spring Boot and https://github.com/graphql-java-kickstart/graphql-spring-boot in 2019 which was quit complex and tricky by the time. Therefore i wanted to try to create a simple GraphQL API using NestJS which looked a lot more mature and easy.

I was able to create the following API in about 3 hours https://github.com/sijakubo/nestjs-graphql and haven't had any big problems whatsoever.

A great feature, nestjs provides is to generate the Schema based on the defined model by just defining the following within the module.ts

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: 'schema.gql'
}),

which helps you get started pretty fast.

Query

To define a simple query you just have to create an appropriate model and resolver like e.g.:

@ObjectType()
export class Cupcake {
  @Field()
  id: string;

  @Field()
  name: string;

  @Field({ nullable: true })
  stock?: number;

  @Field(() => [Ingredient])
  ingredients: Ingredient[];
}
@Resolver(() => Cupcake)
export class CupcakeResolver {

  @Query(() => Cupcake)
  async cupcake(@Args('id', { type: () => String }) id: string) {
    return this.cupcakeRepo.data.find(value => value.id === id);
  }
}

This would be enough to create your first GraphQL Query to fetch cupcakes by id

Mutation

Creating mutations is already quit simple.

Define the following to create the first mutation:

@InputType()
export class CreateCupcakeResource {
  @Field({ nullable: false })
  name: string;

  @Field({ nullable: true })
  stock?: number;

  @Field(() => [CreateIngredientResource])
  ingredients: Array<CreateIngredientResource>;
}
@InputType()
export class CreateIngredientResource {
  @Field({ nullable: false })
  name: string;
}
@Resolver(() => Cupcake)
export class CupcakeResolver {
  @Mutation(() => Cupcake)
  async createCupcake(@Args('cupcake') cupcake: CreateCupcakeResource) {
    ...
    return createdCupcake;
  }
}

Subscriptions

A great way do distribute information in a 'real time' manner is by using subscriptions which is also quit easy to accomplish using NestJS. Here a client can subscribe to some sort of topic and will be informed when new informations are available

Add the transmission protocol to your module.ts (subscriptions-transport-ws or graphql-ws)

GraphQLModule.forRoot<ApolloDriverConfig>({
  ...
  subscriptions: {
    'subscriptions-transport-ws': true
  },
}),

define the topic on which the information will be published and push your information to the topic

const pubSub = new PubSub();

@Resolver(() => Rating)
export class RatingResolver {
  private readonly topicRatingAdded = 'ratingAdded';

  @Subscription(() => Rating)
  async ratingAdded() {
    return pubSub.asyncIterator(this.topicRatingAdded);
  }

  @Mutation(() => Rating)
  async createRating(@Args('rating') rating: CreateRatingResource) {
    ...
    await pubSub.publish(this.topicRatingAdded, { ratingAdded: createdRating });
    ...
  }

see also:

Simon
Zur Übersicht

Mehr vom DevSquad...

Jan Sauer

The Cascading order of CSS

Dennis Hundertmark

Angular OAuth2