GraphQLでサブスクリプションを使用しようとしたときに「Schema is not configured for subscriptions」というエラーが表示されることがあります。このエラーは、GraphQLスキーマがサブスクリプションに対応するように正しく設定されていない場合に発生します。本記事では、このエラーの原因と解決方法について詳しく解説します。

エラーの原因

「Schema is not configured for subscriptions」エラーが発生する主な原因は以下の通りです:

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

2. サーバー側でサブスクリプションの設定が不足している

3. WebSocketの設定が正しくない

解決方法

1. GraphQLスキーマにサブスクリプション型を追加する

まず、GraphQLスキーマにサブスクリプション型を追加する必要があります。以下のように`Subscription`型を定義してください:

type Subscription {
  newMessage: Message
}

2. サーバー側の設定を確認する

サーバー側で、サブスクリプションを処理するためのリゾルバーが正しく設定されているか確認します。例えば、Apollo Serverを使用している場合は以下のように設定します:

const resolvers = {
  Subscription: {
    newMessage: {
      subscribe: () => pubsub.asyncIterator(['NEW_MESSAGE'])
    }
  }
};

3. WebSocketの設定を確認する

サブスクリプションはWebSocketを使用するため、サーバーがWebSocketをサポートしていることを確認してください。Apollo Serverの場合、以下のように設定します:

import { ApolloServer } from 'apollo-server-express';
import { createServer } from 'http';
import express from 'express';
import { makeExecutableSchema } from '@graphql-tools/schema';

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

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

const server = new ApolloServer({
  schema,
  plugins: [
    ApolloServerPluginDrainHttpServer({ httpServer }),
    {
      async serverWillStart() {
        return {
          async drainServer() {
            await serverCleanup.dispose();
          },
        };
      },
    },
  ],
});

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

const serverCleanup = useServer({ schema }, wsServer);

httpServer.listen(PORT, () => {
  console.log(`Server is now running on http://localhost:${PORT}/graphql`);
});

4. クライアント側の設定を確認する

クライアント側でも、サブスクリプションを使用するための設定が必要です。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のサブスクリプションは、リアルタイムデータ更新を実現する強力な機能です。正しく設定することで、よりインタラクティブで動的なアプリケーションを開発することができます。