NestJS Enterprise Backend APIs · Lektion

Resolver und Subscriptions

Implementieren Sie GraphQL-Resolver zum Abrufen und Bearbeiten von Daten und richten Sie Subscriptions für Echtzeitaktualisierungen ein.

Lektion 3 von 311 Schritte

Resolver und Subscriptions ist eine kostenlose NestJS Enterprise Backend APIs-Lektion auf CoddyKit. Dies ist Lektion 3 von 3. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des NestJS Enterprise Backend APIs-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der NestJS Enterprise Backend APIs-Kurs umfasst insgesamt 3 Lektionen.

Teile dieser Lektion wurden noch nicht übersetzt und werden auf Englisch angezeigt.

Intro to GraphQL Resolvers

Welcome to the world of GraphQL resolvers in NestJS! Resolvers are the core of your GraphQL API, acting as the bridge between your GraphQL schema and your application's data sources.

  • They define how to fetch the data for a specific field in your schema.
  • Think of them as functions that execute when a corresponding field is requested in a GraphQL query or mutation.
  • Resolvers can interact with databases, REST APIs, or any other data source.

Resolver Structure in NestJS

NestJS simplifies resolver creation using decorators. You define a class as a resolver and then use specific decorators for different GraphQL operations:

  • @Resolver(): Marks a class as a GraphQL resolver.
  • @Query(): Maps a method to a GraphQL query operation (data fetching).
  • @Mutation(): Maps a method to a GraphQL mutation operation (data modification).
  • @Subscription(): Maps a method to a GraphQL subscription operation (real-time data).

Implementing a Basic Query

Let's create a simple query resolver that returns a 'Hello world!' string. This demonstrates the basic setup for a query:

import { Module, Injectable } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { join } from 'path';
import { Query, Resolver } from '@nestjs/graphql';

@Injectable()
class AppService {
  getHello(): string {
    return 'Hello world!';
  }
}

@Resolver()
class AppResolver {
  constructor(private readonly appService: AppService) {}

  @Query(() => String)
  hello(): string {
    return this.appService.getHello();
  }
}

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
    }),
  ],
  providers: [AppResolver, AppService],
})
class AppModule {}

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();

Handling Query Arguments

Queries often need arguments to filter or specify data. Use the @Args() decorator to extract arguments from the GraphQL request.

Here, we'll create a query that greets a specific name.

import { Module, Injectable } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { join } from 'path';
import { Args, Query, Resolver } from '@nestjs/graphql';

@Injectable()
class AppService {
  getGreeting(name: string): string {
    return `Hello, ${name}!`;
  }
}

@Resolver()
class AppResolver {
  constructor(private readonly appService: AppService) {}

  @Query(() => String)
  greet(@Args('name') name: string): string {
    return this.appService.getGreeting(name);
  }
}

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
    }),
  ],
  providers: [AppResolver, AppService],
})
class AppModule {}

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();

Introducing GraphQL Mutations

While queries fetch data, mutations are used for modifying data on the server. This includes operations like creating, updating, or deleting records.

  • Mutations are similar to queries in structure but clearly signal a side effect.
  • They typically return the modified object or a status indicating success.
  • Use the @Mutation() decorator to define them in NestJS.

Implementing a Basic Mutation

Let's create a mutation to add a simple 'Item'. We'll define an Item type and a mutation that takes a name and returns the newly created item.

import { Module, Injectable, Field, ObjectType, InputType } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { join } from 'path';
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';

@ObjectType()
class Item {
  @Field(() => String)
  id: string;

  @Field(() => String)
  name: string;
}

@Injectable()
class ItemsService {
  private readonly items: Item[] = [];
  create(name: string): Item {
    const newItem = { id: String(this.items.length + 1), name };
    this.items.push(newItem);
    return newItem;
  }
  findAll(): Item[] { return this.items; }
}

@Resolver(() => Item)
class ItemsResolver {
  constructor(private readonly itemsService: ItemsService) {}

  @Query(() => [Item])
  items(): Item[] {
    return this.itemsService.findAll();
  }

  @Mutation(() => Item)
  createItem(@Args('name') name: string): Item {
    return this.itemsService.create(name);
  }
}

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
    }),
  ],
  providers: [ItemsResolver, ItemsService],
})
class AppModule {}

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();

What are GraphQL Subscriptions?

Subscriptions are a GraphQL feature that allows clients to receive real-time updates from the server. Unlike queries and mutations (which are request-response), subscriptions are long-lived connections, typically over WebSockets.

  • When a client subscribes, it opens a persistent connection.
  • The server pushes data to the client whenever a specific event occurs.
  • Perfect for chat applications, live dashboards, or notifications.

Setting up PubSub for Subscriptions

To implement subscriptions, NestJS GraphQL often uses graphql-subscriptions's PubSub (Publish-Subscribe) mechanism. The server publishes events, and subscribers listen for them.

You need to configure GraphQLModule for subscriptions and provide a PubSub instance.

