graphql-request vs urql vs apollo-client vs react-apollo
React 向け GraphQL クライアントライブラリの選定ガイド
graphql-requesturqlapollo-clientreact-apollo유사 패키지:

React 向け GraphQL クライアントライブラリの選定ガイド

apollo-client、graphql-request、react-apollo、urql は GraphQL クエリの実行を助けますが、キャッシュ管理や React との統合方法が大きく異なります。apollo-client は包括的なキャッシュ機能を提供し、urql は軽量で拡張性が高いです。graphql-request は最小限の機能でサーバーサイドに適しています。react-apollo は非推奨であり、新しいプロジェクトでは使用すべきではありません。

npm 다운로드 트렌드

3 년

GitHub Stars 순위

통계 세부사항

패키지
다운로드
Stars
크기
Issues
발행일
라이선스
graphql-request13,112,8486,121420 kB601年前MIT
urql1,518,1508,985140 kB332ヶ月前MIT
apollo-client583,95619,781-4106年前MIT
react-apollo167,0586,790-2057年前MIT

Apollo Client vs urql vs graphql-request:GraphQL クライアントの比較

現代の React アプリケーションにおいて、GraphQL クライアントの選定はアーキテクチャ全体に影響を与えます。apollo-client、urql、graphql-request はそれぞれ異なる哲学を持って設計されており、react-apollo は歴史的な経緯から特別な注意が必要です。ここでは、実務的な観点からこれらを比較します。

⚠️ 最重要:非推奨パッケージの注意

まず最初に明確にすべき点があります。react-apollo は現在、公式に非推奨(deprecated)となっています。

react-apollo

  • かつて Apollo Client の React バインディングとして使われていました。
  • 現在は機能が @apollo/client に統合されています。
  • 新しいプロジェクトで使用すると、メンテナンス性やセキュリティのリスクが生じます。
// react-apollo: 非推奨(レガシーコード)
import { Query } from 'react-apollo';

// 古いコンポーネントベースの API
<Query query={GET_USER}>
  {({ loading, data }) => loading ? <Spinner /> : <User data={data} />}
</Query>

apollo-client (現代の @apollo/client)

  • 現在の標準パッケージです。
  • フックベースの API が提供されます。
// apollo-client: 現在の標準
import { useQuery } from '@apollo/client';

function User() {
  const { loading, data } = useQuery(GET_USER);
  return loading ? <Spinner /> : <User data={data} />;
}

🗂️ アーキテクチャとキャッシュ機能

データキャッシュの有无は、クライアント選定における最大の分岐点です。

apollo-client

  • 正規化されたキャッシュを内蔵しています。
  • クエリ結果を自動的に保存し、関連するコンポーネントを更新します。
  • 複雑なデータ関係の管理に優れています。
// apollo-client: 自動キャッシュ更新
import { useQuery, useMutation } from '@apollo/client';

function UserProfile() {
  const { data } = useQuery(GET_USER);
  const [updateName] = useMutation(UPDATE_USER);
  // ミュテーション実行後、キャッシュが自動的に更新され UI が反映される
}

urql

  • キャッシュ機能を持っていますが、よりシンプルです。
  • デフォルトではドキュメントキャッシュを使用し、必要に応じて交換可能(exchange)なキャッシュを使います。
// urql: シンプルなキャッシュ
import { useQuery } from 'urql';

function UserProfile() {
  const [result] = useQuery({ query: GET_USER });
  // デフォルトでキャッシュされるが、Apollo より設定が簡素
}

graphql-request

  • キャッシュ機能はありません。
  • 毎回サーバーにリクエストを送ります。
  • 単純な取得や、キャッシュ制御を自前で行いたい場合に適しています。
// graphql-request: キャッシュなし
import { request } from 'graphql-request';

async function getUser() {
  // 毎回ネットワークリクエストが発生する
  const { user } = await request(endpoint, GET_USER);
  return user;
}

📥 React 統合とフック

React コンポーネント内でどのようにデータを扱うかも重要な違いです。

apollo-client

  • ApolloProvider でアプリを囲む必要があります。
  • useQuery、useMutation などの専用フックが充実しています。
// apollo-client: Provider 設定
import { ApolloProvider, ApolloClient, InMemoryCache } from '@apollo/client';

const client = new ApolloClient({ uri: '/graphql', cache: new InMemoryCache() });

function App() {
  return <ApolloProvider client={client}><Dashboard /></ApolloProvider>;
}

urql

  • Provider でアプリを囲みますが、設定がより簡潔です。
  • useQuery は配列 destructuring を使用します。
// urql: Provider 設定
import { Provider, createClient } from 'urql';

const client = createClient({ url: '/graphql' });

function App() {
  return <Provider value={client}><Dashboard /></Provider>;
}

graphql-request

  • React 専用ライブラリではありません。
  • Provider は不要で、どこからでも呼び出せます。
  • React 内で使う場合は、useEffect などで手動管理が必要です。
// graphql-request: React での手動管理
import { request } from 'graphql-request';
import { useEffect, useState } from 'react';

function Dashboard() {
  const [data, setData] = useState(null);
  useEffect(() => {
    request(endpoint, GET_USER).then(setData);
  }, []);
  // 状態管理を自分で行う必要がある
}

🔄 拡張性とミドルウェア

リクエストの前後に処理を挟む機能(ミドルウェア)の比較です。

apollo-client

  • Link システムを使用します。
  • 認証トークンの付与やエラー処理をチェーンできます。
// apollo-client: Link による拡張
import { setContext } from '@apollo/client/link/context';

const authLink = setContext((_, { headers }) => ({
  headers: { ...headers, authorization: token }
}));
// client 作成時に link を結合する

urql

  • Exchange システムを使用します。
  • 関数型アプローチで処理を繋ぎます。
// urql: Exchange による拡張
import { fetchExchange, cacheExchange } from '@urql/core';

const client = createClient({
  url: '/graphql',
  exchanges: [cacheExchange, fetchExchange]
  // ここにカスタム exchange を挟み込む
});

graphql-request

  • 拡張機能はほぼありません。
  • 必要な場合は、ラッパー関数を作成して対応します。
// graphql-request: 手動ラッパー
async function requestWithAuth(query, variables) {
  const headers = { authorization: token };
  return request(endpoint, query, variables, headers);
}

📊 比較まとめ

特徴apollo-clienturqlgraphql-requestreact-apollo
キャッシュ✅ 正規化キャッシュ✅ シンプルキャッシュ❌ なし✅ 旧キャッシュ
React 統合✅ 専用フック✅ 専用フック❌ 手動管理✅ 旧コンポーネント
拡張性✅ Link システム✅ Exchange システム❌ 手動ラッパー✅ 旧 Link
状態✅ 維持中✅ 維持中✅ 維持中❌ 非推奨
用途大規模アプリ軽量〜中規模スクリプト/単純取得使用禁止

💡 最終推奨

apollo-client は、大規模なアプリケーションでデータの一貫性を保ちたい場合に最適です — 学習コストは高いですが、その分の機能があります。

urql は、Apollo の機能は欲しいが重すぎる場合に選ばれます — 設定がシンプルで、カスタマイズも容易です。

graphql-request は、React の状態管理を介さず、単純にデータを取得したい場合に有効です — サーバーサイド処理やバッチスクリプトに向いています。

react-apollo は、技術的な負債となります — 新しいプロジェクトでは絶対に避け、既存プロジェクトからは移行してください。

最終的には、プロジェクトの規模とキャッシュの必要性で決まります — 複雑な状態管理が必要なら Apollo、シンプルさ優先なら urql、単なる取得なら graphql-request です。

선택 방법: graphql-request vs urql vs apollo-client vs react-apollo

  • graphql-request:

    キャッシュ不要で単純なデータ取得が必要な場合や、サーバーサイド Node.js スクリプトでの利用に適しています。バンドルサイズを最小限に抑えたい場合にも有効です。

  • urql:

    軽量さを保ちつつカスタマイズ性を求めたい場合に最適です。Apollo よりもシンプルな API を好みながら、拡張機能も必要なチームに向いています。

  • apollo-client:

    大規模なキャッシュ管理や複雑な状態管理が必要なエンタープライズ向けプロジェクトに適しています。正規化されたキャッシュにより、UI の更新を自動的に処理できるため、データ整合性が重要な場合に選択します。

  • react-apollo:

    非推奨パッケージです。新しいプロジェクトでは絶対に使用しないでください。既存プロジェクトからは @apollo/client へ移行すべきです。

graphql-request의 README

graphql-request

Minimal GraphQL client supporting Node and browsers for scripts or simple apps.

GitHub Action npm version

Highlights

  • Most simple & lightweight GraphQL client
  • Promise-based API (works with async / await)
  • Pure ESM package
  • First class TypeScript support
    • Including TypedDocumentNode
  • Isomorphic (works in both Node and Browsers)

Install

npm add graphql-request graphql

TypeScript Setup

This package uses package.exports. Therefore if you are a TypeScript user you must:

  1. have your tsconfig.json moduleResolution set to "bundler" or "node16"/"nodenext".
  2. Have your package.json type set to "module".

Quick Start

Send a GraphQL document using a static request function:

import { gql, request } from 'graphql-request'

const document = gql`
  {
    company {
      ceo
    }
  }
`
await request('https://api.spacex.land/graphql/', document)

The function can be passed a configuration object for more complex cases:

await request({
  url,
  document,
  variables,
  requestHeaders,
})

A class is available for constructing your own instances:

import { gql, GraphQLClient } from 'graphql-request'

const document = gql`
  {
    company {
      ceo
    }
  }
`
const endpoint = 'https://api.spacex.land/graphql/'
const client = new GraphQLClient(endpoint)
await client.request(document)

Examples

Node Version Support

We only (officially) support versions of Nodejs of the following status:

  • Current
  • LTS
  • Maintenance and end of life not yet reached

So for example on Oct 24 2023 that would mean these versions: 18, 20, 21.

Any issue that exists solely for an unsupported version of Nodejs will be rejected (not worked on).

Reference

⚠️ This reference is incomplete. Check out the examples for more reference material.

Configuration

ErrorPolicy

By default GraphQLClient will throw when an error is received. However, sometimes you still want to resolve the (partial) data you received. You can define errorPolicy in the GraphQLClient constructor.

const client = new GraphQLClient(endpoint, { errorPolicy: 'all' })
None (default)

Allow no errors at all. If you receive a GraphQL error the client will throw.

Ignore

Ignore incoming errors and resolve like no errors occurred

All

Return both the errors and data, only works with rawRequest.

IgnoreOperationName

OperationName has been introduced to address issues reported here Support operation name, However, on certain occasions this information may not be needed in requests. In such cases, you might consider ignoring operationName to avoid the extraction steps currently performed by a parsing operation when the document is provided in string format.

By default the GraphQLClient tries to extract the operationName from the document. You can define excludeOperationName in the constructor of GraphQLClient to avoid the extraction process if it is not needed. This can be useful if you don't use operationName and want to optimise queries by reducing the amount of computation as much as possible, especially if we are in a context where we are using documents in string format to reduce bundle size.

// example where the operation name is not ignored
const client = new GraphQLClient(endpoint, {
  method: 'POST',
})
// example in which the operation name is ignored
const client = new GraphQLClient(endpoint, {
  method: 'POST',
  excludeOperationName: true,
})

Knowledge Base

Why was the file upload feature taken away? Will it return?

In this issue we decided to make this library more stable and maintainable. In principal the feature is still in scope of this library and will make a return when we find time to do the feature right.

Why do I have to install graphql?

graphql-request uses methods exposed by the graphql package to handle some internal logic. On top of that, for TypeScript users, some types are used from the graphql package to provide better typings.

Do I need to wrap my GraphQL documents inside the gql template exported by graphql-request?

No. It is there for convenience so that you can get the tooling support like automatic formatting and syntax highlighting. You can use gql from graphql-tag if you need it for some reason too.

What sets graphql-request apart from other clients like Apollo, Relay, etc.?

graphql-request is the most minimal and simplest to use GraphQL client. It's perfect for small scripts or simple apps.

Compared to GraphQL clients like Apollo or Relay, graphql-request doesn't have a built-in cache and has no integrations for frontend frameworks. The goal is to keep the package and API as minimal as possible.

Project Stats

Package Installs

NPM Usage Trend of graphql-request

Repo Beats

Alt