GraphQL

グラフキューエル

GraphQL を分かりやすく

GraphQLを一言で説明すると、「クライアントが必要なデータだけをサーバから取得することを可能にするクエリ言語」なんです。なんとも効率的な仕組みですよね。

例えば、レストランで食事をするとします。レストランのメニューがREST APIだとすると、お店の人(サーバ)がすでに用意している料理(データ)を選ぶしかないわけです。でも、「この料理はお野菜を抜きで」「あの料理はチーズ多めで」といった具体的なリクエストはできませんよね。

一方で、GraphQLを使うと、まるで自分だけのシェフを雇ったような感じです。あなた(クライアント)が「野菜を抜いた料理」や「チーズ多めの料理」をリクエストすれば、シェフ(サーバ)がそれに合わせて料理(データ)を作ってくれるわけです。何これ、贅沢すぎませんか?

さらに、あなたが「じゃあ、この料理から野菜を抜いて、あの料理からチーズを増やして…」と、必要なものだけを取り合わせて一度にリクエストできます。これがGraphQLの一番の強みで、データの過剰取得や不足を防ぐことができるんです。

まあ、だからと言ってすべての場合にGraphQLが最適というわけではないんですけどね。それぞれの技術には向き不向きがあるので、状況に応じて適切なものを選ぶのが大事ですよね。

まとめると、GraphQL(グラフキューエル)は、Facebook が開発した API 用のクエリ言語で、RESTful API の代替手段として広く利用されています。データの取得や更新を柔軟に行えるため、効率的なコミュニケーションを実現します。本解説では、Next.js と TypeScript を用いたソースコードを交えて、GraphQL の利用方法を説明します。

Next.js で GraphQL を利用する方法

Next.js と TypeScript を使用して、GraphQL を利用するためには、まず必要なライブラリをインストールしましょう。

npm install @apollo/client graphql

インストールが完了したら、Apollo Client の設定を行います。_app.tsx に以下のようなコードを追加しましょう。

// pages/_app.tsx
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client'

const client = new ApolloClient({
  uri: 'https://your-graphql-endpoint.example.com/graphql',
  cache: new InMemoryCache(),
})

function MyApp({ Component, pageProps }) {
  return (
    <ApolloProvider client={client}>
      <Component {...pageProps} />
    </ApolloProvider>
  )
}

export default MyApp

これで、Next.js と TypeScript の環境で GraphQL を使う準備が整いました。次に、具体的なクエリの実行方法を解説します。

クエリの実行とデータの取得

GraphQL を使用してデータを取得する際は、クエリを記述して送信します。例として、ブログ記事の一覧を取得するクエリを見てみましょう。

query {
  posts {
    id
    title
    author {
      name
    }
  }
}

このクエリを Next.js と TypeScript で実行して、データを取得する方法を解説します。まず、pages/posts/index.tsx に以下のようなコードを記述しましょう。

// pages/posts/index.tsx
import { useQuery, gql } from '@apollo/client'

const GET_POSTS = gql`
  query {
    posts {
      id
      title
      author {
        name
      }
    }
  }
`

const PostsPage = () => {
  const { loading, error, data } = useQuery(GET_POSTS)

  if (loading) return <p>Loading...</p>
  if (error) return <p>Error: {error.message}</p>

  return (
    <div>
      <h1>Posts</h1>
      <ul>
        {data.posts.map((post) => (
          <li key={post.id}>
            <h2>{post.title}</h2>
            <p>Author: {post.author.name}</p>
          </li>
        ))}
      </ul>
    </div>
  )
}

export default PostsPage

このコードでは、useQuery フックを使用して、GET_POSTS クエリを実行しています。loading が true の場合は、読み込み中のメッセージを表示します。エラーが発生した場合は、エラーメッセージを表示します。データが取得できた場合は、data.posts をマップして、記事の一覧を表示します。

ミューテーションの実行とデータの更新

データを更新するためには、GraphQL のミューテーションを使用します。例として、ブログ記事を作成するミューテーションを見てみましょう。

mutation CreatePost($title: String!, $authorId: ID!) {
  createPost(input: { title: $title, authorId: $authorId }) {
    id
    title
    author {
      name
    }
  }
}

このミューテーションを Next.js と TypeScript で実行する方法を解説します。まず、pages/posts/create.tsx に以下のようなコードを記述しましょう。

// pages/posts/create.tsx
import { useState } from 'react'
import { useMutation, gql } from '@apollo/client'
import { useRouter } from 'next/router'

const CREATE_POST = gql`
  mutation CreatePost($title: String!, $authorId: ID!) {
    createPost(input: { title: $title, authorId: $authorId }) {
      id
      title
      author {
        name
      }
    }
  }
`

const CreatePostPage = () => {
  const [title, setTitle] = useState('')
  const [authorId, setAuthorId] = useState('')
  const [createPost] = useMutation(CREATE_POST)
  const router = useRouter()

  const handleSubmit = async (e) => {
    e.preventDefault()

    await createPost({ variables: { title, authorId } })
    router.push('/posts')
  }

  return (
    <form onSubmit={handleSubmit}>
      <h1>Create a New Post</h1>
      <input type="text" placeholder="Title" value={title} onChange={(e) => setTitle(e.target.value)} />
      <input type="text" placeholder="Author ID" value={authorId} onChange={(e) => setAuthorId(e.target.value)} />
      <button type="submit">Create Post</button>
    </form>
  )
}

export default CreatePostPage

このコードでは、useMutation フックを使用して、CREATE_POST ミューテーションを実行しています。入力されたタイトルと著者の ID を変数として渡し、ミューテーションを実行します。フォームが送信された際に、handleSubmit 関数が呼び出され、createPost 関数を実行して新しい記事を作成します。その後、router.push('/posts') で記事一覧ページにリダイレクトします。

このように、Next.js と TypeScript を用いて GraphQL を利用する方法を解説しました。GraphQL はデータの取得や更新を柔軟に行えるため、効率的なコミュニケーションが可能です。Next.js と TypeScript の環境で GraphQL を活用し、アプリケーションの開発を効率化しましょう。