この記事では、 Mutation
と Subscription
GraphQLでクエリを実行するだけでなく、データを操作して変更を監視するタイプ。 公式ドキュメントで詳細をお気軽に見つけてください。
簡単にするために、データベースやHTTPリクエストは使用しませんが、スキーマとリゾルバーを使用して基本的なAPIを設定する方法を知っている必要があります。
インストール
graphql-yogaライブラリを使用してサーバーをセットアップします nodemon
自動的にリロードします。 また、JavaScriptの最新機能を使用できるように、Preprosやbabelなどのプリプロセッサーも必要です。
$ npm i graphql-yoga nodemon
ボイラープレートの設定
サーバーのセットアップに加えて、空の users
配列と、すべてのユーザーを返すための単純なスキーマとリゾルバー。
import { GraphQLServer } from 'graphql-yoga'
const users = [];
const typeDefs = `
type Query {
users: [User!]!
}
type User {
name: String!
age: Int!
}
`;
const resolvers = {
Query: {
user() {
return users;
}
}
}
const server = new GraphQLServer({ typeDefs, resolvers });
server.start(() => console.log('server running'));
必要です start
出力ファイルでnodemonを実行するスクリプト:
{
"name": "graphql-api",
"version": "1.0.0",
"description": "",
"main": "server.js",
"dependencies": {
"graphql-yoga": "^1.16.7"
},
"devDependencies": {
"nodemon": "^1.19.1"
},
"scripts": {
"start": "nodemon server-dist.js"
},
"author": "",
"license": "ISC"
}
今ターミナルであなたはただ走ることができます npm run start
.
以上で localhost:4000
GraphQLPlaygroundを起動して実行する必要があります。 user { name }
空の配列を返します。
ミューテーションを作成する
ミューテーションの構文は、クエリの構文とほぼ同じです。 必要なオプションを宣言し、引数(存在する場合)を追加し、完了時に返されるタイプを宣言するだけです。
すべてのout引数をインラインで追加する代わりに、データをと呼ばれる独自の特殊な型に分割することはかなり一般的です。 input
整理のために入力します。 これは、 Prisma などのツールで見られる一般的な命名規則であり、リゾルバーがinputという単語で終わるものに関係なく、入力に名前を付けます。 addUser
取得します AddUserInput
入力。
const typeDefs = `
type Mutation {
addUser(data: AddUserInput): User!
}
input AddUserInput {
name: String!,
age: Int!
}
`;
クエリの場合と同様に、上の引数にアクセスできます args
新しいユーザーを配列に追加して、それらを返します。
const resolvers = {
Query: {...},
Mutation: {
addUser(parent, args, ctx, info) {
const user = { ...args.data };
users.push(user);
return user;
}
}
}
ミューテーションの削除と更新
構文が非常に単純なため、他のCRUD操作を具体化するのはほとんど簡単です。
名前でユーザーを検索するだけで、削除または更新するアイテムがわかります。
const typeDefs = `
type Mutation {
deleteUser(name: String!): User!
updateUser(name: String!, data: UpdateUserInput): User!
}
input UpdateUserInput {
name: String
age: Int
}
`
const resolvers = {
Query: { ... },
Mutation: {
deleteUser(parent, args, ctx, info) {
// We're just finding the index of the user with a matching name,
// checking if it exists, and removing that section of the array.
const userIndex = users.findIndex(user => user.name.toLowerCase() === args.name.toLowerCase());
if (userIndex === -1) throw new Error('User not found');
const user = users.splice(userIndex, 1);
return user[0];
},
updateUser(parent, args, ctx, info) {
const user = users.find(user => user.name.toLowerCase() === args.who.toLowerCase());
if (!user) throw new Error('User not found');
// This way, only the fields that are passed-in will be changed.
if (typeof args.data.name === "string") user.name = args.data.name;
if (typeof args.data.age !== "undefined") user.age = args.data.age;
return user;
}
}
}
今で終わり localhost:4000
このミューテーションを試して、配列を再度クエリできます。
mutation {
addUser(data: {
name: "Alli",
age: 48
}) {
name
age
}
}
または別のタブで:
mutation {
updateUser(name: "Alli", data: {
name: "Crusher",
age: 27
}) {
name
age
}
}
サブスクリプション
スペシャルが使えます Subscription
データの変更を監視するために入力します。 構文はクエリやミューテーションの構文と非常に似ていますが、タイプを追加するだけです Subscription
、見たいものと、返したいものを追加します。 変更されたデータと、それが作成、削除、または更新のいずれの操作であったかを通知するカスタムタイプを返します。
サブスクリプションを使用するには、使用する必要があります PubSub
graphql-yogaから、他のすべての前に初期化します。 サブスクリプションリゾルバーでは、次の関数を使用します subscribe
非同期イベントを返す必要があります。これに名前を付けます user
. このサブスクリプションに何かを接続する場合は常に、このイベント名を使用します。
import { GraphQLServer, PubSub } from 'graphql-yoga';
const pubsub = new PubSub();
const typeDefs = `
type Subscription {
user: UserSubscription!
}
type UserSubscription {
mutation: String!
data: User!
}
`
const resolvers = {
Query: { ... },
Mutation: { ... },
Subscription: {
user: {
subscribe() {
return pubsub.asyncIterator('user');
}
}
}
}
サブスクリプション自体はセットアップされており、生成されたGraphQLドキュメントで利用できますが、いつ起動するか、何を返すかはわかりません。 ミューテーションに戻って、追加します pubsub.publish
私たちにリンクするには user
イベントを行い、データを返します。
const resolvers = {
Query: { ... },
Mutation: {
addUser(parent, args, ctx, info) {
const user = { ...args.data };
users.push(user);
// We'll just link it to our user event,
// and return what type of mutation this is and our new user.
pubsub.publish("user", {
user: {
mutation: "Added",
data: user
}
});
return user;
},
deleteUser(parent, args, ctx, info) {
const userIndex = users.findIndex(
user => user.name.toLowerCase() === args.who.toLowerCase()
);
if (userIndex === -1) throw new Error("User not found");
const user = users.splice(userIndex, 1);
pubsub.publish("user", {
user: {
mutation: "Deleted",
data: user[0]
}
});
return user[0];
},
updateUser(parent, args, ctx, info) {
const user = users.find(
user => user.name.toLowerCase() === args.who.toLowerCase()
);
if (!user) throw new Error("User not found");
if (typeof args.data.name === "string") user.name = args.data.name;
if (typeof args.data.age !== "undefined") user.age = args.data.age;
pubsub.publish("user", {
user: {
mutation: "Updated",
data: user
}
});
return user;
}
},
Subscription: { ... }
};
以上で localhost:4000
新しいタブを開いて、次のサブスクリプションを実行できます。 小さな糸車で「聞いている…」というメッセージが表示されるはずです。 別のタブで、他の過去のミューテーションを実行できるようになりました。サブスクリプションは、実行された内容と変更された内容を自動的に返します。
subscription {
user {
mutation
data {
name
age
}
}
}
結論
これが、ミューテーションとサブスクリプションを使用してGraphQLAPIをセットアップする方法を理解するのに役立つことを願っています。 これを設定する際に問題が発生した場合は、いつでもこのリポジトリを確認できます。