Skip to content

필사 모드: GraphQL スペック、ほぼ4年ぶりのリリース — September 2025 エディションと GraphQL.js 17 GA に入ったもの、まだ外にあるもの

日本語
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

はじめに — 止まっていたはずの標準が動いた

GraphQL スペックの最後のエディションは、長らくOctober 2021でした。その間もエコシステムは回り続けましたが — Apollo Federation、各種ゲートウェイやクライアントがそれぞれ進化する一方で — 標準文書そのものは4年近く止まっていました。「GraphQLはもう保守モードなのか」という皮肉が出てもおかしくない空白でした。

その空白が、最近の二つのリリースで破られました。2025年9月、September 2025 エディションが出て — 公式発表の表現どおり、October 2021以来初のエディションです — 2026年6月15日には、参照実装であるGraphQL.js v17がGAになりました。v17の最初のアルファがnpmに上がった日付が2022年5月19日ですから、アルファのラベルを外すのに4年を超える時間がかかったことになります。

本稿はこの二つのリリースをハイプ抜きで解剖します。何が実際に標準に入ったのか、何がまだ外にあるのか(ネタバレ: @defer@stream)、そして今あなたのチームが何をすべきか。すべての日付とバージョンは、スペック原文・npmレジストリ・GitHubリリースで直接確認しました。

まず日付を正確に — 二つのリリースのタイムライン

GraphQL スペック (spec.graphql.org)
  2015-07  最初のワーキングドラフト (July 2015)
  2021-10-26  October 2021 エディション
  2025-09-03  September 2025 エディション   <- 3年10か月ぶり
  2026-06-04  現行ワーキングドラフト更新(次エディションの準備)

GraphQL.js (registry.npmjs.org 公開時刻)
  2022-05-19  17.0.0-alpha.1
  2025-06-11  17.0.0-alpha.9
  2026-05-07  17.0.0-beta.0
  2026-06-02  17.0.0-rc.0
  2026-06-15  17.0.0 GA              <- アルファ開始から4年あまり
  2026-07-03  17.0.2 (現行のlatest)

  16.x は今もパッチ中: 16.13.0(2026-02-24)、16.14.2(2026-06-09)

スペックのリリースノートによれば、September 2025 エディションには October 2021 以降、30名の貢献者による100件を超える変更が入っており、このリリースは最初のドラフト(2015年7月)から10年目にあたるリリースでもあります。

September 2025 エディション — 4年分の変更から拾うべきもの

公式チェンジログが挙げる主要な変更は5つです。一つずつ見ていきます。

OneOf 入力オブジェクト — 「入力ユニオン」の標準化

GraphQLには出力タイプのユニオンはあっても入力タイプのユニオンがなく、「IDで探すか、メールで探すか、どちらか一方だけ」をスキーマで表現する方法がありませんでした。誰もがフィールドを全部nullableにして、リゾルバで手作業で検証していたのです。RFC #825として数年引きずったこの問題が、@oneOfで標準化されました。

input UserUniqueCondition @oneOf {
  id: ID
  username: String
  organizationAndEmail: OrganizationAndEmailInput
}

スペックの文言そのままに、OneOf入力オブジェクトは正確に一つのフィールドだけが与えられなければならず、その値はnullであってはなりません。二つ埋めればリクエストエラー、一つをnullで埋めてもエラーです。この検証は、もうリゾルバのコードではなく、スペックレベルの入力強制(coercion)ルールです。イントロスペクションには__Type.isOneOfフィールドが追加され、コード生成ツールがユニオン型を正確に生成できるようになりました。

Schema Coordinates — スキーマ要素のアドレス体系

RFC #794は、スキーマのすべての要素に一意な文字列アドレスを与えます。

Business                          型
Business.name                     フィールド
SearchCriteria.filter             入力フィールド
SearchFilter.OPEN_NOW             enum 値
Query.searchBusiness(criteria:)   フィールド引数
@private                          ディレクティブ
@private(scope:)                  ディレクティブ引数

スペックは各要素が正確に一つの座標を持つことを保証します。些細に見えますが、これはツールエコシステムの共通語彙です — スキーマdiff、リントルール、エラーレポート、使用状況の追跡(「このフィールドを誰が使っているか」)は、これまでツールごとにバラバラの表記を使っていました。実際、エラーにスキーマ座標を含めようという後続RFCがすでに上がっています。

残り: ドキュメント説明、deprecation の拡大、全Unicode対応

  • 実行ドキュメント(クエリ・ミューテーション)にも説明(description)を付けられるようになりました(#1170)。チェンジログが明示する動機が興味深く、AIの消費者のためです — LLMがクエリの意図を把握するためのコンテキストを、ドキュメント自体に持たせようというものです。
  • deprecationがスキーマ要素全般に拡大され、ルールが整理されました — インターフェースがdeprecateしていないフィールドを実装側がdeprecateできないという制約、includeDeprecated引数のnon-null化など(#1053#1142)。
  • 言語文法が全Unicode範囲をサポートします(#849)。
  • デフォルト値の強制ルールが再定義され(#793)、実行アルゴリズムの記述が大幅に整理されました(ExecuteSelectionSetExecuteCollectedFieldsに置き換わるなど)。

全体として見れば、今回のエディションは新機能の祭典ではなく、4年分の整合性の負債の清算 + 二つの大きな言語機能(OneOf、Coordinates)です。公式発表がAI-readyを前面に押し出して包装してはいますが、実体は着実な標準整備に近いものです。

スペックに入らなかったもの — defer と stream はまだRFCのまま

ここが、このリリースで最も正直に見るべき部分です。@defer@stream — レスポンスを段階的に分けて送るincremental delivery — はSeptember 2025エディションにはありません。スペック本文を直接検索して確認しました。deferという単語自体が0回しか登場しません。2026年6月時点のワーキングドラフトにもありません。

これがどれほど古い話か感覚をつかむために言うと、graphqlパッケージのnpmレジストリには、experimental-stream-deferという実験ビルドが2020年10月から上がっており、そのdist-tagは今も2021年12月に公開された16.1.0系のビルドを指しています。Incremental Delivery RFCは現在RFC 2(Draft)段階であり — 死んではいません。この記事を書いている週にもスペックドラフトにコミットが付きました(2026-07-15)。しかし5年を超えて「ほぼ完成」だった機能だという事実は変わりません。

なぜこれほど時間がかかるのでしょうか。実行セマンティクス(重複フィールドの処理、エラー伝播)とペイロード形式を標準化する難しさもありますが、実運用データが一様でないことも一因です。GraphQLConf 2025で、Metaは@asyncという独自ディレクティブを発表し、@deferが残す隠れたコストを理由に挙げました — 世界で最も大規模にGraphQLを使う組織が、deferの代替を実験しているということです。標準化の対象そのものがまだ揺れているわけです。

実務上の含意は明確です。defer/streamを使うすべてのスタックは、今もスペック外(pre-spec)の機能を使っていることになり、ペイロード形式が変わりうるリスクを抱えます。実際に変わりました — すぐ下のv17の話です。

GraphQL.js 17 — 何が壊れ、何が良くなるか

公式アップグレードガイドが異例なほど充実しているので、ここでは判断に必要な骨子だけを取り出します。

壊れるもの

  • Node.jsの要件が^22.0.0 || ^24.0.0 || ^25.0.0 || >=26.0.0に上がります。Node 20以下に縛られた環境なら、ここで終わりです。
  • パッケージがexports条件付きエクスポートに変わります。公式のエントリポイント(graphqlgraphql/executionなど)の外のディープインポートにはsemver保証がないと明示され、廃止予定だったgraphql/subscriptionサブパスは削除されました。
  • 開発モードがNODE_ENVベースの自動有効化から、明示的なオプトイン(enableDevMode()またはdevelopmentパッケージ条件)に変わります。
  • カスタムスカラーAPIの名前が整理されます — serializeparseValueparseLiteralはdeprecatedなエイリアスとして残り、coerceOutputValuecoerceInputValuecoerceInputLiteralが新しい名前です。
  • subscribe()の戻り値の型が、固定のPromiseからPromiseOrValueに変わり、Promiseを前提としたTypeScriptコードは修正が必要です。

実行器の分離 — execute は単一結果専用に

v17の設計で最も目を引く決定は、安定機能と実験機能の物理的な分離です。execute()は単一結果専用の安定実行器になり、スキーマに@defer/@streamディレクティブがあると、そもそも拒否します。incremental deliveryを使うには、名前からして実験であることを明記した別の関数を呼ぶ必要があります。

import { experimentalExecuteIncrementally } from 'graphql';

const result = await experimentalExecuteIncrementally({ schema, document });

if ('initialResult' in result) {
  send(result.initialResult);
  for await (const subsequent of result.subsequentResults) {
    send(subsequent);
  }
} else {
  send(result); // 段階的な送信が不要だった場合
}

アルファ時代にdefer/streamをプロダクションに入れたチームにとって重要な変更: ペイロード形式が変わりました。初期アルファの形式はpathlabelでペイロードを識別し、フィールドデータが重複しうるものでしたが、現在の形式はpending項目をidで登録し、completedで完了を知らせる方式です。古い形式が必要なホストのためにlegacyExecuteIncrementally()が残されていますが、名前が示すとおり移行期間用です。スペック外の機能を先取りして使うと、こういう請求書が回ってくるという実例です。

エラー伝播の側にも実験機能が一つ入りました。@experimental_disableErrorPropagationをオペレーションに付けると、non-nullフィールドの実行エラーが親を連鎖的にnullにする代わりに、その位置だけがnullになります — 正規化キャッシュを使うクライアントで、祖先のnullが実データの更新のように見えてしまう問題を狙ったもので、進行中のエラー動作(onError)スペック議論の先行実装です。これも名前にexperimentalが刻まれています。

運用者にとって有用なもの — AbortSignal、diagnostics_channel、Harness

壊れるものだけでなく、得られるものも実質的です。

  • AbortSignalサポートが第一級機能として入りました。リクエストのタイムアウト、クライアントの接続切断、下流APIのキャンセルを一つのキャンセル経路に統合でき、リゾルバはinfo.getAbortSignal()でアクセスします。部分的なデータを作った後に中断されると、AbortedGraphQLExecutionErrorが中断理由と部分結果を一緒に公開します。
  • Node.jsのdiagnostics_channelで、パース・検証・実行・フィールドリゾルブなどのライフサイクルイベントが発行されます。APM計測がモンキーパッチなしで可能になります。
  • GraphQLHarnessで、parse/validate/execute/subscribeの各段階を差し替えられる公式な形が生まれました。発表文自身が、Envelopが実証した段階モデルに従ったと述べています — コミュニティのパターンが参照実装へ逆輸入された事例です。
  • フレームワーク作者向けに、実行パイプラインの下位境界(validateExecutionArgs()executeRootSelectionSet()など)が公開され、内部コードをコピーせずにカスタム実行器を作れます。

つまりv17の実質は、defer/streamではなくサーバー運用の表面 — キャンセル、計測、拡張ポイント — にあります。

フェデレーション標準化の現在地 — Composite Schemas は Stage 0

「連合GraphQLの標準化」を待っている方向けの状況確認です。前回の記事で扱ったApollo Federationは、あくまで一ベンダーのスペックであり、GraphQL Foundationは2024年5月からComposite Schemasワーキンググループでベンダー中立の標準を作っています。

2026年7月現在の正直な状態: スペックのリポジトリのREADMEは依然としてStage 0(Preliminary) — Draft段階前であり、内容が変わりうると明記しています。GitHubリリースは0件です。ただし、死んだプロジェクトでは全くありません — 2026年7月9日にも@key@requireルールを磨くコミットが複数マージされ、2026年5月のGraphQLConfの基調講演でThe GuildのUri Goldshteinは、フェデレーションはもはやフロンティアの実験ではなく、業界が自信を持って歩ける舗装された道になったと診断しました。実務的な結論: 連合アーキテクチャを今設計するなら、依然としてベンダースペック(Apollo Federation v2系)を選ぶことになり、Composite Schemasは「いつか乗り換えられる方向性」として追っておけば十分です。

ガバナンス面の変化も一つ記録しておく価値があります。2026年6月に発表されたGAPs(GraphQL Auxiliary Proposals)は、コアスペックが意図的に扱わない慣行 — ページネーションのコネクション、@costのようなもの — をコミュニティスペックとして集める公式リポジトリです。コアスペックは狭く、周辺の慣行はGAPsへ、分散実行はComposite Schemasへ — 標準化が三層に分化していく構図です。ちなみに同じ時期、MetaはGraphQLConf 2026の基調講演(「The Creator's Curse」)で、10年前の「学びやすく使いやすい」という約束が数千人規模のエンジニアの下では全部守られたわけではなかったと自省しつつ内部の再設計について語り、Apollo CEOのMatt DeBergalisは「GraphQL can and must be the language of AI」と宣言しました。標準は整備モード、ベンダーはAIの物語 — 温度差のある時点です。

では、いま何をすべきか

判断基準として整理します。

v17に上げる理由がはっきりしている場合

  • サーバーフレームワーク・ゲートウェイ・計測ツールを作る立場 — 実行境界API、Harness、diagnostics_channelが目的そのものです。
  • リクエストのキャンセルが実際の課題であるサービス — AbortSignal統合は、v16にはきれいな代替がありません。
  • 新規プロジェクト — 今はv17がlatestであり、ドキュメント・APIリファレンスもv17基準で再編されています。

急がなくてよい場合

  • Node 22未満に縛られた環境。エンジン要件がハードゲートです。
  • ディープインポートや内部APIに依存するカスタムコードが多いコードベース — exportsの強制と実行器の分離で、手を入れる箇所が増えます。
  • 16.xは見捨てられたブランチではありません — 2026年6月にも16.14.2のパッチが出ました。今すぐ機能に困っていないなら、周辺ライブラリのpeerDependenciesが17を受け入れるか確認してから動いても遅くありません。

defer/streamについてはより保守的に

  • 新規導入なら: スペックはまだRFC 2であり、v17でも関数名にexperimentalが刻まれています。ペイロード形式がアルファ時代に一度作り直された事実こそ、最良の警告です。ゲートウェイ・クライアント・キャッシュまで全区間が同じ形式をサポートしているか確認するまでは有効にしないでください。
  • すでにアルファ形式で運用中なら: legacyExecuteIncrementally()で時間は稼げますが、新しいpending/completed形式への移行計画を今から立てておく方がよいでしょう。

付け加えると、スキーマ設計の観点から今すぐタダで得られるのは@oneOfです。「複数のキーのうち一つで照会する」パターンの入力型を持っているなら、リゾルバの検証コードをスキーマ宣言へ移すリファクタリングはリスクが低く、クライアントの型生成の品質がすぐに良くなります。もちろんこれも、サーバー・クライアントのライブラリがSeptember 2025エディションを実装しているかの確認が先です — スペックのリリースとエコシステムの実装の間には、いつもタイムラグがあります。

おわりに

まとめるとこうです。GraphQLの標準はほぼ4年の沈黙を破ってSeptember 2025エディションで戻ってきましたが、中身は派手な新機能というより、整合性の清算 + OneOf + Schema Coordinatesという実質重視のものです。参照実装のGraphQL.js 17は、4年のアルファの末にGAとして出てきて、安定実行と実験機能(defer/stream、エラー伝播の制御)の境界をコードレベルで引きました。一方でdefer/streamは10年目に入っても標準の外にあり、フェデレーション標準(Composite Schemas)はStage 0です。

この構図は皮肉として読むこともできます — 「4年かけてこれか」。しかし逆に読む方が実務には役立ちます。このプロジェクトは、破壊的変更をスペックに入れる代わりに10年待つ方を選ぶプロジェクトであり、だからこそOctober 2021のスペックで組んだサーバーが今も有効なのです。安定性がデフォルトで、実験にはラベルが付いてやってくる — APIレイヤーの基盤技術に望みたい性質です。同じ時期にProtobufが Edition体系でデフォルトを締め付けている様子と比べてみると、両陣営とも「革新よりも移行コストの管理」へ収斂しつつあることが見えてきます。標準の速度に失望している時間があれば、@oneOfのリファクタリングとv17アップグレードの見積もりから始めてみてください。

参考資料

현재 단락 (1/99)

GraphQL スペックの最後のエディションは、長らく[October 2021](https://spec.graphql.org/)でした。その間もエコシステムは回り続けましたが — [Apoll...

작성 글자: 0원문 글자: 10,954작성 단락: 0/99