import { Module, Injectable } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { join } from 'path';
import { PubSub } from 'graphql-subscriptions';

// We need a module to provide PubSub
@Module({
  providers: [
    {
      provide: 'PUB_SUB', // Token for PubSub instance
      useValue: new PubSub(),
    },
  ],
  exports: ['PUB_SUB'], // Export to use in other modules
})
class PubSubModule {}

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
      // Crucial for subscriptions:
      subscriptions: {
        'graphql-ws': true, // Enable WebSocket for subscriptions
        'subscriptions-transport-ws': true,
      },
    }),
    PubSubModule,
  ],
  // No resolvers needed for this example, just setup
})
class AppModule {}

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
  console.log('GraphQL server with subscriptions running on port 3000');
}
bootstrap();

Implementing a Subscription

Now let's build a subscription! We'll create a postAdded subscription that emits an event whenever a new post is created via a mutation.

  • Use @Subscription() to define the subscription method.
  • Inject PubSub to publish events.
  • The mutation will trigger the event.
import { Module, Injectable, Field, ObjectType, Inject } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { join } from 'path';
import { Args, Mutation, Query, Resolver, Subscription } from '@nestjs/graphql';
import { PubSub } from 'graphql-subscriptions';

const POST_ADDED_EVENT = 'postAdded';

@ObjectType()
class Post {
  @Field(() => String)
  id: string;

  @Field(() => String)
  title: string;

  @Field(() => String)
  content: string;
}

@Injectable()
class PostsService {
  private readonly posts: Post[] = [];
  create(title: string, content: string): Post {
    const newPost = { id: String(this.posts.length + 1), title, content };
    this.posts.push(newPost);
    return newPost;
  }
  findAll(): Post[] { return this.posts; }
}

@Module({
  providers: [
    {
      provide: 'PUB_SUB', // Token for PubSub instance
      useValue: new PubSub(),
    },
  ],
  exports: ['PUB_SUB'], // Export to use in other modules
})
class PubSubModule {}

@Resolver(() => Post)
class PostsResolver {
  constructor(
    private readonly postsService: PostsService,
    @Inject('PUB_SUB') private pubSub: PubSub,
  ) {}

  @Query(() => [Post])
  posts(): Post[] {
    return this.postsService.findAll();
  }

  @Mutation(() => Post)
  async createPost(
    @Args('title') title: string,
    @Args('content') content: string,
  ): Promise<Post> {
    const newPost = this.postsService.create(title, content);
    await this.pubSub.publish(POST_ADDED_EVENT, { postAdded: newPost });
    return newPost;
  }

  @Subscription(() => Post, { name: POST_ADDED_EVENT })
  postAdded() {
    return this.pubSub.asyncIterator(POST_ADDED_EVENT);
  }
}

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
      subscriptions: {
        'graphql-ws': true,
        'subscriptions-transport-ws': true,
      },
    }),
    PubSubModule,
  ],
  providers: [PostsResolver, PostsService],
})
class AppModule {}

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
  console.log('GraphQL server with subscriptions running on port 3000');
  console.log('Try a POST_ADDED_EVENT subscription in your client!');
}
bootstrap();

Resolver & Subscription Check

Time to test your knowledge on NestJS GraphQL resolvers and subscriptions!

Recap: Resolvers & Real-time

Congratulations! You've grasped the essentials of GraphQL resolvers and subscriptions in NestJS.

  • Resolvers are the backbone, connecting your schema to your data.
  • Queries fetch data, Mutations change data, and Subscriptions provide real-time updates.
  • We explored how to implement simple queries and mutations, and set up real-time features using PubSub for subscriptions.

Keep practicing to build dynamic and responsive GraphQL APIs!

Kostenlos starten

Lerne TypeScript mit einem KI-Tutor — kostenlos

Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.

Kurse
20
Lektionen
76

Häufig gestellte Fragen

Ist die Lektion „Resolver und Subscriptions“ kostenlos?

Ja — der vollständige Text von „Resolver und Subscriptions“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des NestJS Enterprise Backend APIs-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der NestJS Enterprise Backend APIs-Kurs umfasst insgesamt 3 Lektionen.

Was lerne ich in „Resolver und Subscriptions“?

Implementieren Sie GraphQL-Resolver zum Abrufen und Bearbeiten von Daten und richten Sie Subscriptions für Echtzeitaktualisierungen ein. Du übst NestJS Enterprise Backend APIs mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um NestJS Enterprise Backend APIs zu starten?

Keine Vorkenntnisse erforderlich. NestJS Enterprise Backend APIs auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 3.

Wie lange dauert die Lektion „Resolver und Subscriptions“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser NestJS Enterprise Backend APIs-Lektion Code schreiben und ausführen?

Ja. Jede NestJS Enterprise Backend APIs-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Grundlagen von GraphQL
  2. NestJS-GraphQL-Einrichtung
  3. Resolver und Subscriptions
← Zurück zu NestJS Enterprise Backend APIs