GitHubのGraphQL API v4にて、EmailのScalar型を定義していない理由を考察してみた

GitHubのAPI v4は、GraphQLで開発されている。バックエンドの開発者で参考にされることが多い。

GraphQLは、StringやIntなどビルドインのScalar型以外に独自定義を行うことで型安全なAPIを開発することができる。

GitHubのAPIにおいても多くのカスタムScalars型が定義されている。

少しドキュメントを眺めてみるとRFCやISOなど比較的変更が起こりにくいものに依存して型を定義していることがわかる。

しかし、UserオブジェクトのEmail Filedの型にはStringが利用されている。

そこでタイトルの通り、GitHubのGraphQL API v4にて、EmailのScalar型を定義していない理由を考察してみた。

考察

RubyにおけるEmailのバリデーションは、以下の通りである。

URI::MailTo::EMAIL_REGEXP

EMAIL_REGEXP = /\A[a-zA-Z0-9.!\#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\z/

https://github.com/ruby/ruby/blob/ruby_2_7/lib/uri/mailto.rb#L56

しかし、愚直に利用すると思わぬ失敗を招いてしまうことがある。

これについては、その正規表現、意義ありの資料が参考になる。

Railsというフレームワークを用いた開発では、Deviseという認証系のライブラリが頻繁に利用される。実装は以下の通りだ。

@@email_regexp = /\A[^@\s]+@[^@\s]+\z/

https://github.com/heartcombo/devise/blob/5-rc/lib/devise.rb#L116

議論からEmailバリデーションの困難さが窺える。

最初に、以下のように述べたがEmailは実装が安定していないことからGitHubではカスタムScalar型を定義していないのではないかと考えた。

RFCやISOなど比較的変更が起こりにくいものに依存して型を定義している

この考えは、Shopifyのスキーマ設計チュートリアルでも述べられる。

Use weaker types for inputs (e.g. String instead of Email) when the format is unambiguous and client-side validation is complex. This lets the server run all non-trivial validations at once and return the errors in a single place in a single format, simplifying the client.

まとめ

GitHubのGraphQL API v4にて、EmailのScalar型を定義していないを理由を考察した。

Emailは、実装が安定していないためカスタムScalar型を定義すると複雑性をアプリケーションに注入することになる。

初めてのGraphQL ―Webサービスを作って学ぶ新世代API

初めてのGraphQL ―Webサービスを作って学ぶ新世代API