リゾルバーとサブスクリプション
データの取得や操作を行うGraphQLリゾルバーを実装し、リアルタイムのデータ更新に対応するサブスクリプションを設定します。
「リゾルバーとサブスクリプション」はCoddyKit上の無料NestJS Enterprise Backend APIsレッスンです。 これはレッスン3/3です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはNestJS Enterprise Backend APIs学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 NestJS Enterprise Backend APIsコースには全3レッスンが含まれています。
このレッスンの一部はまだ翻訳されておらず、英語で表示されています。
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
PubSubto 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
PubSubfor subscriptions.
Keep practicing to build dynamic and responsive GraphQL APIs!
よくある質問
「リゾルバーとサブスクリプション」レッスンは無料ですか?
はい。「リゾルバーとサブスクリプション」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、NestJS Enterprise Backend APIsコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 NestJS Enterprise Backend APIsコースには全3レッスンが含まれています。
「リゾルバーとサブスクリプション」で何を学びますか?
データの取得や操作を行うGraphQLリゾルバーを実装し、リアルタイムのデータ更新に対応するサブスクリプションを設定します。 ブラウザで直接実行するハンズオンコードでNestJS Enterprise Backend APIsを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
NestJS Enterprise Backend APIsを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのNestJS Enterprise Backend APIsは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/3です。
「リゾルバーとサブスクリプション」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このNestJS Enterprise Backend APIsレッスンでコードを書いて実行できますか?
はい。すべてのNestJS Enterprise Backend APIsレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- GraphQLの基礎
- NestJSのGraphQL設定
- リゾルバーとサブスクリプション