GraphQLのScalar型について調べる
GraphQLの型システム
GraphQLの型システムは、Object型、Interface型、Union型、Enum型、Scalar型がある
Scalar型は、GraphQLの型システムにおける最も基本的な型で、それ以上分解できない原子的な値を表現している
# Object型はフィールドを持つ type User { id: ID! # ← Scalar型 name: String! # ← Scalar型 age: Int # ← Scalar型 active: Boolean! # ← Scalar型 } # Scalar型はリーフノード(末端)として機能 query { user(id: "1") { id # String型の値を返す name # String型の値を返す age # Int型の値を返す } }
組み込みScalar型
GraphQL仕様で定義されている5つの組み込みScalar型
| Scalar型 | 説明 | 例 |
|---|---|---|
Int |
符号付き32ビット整数 | 42, -100 |
Float |
倍精度浮動小数点数 | 3.14, -2.5 |
String |
UTF-8文字列 | "Hello", "こんにちは" |
Boolean |
真偽値 | true, false |
ID |
一意識別子(内部的にはString) | "user_123", "550e8400-e29b-41d4-a716-446655440000" |
type Product { id: ID! # 一意識別子 name: String! # 製品名 price: Float! # 価格 stock: Int! # 在庫数 available: Boolean! # 販売可否 }
カスタムScalar
組み込みScalar型だけでは表現が不十分なケースがあるので、カスタムScalarというのを駆使する
https://spec.graphql.org/October2021/#sec-Scalars.Custom-Scalars
組み込み型の限界
# 問題のあるスキーマ設計 type Event { id: ID! title: String! startDate: String! # ISO8601形式の日時文字列のはず endDate: String! # 形式のバリデーションがない url: String # URL形式かどうか不明 email: String # メールアドレス形式かどうか不明 }
この設計の問題点:
startDateに"hello"という無効な値が入る可能性- クライアント側で毎回パースとバリデーションが必要
- スキーマを見ただけでは期待される形式が不明
カスタムScalarによる解決
scalar UUID @specifiedBy(url: "")で定義する
@specifiedByをつけるのが推奨されている
scalar URL @specifiedBy(url: "https://tools.ietf.org/html/rfc3986") type Event { url: URL # URL形式が保証される }
graphql-scalarsライブラリ
よく使用されるカスタムScalarの実装を提供するライブラリgraphql-scalarsがあるので、自作する前に導入を検討する
npm install graphql-scalars
利用可能なScalar一覧(一部)
| カテゴリ | Scalar | 説明 |
|---|---|---|
| 日時 | DateTime, Date, Time, Timestamp |
日時関連 |
| 数値 | PositiveInt, NegativeInt, NonNegativeInt, BigInt |
数値制約 |
| 文字列 | EmailAddress, URL, UUID, JWT |
形式制約付き文字列 |
| ネットワーク | IPv4, IPv6, MAC, Port |
ネットワーク関連 |
| 通貨 | Currency, ISO4217CurrencyCode |
通貨関連 |
| その他 | JSON, JSONObject, Void |
汎用 |