GraphQL SDL

TypeScript

このコンバーターでできること

GraphQL のスキーマがあって、フロントエンドは TypeScript。その間のどこかで、スキーマとフィールド単位で一致する型一式が必要になり、しかも今すぐ欲しい — 5 分の codegen ビルド待ちでもなく、新規プロジェクトに graphql-code-generator をセットアップしてからでもなく、ジュニアにどのプラグインを入れるか説明してからでもなく。左パネルに GraphQL SDL を貼ると、右パネルに慣用的な TypeScript が返ります:object 型と input 型は interface、enum は enum、union とスカラーはシンプルな type エイリアスです。

マッピングは TypeScript コードがおおむね期待するルールに従います。組み込みスカラーは TypeScript のプリミティブ相当に対応します:StringIDstringIntFloatnumberBooleanbooleanDateTime のようなカスタムスカラーは既定で string になり、後で広げ忘れないように // custom scalar マーカーが付きます。non-null フィールド(name: String!)は必須プロパティとして出力し、nullable フィールドは ? 修飾子付きで出力します。リスト型 [Order!]!Order[] になります。type Order implements Nodeinterface Order extends Node になります — GraphQL の interface 関係は TS の構造的拡張にきれいに対応します。

アップロードなし、ネットワークなし、AI なし。変換は手書きの SDL トークナイザーでクライアント側で実行されます — スキーマはページの外に出ません。社内スキーマや公開前のスキーマを扱うときに欲しいのはこの動作です。

使い方

3 ステップ。変換は自動で走ります — 変換ボタンはありません。

1

貼り付け、アップロード、またはサンプル読み込み

左の GraphQL SDL パネルに SDL を貼り付けます。タイプを止めた瞬間に右パネルが更新されます。.graphql / .graphqls / .gql ファイルなら アップロード、リアルな EC スキーマを読み込むには サンプル をクリック。SDL の小片はこんな感じです:

type Order implements Node { id: ID! placedAt: DateTime! status: OrderStatus! items: [OrderItem!]! } enum OrderStatus { PENDING PAID SHIPPED DELIVERED CANCELLED }

サーバー側スタイルのスキーマ(extend type Query 付き)も、単独の型定義もどちらも動きます。ブロック文字列の説明("""...""")は拾われ、生成型の上に JSDoc コメントとして出力されます — これは GraphQL のリファレンス実装が文書化している慣例です。

2

生成された TypeScript を読む

右パネルは型を種類別にまとめて出力します:まずスカラー、次に enum、union、interface、input 型、最後に object 型。各グループ内では定義はソース順を保つので、手書きの型との diff は最小になります。SDL にパースエラー(中括弧の不整合、未終端のブロック文字列など)があると、出力パネルは例外を投げる代わりに // Invalid GraphQL: ... という単一のコメントを表示します — Apollo Server が起動時のパースに失敗したときと同じパターンです。

3

コピーまたはダウンロード

コピー を押すと、プロジェクト内の schema.types.ts ファイルにそのまま貼り付けられます。ダウンロード を押すと .ts ファイルとして保存できます。出力はプレーンテキスト — モジュールの import なし、ランタイムコードなし — なので、フロントでもバックでも、どんな TS プロジェクトにも入ります。

実際に使う場面

codegen を立てずにサクッと型が欲しい

既存の GraphQL エンドポイントに対してフロントを試作中で、たった 3 つのクエリの型のためだけに codegen のフルパイプラインを立てたくない。スキーマを貼り、出力を types.ts にコピーして、プロトタイプを出す。プロジェクトが本物になったら、後でちゃんとした codegen パイプラインに切り替えればいい。

codegen の出力を事前確認

スキーマに新しい型を追加する前に、提案中の SDL をここに貼って、TypeScript 呼び出し側がどんな形になるかを見ます。SDL では読みやすかったフィールドが、不格好な TS を生むことがあります — オプショナルな nullable のリスト、TS の予約語と衝突する値を持つ enum など — PR をマージしてから気づくよりここで気づくほうが圧倒的に安いです。

TypeScript 中心のチームにスキーマを共有する

TS ファーストのチームを GraphQL API にオンボーディング? スキーマを貼って、生成された型を Wiki にコピーします。TS の interface で考えるエンジニアは、生の SDL より TS ビューのほうが速くスキーマを把握できます — データ形状は同じで、構文は彼らが毎日読み慣れているものなだけです。

GraphQL エンドポイントを叩く使い捨てスクリプト

一度きりの CLI、Node スクリプト、管理タスク — codegen をきっちり組まずにレスポンスに型を付けたいような場面ぜんぶ。貼り、コピーし、レスポンスに型を付け、スクリプトを動かす。使い捨てだけど、自分が恥をかかない程度には型が付いている状態です。

よくある質問

オペレーションの型(Query / Mutation の結果型)も生成しますか?それともスキーマ型だけ?

スキーマ型だけです — SDL で宣言された型のみ。オペレーションの結果型はクライアントが実行する具体的なクエリやミューテーションに依存するもので、それはまさに graphql-code-generator と typed-document-node プラグインの仕事です。このページはスキーマ側の半分をカバーします:SDL 内のすべての typeinterfaceenuminputunionscalar が TS の宣言になります。

nullable と non-null フィールドの扱いは?

non-null フィールド(name: String!)は必須・非オプショナルな TS プロパティとして出力されます:name: string;。nullable フィールド(name: String)はオプショナルとして出ます:name?: string;。出力はクリーンに保たれます — そこら中に | null ユニオンを撒き散らしません — これがほとんどの利用側にとって望ましい形です。strict null checks のスタイルが好みなら、出力に対して find-and-replace をかけてください。

[Order] や [Order!]! のようなリスト型は?

リストは TS の配列になります。[Order!]! は必須フィールド上で Order[] として出力されます。[Order] はオプショナルフィールド上で Order[] として出ます。要素レベルの nullability は可読性のために潰されます — 残したい場合は、生成された T[] を手で (T | null)[] に変えればよいですが、実務では内側の nullability を別個に読むコードベースはほぼ皆無です。

カスタムスカラーはどう扱われますか?

カスタムスカラー(IDStringIntFloatBoolean 以外すべて)は既定で string になり、見つけやすく広げやすいように // custom scalar マーカーが付きます。DateTime スカラーなら string | Date に広げてもいいですし、JSON スカラーなら unknown や型付きの形に広げてもいいです。既定の string は、ほとんどのサーバーが JSON でワイヤー越しに送るものと一致します。

スキーマはサーバーに送られますか?

いいえ。変換は完全にブラウザ内で動きます — SDL はクライアント側でトークン化され、TypeScript の出力は右パネルに直接描画されます。何もアップロードされず、何もログされません。社内や未公開のスキーマを貼っても安全です。

出力を貼り戻したら同じ SDL に戻りますか?

いいえ — そういう設計でもありません。出力は TypeScript で、別言語です。TS の出力を SDL パネルに貼り直すとパースエラーになります。GraphQL の SDL 自体を整形したいなら、下にリンクされている GraphQL Formatter を使ってください。そのために作られています。

その他の GraphQL ツール

型生成は一部にすぎません。GraphQL ワークフローの残りはこれらのツールでカバーできます: