サーバサイド(Spring Boot)でGraphQLを実行する

アソビュー Advent Calendar 2020の14日目です。

アソビューでバックエンドの開発をしている上中です。

今回は表題の通り、GraphQLをSpring Bootのサーバサイドから実行することがあったため、その時の実装についてです。

というか、もっと良い方法があれば教えてください!というお話になります。

アソビューでは現在、アソビュー!ストアというECサイトを運営しており、屋内で体験を楽しめる体験キットや、アソビュー!に掲載される体験を友人や家族にプレゼントできるギフトの販売を中心に展開しています。

アソビュー!ストアはShopifyを活用しており、体験キットやギフトの商品情報や在庫、注文などのリソースはShopifyで一元管理をしています。

そのため、弊社で開発している他のシステムでShopifyで管理しているリソースが必要となる場合は、Shopify APIを利用します。

Shopify APIには大きく分けて2種類あります。詳細はここでは説明しませんが、ざっくり以下のような特徴があります。

  • StoreFront API:スマホアプリやWebのフロントエンドから利用されることを想定している。機能は限定的。GraphQLのみ。
  • Admin API:様々なリソースの利用を網羅している。ただしAPIの利用制限がStoreFront APIより厳しく、フロントエンドから実行されることに向いていない。REST APIとGraphQLがそれぞれ用意されている。

今回、サーバサイドで商品情報を参照するためにAdmin APIをサーバサイドから実行する必要がありました。今回は商品情報の一部のパラメータのみ利用したかったため、ペイロードの効率性とそれに伴うパフォーマンスの良さから、GraphQLを選択しました。

クエリを構築してみる

GraphQLと言っても利用するプロトコルはHTTP(S)であり、エンドポイントにPOSTリクエストをするだけなので、話の要点はリクエストBodyのクエリをどう構築するか、という話になります。

正直、サーバサイドの、かつJavaで利用できる良さげなライブラリを探してみるも見つからなかったので、何かいい方法があれば教えてください、という感じです。

まずは普通にクエリを書いてみます。

gist.github.com

APIの実行はRestTemplateを使います。↓
GraphQLのクエリはJSONに見えてJSONではないため、Jackson使ってオブジェクトからのクエリ文字列生成、みたいなことはできません。

となると、上記のようにクエリの中にパラメータを埋め込む、みたいな実装が思いつきますが、ORマッパーが出る前のSQLの構築みたいでやりづらい、、、

Variablesを利用してみる

GraphQLにはVariablesという仕組みがあり、上記のような問題を解決することができます。

動的なパラメータをクエリと分離し、JSONで記述できる仕組みです。Variablesを利用すると先ほどのクエリはこうなります。

↑動的なパラメータ部分を変数で定義し、それをクエリ内で利用するイメージですね。クエリをパラメータとは切り離して作成できるので、リソースファイル で管理すればクエリの構築に集中できます。

↓変数の中身をVariablesで指定します。VariablesはJSONで定義できるため、Jacksonを使ってオブジェクトから生成できます。

ということで、今回はひとまずこんな形に落ち着きましたが、今後必要なクエリが増えた時にどのように管理していくのか課題ですね。

もっと良い方法があれば教えてください!

 

さいごに

アソビュー!では一緒に働くメンバーを募集しています。
興味がありましたらお気軽にご応募ください!

www.wantedly.com