GraphQLを使用していて「Schema is not configured for subscriptions」というエラーに遭遇した経験はありますか?このエラーは、サブスクリプション機能を使おうとしたときに、スキーマが適切に設定されていない場合に発生します。本記事では、このエラーの原因と解決方法について詳しく説明します。

エラーの原因

「Schema is not configured for subscriptions」エラーは、主に以下の理由で発生します:

1. サブスクリプション用のスキーマが定義されていない

2. サーバー側でサブスクリプションがサポートされていない

3. クライアント側の設定が不適切

解決方法

1. サブスクリプションスキーマの定義

まず、GraphQLスキーマにサブスクリプションタイプを追加する必要があります:

type Subscription {
  newMessage: Message
}

2. サーバー側の設定

サーバー側でサブスクリプションをサポートするために、以下の手順を実行します:

  • WebSocketサポートを追加
  • PubSubメカニズムの実装
  • サブスクリプションリゾルバーの定義

例えば、Apollo Serverを使用している場合:

const { ApolloServer } = require('apollo-server-express');
const { createServer } = require('http');
const express = require('express');
const { execute, subscribe } = require('graphql');
const { SubscriptionServer } = require('subscriptions-transport-ws');
const { makeExecutableSchema } = require('@graphql-tools/schema');

const app = express();
const httpServer = createServer(app);

const schema = makeExecutableSchema({
  typeDefs,
  resolvers,
});

const server = new ApolloServer({
  schema,
  plugins: [{
    async serverWillStart() {
      return {
        async drainServer() {
          subscriptionServer.close();
        }
      };
    }
  }],
});

const subscriptionServer = SubscriptionServer.create(
  { schema, execute, subscribe },
  { server: httpServer, path: '/graphql' }
);

await server.start();
server.applyMiddleware({ app });

httpServer.listen(PORT, () => {
  console.log(`Server ready at http://localhost:${PORT}${server.graphqlPath}`);
  console.log(`Subscriptions ready at ws://localhost:${PORT}${server.graphqlPath}`);
});

3. クライアント側の設定

クライアント側では、WebSocketクライアントを設定する必要があります。Apollo Clientを使用している場合:

import { ApolloClient, InMemoryCache, HttpLink, split } from '@apollo/client';
import { getMainDefinition } from '@apollo/client/utilities';
import { WebSocketLink } from '@apollo/client/link/ws';

const httpLink = new HttpLink({
  uri: 'http://localhost:4000/graphql'
});

const wsLink = new WebSocketLink({
  uri: 'ws://localhost:4000/graphql',
  options: {
    reconnect: true
  }
});

const splitLink = split(
  ({ query }) => {
    const definition = getMainDefinition(query);
    return (
      definition.kind === 'OperationDefinition' &&
      definition.operation === 'subscription'
    );
  },
  wsLink,
  httpLink
);

const client = new ApolloClient({
  link: splitLink,
  cache: new InMemoryCache()
});

まとめ

「Schema is not configured for subscriptions」エラーは、GraphQLサブスクリプションの設定が不完全な場合に発生します。適切なスキーマ定義、サーバー側の設定、そしてクライアント側の設定を行うことで、このエラーを解決し、リアルタイムデータ更新機能を実現できます。

GraphQLサブスクリプションは強力な機能ですが、適切な設定が必要です。本記事の手順に従って設定を行えば、スムーズにサブスクリプション機能を利用できるようになるでしょう。