【TypeScript】GraphQL Subscriptionの型定義 - リアルタイムデータを型安全に処理

【TypeScript】GraphQL Subscriptionの型定義 - リアルタイムデータを型安全に処理

2024-10-26

2024-10-26

TypeScriptとGraphQL Subscriptionの概要

GraphQLは、API通信を柔軟に管理できるデータクエリ言語で、特にリアルタイム更新を扱うSubscription機能が特徴です。Subscriptionを使用することで、特定のデータに変更が生じた際にサーバーから自動的に通知を受け取り、クライアント側でリアルタイムにデータを処理できます。TypeScriptGraphQL Subscriptionを実装すると、リアルタイムデータを安全に受け取り、効率的に活用することが可能です。

TypeScriptでのGraphQL Subscription型定義の利点

  • コンパイル時のエラーチェック
    TypeScriptの型定義により、サブスクリプションで受信するデータが常に予測可能であるため、コンパイル時にエラーを発見しやすくなり、開発の効率が向上します。
  • コードの信頼性向上
    正確な型定義を使うことで、サーバーからの更新データが変わった際にも予期せぬエラーが発生しにくくなり、コードの信頼性が高まります。
  • 自動生成で型整合性を確保
    GraphQLのスキーマから自動生成した型定義を使うことで、フロントエンドとバックエンド間での型整合性が保たれ、コードの保守性が向上します。

GraphQL Subscriptionの型定義を実装する手順

GraphQL Code Generatorで型定義を自動生成

GraphQLの型定義をTypeScript用に自動生成するには、GraphQL Code Generatorgraphql-codegen)を使います。これにより、GraphQLのスキーマやクエリからTypeScriptの型を生成し、効率的に型定義を管理できます。

1.1 インストール

まず、graphql-codegenをインストールします。

npm install @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-operations --save-dev

1.2 設定ファイルの作成

次に、型を自動生成するための設定ファイルcodegen.ymlをプロジェクトのルートディレクトリに作成します。

schema: 'http://localhost:4000/graphql'
documents: 'src//*.graphql'
generates:
  src/generated/graphql.ts:
    plugins:
      - 'typescript'
      - 'typescript-operations'

1.3 型の生成

以下のコマンドでTypeScriptの型定義を生成します。

npx graphql-codegen

これにより、src/generated/graphql.tsにサブスクリプション用の型定義が生成されます。

Subscriptionクエリの定義と型の使用

生成した型を用いて、リアルタイムデータを型安全に受信するためのコードを実装します。たとえば、新しいメッセージをリアルタイムで受信するサブスクリプションを考えます。

Subscriptionクエリの作成

以下のように、サブスクリプションのクエリをsrc/subscription.graphqlに定義します。

subscription OnMessageReceived {
  messageReceived {
    id
    content
    sender {
      id
      name
    }
  }
}

TypeScriptでのSubscription実装

自動生成された型を使い、TypeScriptコード内でサブスクリプションを定義します。以下は、Apollo Clientを使用した実装例です。

import { gql, useSubscription } from '@apollo/client';
import { OnMessageReceivedSubscription } from './generated/graphql';
// サブスクリプションクエリ
const ON_MESSAGE_RECEIVED = gql`
  subscription OnMessageReceived {
    messageReceived {
      id
      content
      sender {
        id
        name
      }
    }
  }
`;
// useSubscriptionフックの使用
function MessageSubscription() {
  const { data, loading, error } = useSubscription<OnMessageReceivedSubscription>(ON_MESSAGE_RECEIVED);
  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;
  return (
    <div>
      <h2>New Message</h2>
      <p>{data?.messageReceived.content}</p>
      <p>From: {data?.messageReceived.sender.name}</p>
    </div>
  );
}

OnMessageReceivedSubscription型を指定することで、dataオブジェクトに自動的に型が適用され、サーバーから受け取るデータの安全性が確保されます。

TypeScriptでの型定義を活用したエラーハンドリング

サブスクリプションでデータを受信する際、エラーハンドリングも型安全に実装できます。たとえば、dataerrorの存在チェックは、TypeScriptの型システムを活用することで、明示的にエラーや未定義状態を判別可能です。

function MessageSubscription() {
  const { data, loading, error } = useSubscription<OnMessageReceivedSubscription>(ON_MESSAGE_RECEIVED);
  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error occurred: {error.message}</p>;
  if (!data || !data.messageReceived) return <p>No new messages</p>;
  return (
    <div>
      <p>{data.messageReceived.content}</p>
      <p>From: {data.messageReceived.sender.name}</p>
    </div>
  );
}

このように型を活用することで、dataオブジェクト内のプロパティが未定義であるかのチェックが簡素化され、型の安全性が向上します。

まとめ

TypeScriptGraphQL Subscriptionの型定義を行うと、リアルタイムデータの受信処理が型安全に管理でき、データの整合性が保たれます。GraphQL Code Generatorを使用して自動生成された型を使うことで、スキーマとコードの一貫性が保たれ、エラーハンドリングも含めて信頼性の高い実装が可能になります。リアルタイムデータを扱う場面では、型安全の重要性が特に増すため、TypeScriptとGraphQLの組み合わせを活用してエラーの少ないコーディングを目指しましょう。

Recommend