GraphQL vs OpenAPI スキーマ駆動開発比較

今回はGraphQLとOpenAPIの開発を比較していきたいと思います。 筆者は本業のプロジェクトでGraphQLを、副業でOpenAPIを使用しています。

アプリケーション開発時にどちらを選定するか迷っている方の参考になれば幸いです。

使用技術概要

GraphQL OpenAPI
バックエンド Go Go
フロントエンド Next.js Next.js
バックエンドコードジェネレーター gqlgen oapi-codegen
フロントエンドコードジェネレーター graphql-codegen openapi-generator
状態、キャッシュ管理 ApolloClient Redux(予定)
DB DynamoDB MySQL
使用期間 8ヶ月 3ヶ月

プロジェクトはいずれも新規開発(SaaS)でモノリスアーキテクチャです。gRPCも比較対象としてよく挙げられますが未経験の為触れません。 SPAのアプリケーション開発という視点で比較したいと思います。


GraphQL vs OpenAPI

結論から言うと私はGraphQL推しです。特にフロントエンド開発においてはかなりメリットがある印象です。

まずフロントエンド開発においてGraphQLに軍配が上がる理由はApolloClientRelayといった強力なライブラリがある事です。(Relayは未経験)

ApolloClientはライブラリ内にキャッシュ管理機構、GraphQLスキーマからのhooks自動生成(ジェネレータ)など強力な機能がたくさんあります。コールバック関数も豊富で自前実装する箇所はとても少ないです。Redux使うかどうかという議論なしに丸っとApolloClientに丸投げできます。またGraphQLなら複雑なデータも一つのリクエストで取得することができます。

OpenAPIにもコードジェネレータはありますが、APIをfetchするコード部分のみです。TypeScriptの型が使えたり、axiosかfetchAPIを選べたりしますがあくまでも最低限の機能という感じです。

以上の理由からフロントエンド開発者としてはGraphQLを推したくなります。

一方でGraphQLにはいくつか問題があります。まずは学習コストがそれなりに高いです。OpenAPIはRESTfulさえ理解できればスキーマ定義(yaml)はそこまで難しくない印象があります。GraphQLはというととにかく新しい用語が多いです。(Mutation,Resolver, Fragmentsなどなど) また、OpenAPIに比べてバックエンド側のコード量は多くなる傾向にあると思います。柔軟にAPIを生やすことができるので極端に言うとどんなリソースでも無限に(簡単に)表現できてしまいます。RESTfulというプラクティスがあるのに対しGraphQLのAPI設計はこうあるべきという指標はまだ少く、設計をちゃんとしないと同じようなAPIがたくさん生えたり、あとから実装しようと思って定義していたAPIを結局使わなかったという事があります。

ざっくりですが以上が両者の比較です。

結局どちらを採用したいかでいうと、リッチなUIが求められる程GraphQLの方がメリットが多のではないかと思います。ApolloClientはフロントエンド開発者にとって学習コストに対して余りある恩恵が得られると思っています。比較的にシンプルなWebサービスAPI単体で提供する場合にはOpenAPIの方が良いと思います。

スキーマ駆動開発比較

次に前章でも軽く触れましたが、両プロジェクトで使ったコードジェネレーターやクライアントツールを元に開発フローを比較紹介したいと思います。

GraphQL

クライアントツール

ドキュメントGUI

  • gqlgenのplayground

GoでGraphQLサーバーを立てる時はgqlgenというパッケージを使用しています。

大まかな開発フローは以下です。

バックエンド

  • .graphql ファイルにスキーマ定義
  • cliでコード生成
  • 生成されたResolverを実装する。

フロントエンド

  • codegen.yml に設定を記述(Apolloとの連携)
  • cliでコード生成
  • UI実装

gqlgenにはplaygroundという機能があり、エンドポイントを指定するとlocalhostGUIを起動してAPIを試すことができます。 このプロジェクトはフロント, バックエンド一貫して開発しているのでmockサーバーは立てていませんが、graphql-fakerというライブラリがあるようです。

OpenAPI

次にOpenAPIです。

ジェネレーター

クライアントツール

大まかな開発フロー。

バックエンド

  • .yaml ファイルにスキーマ定義
  • cliでコード生成
  • 生成されたControllerを実装する。

フロントエンド

  • cliでコード生成
  • UI実装

こちらのプロジェクトではフロントチームとサーバーチームで別れて開発をしているのでprismでモックサーバーを立てています。クライアントツールは個人的にはvscodeを使っていますが、他にもたくさんあるので各々好きなものを使っている感じです。


以上が両者の開発フローです。

今のところ大きく異なる点は無いです。gqlgenではスキーマファイルの分割とコード生成の設定が複雑だったりしますが、OpenAPIにもかゆいところに手が届かないという事はよくあるので細かい設定でのメリデメは相殺されると思います。

GraphQLのplaygroundはQuery, MutationのAPIを叩くまであまり慣れませんでしたが、スキーマからドキュメントを生成してくれたり、argsを変数で設定できたりと機能自体はOpenAPIのクライアントツールよりリッチかもしれません。

スキーマ開発のメリットとしては、ドキュメント管理のコスト削減、コード(型)の自動生成、フロント・バックエンドの開発速度向上が挙げられると思いますが両者とも同じ恩恵を享受できると考えていいと思います。

まとめ

これまでの開発で使用した技術を比較してきましたが、もし筆者が0から個人開発をするとしたらGraphQLを採用したいというのが本音です。しかしチーム開発となるとフロント, バックいずれもかなり学習コストがかかります。それを許容できるのであればGraphQLの導入を一度考えてもいいかもしれません。

今回は以上です。 最後に、 このブログではweb開発について発信していくのでまたご覧頂けると嬉しいです。 最後までお読み頂きありがとうございました。