この記事は GraphQL Advent Calendar 2021 の21日目の記事です。
こんにちは、プレックスの ij_spitz です。
久しぶりのブログ更新になってしまいましたが、アドベントカレンダーに登録することによりブログを書かなくてはいけない環境を強制的に作り出して、なんとかこの記事を書いています。
弊社では半年ほど前から新規事業の開発をGraphQLを使って進めているので、今回はそれの振り返りと失敗談を書いていきます。
自分も社内のメンバーもGraphQLの採用は初めてだったので、かなり初歩的なミスも犯してきたと思いますが、少しでもこれからGraphQLを採用する皆さんの参考になれば幸いです。
振り返り
GraphQLを採用して一番大きな問題となったのは、やはり学習コストがそれなりに掛かることでした。
新規事業を立ち上げる場合、エンジニアでもそれなりの事業ドメインのキャッチアップやリサーチなどのタスクをやっていく必要があると思います。そういった中で技術自体のキャッチアップもしていくとなると、なかなか学習に掛ける時間が取れなくなってしまいます。
実際自分も入社してすぐに新規事業を担当することになったのですが、入社から1ヶ月くらいは、人材紹介をしているメンバーの音声を聞いたり、物流業界についてのインプットを増やしたりと技術以外の学習に使っていた時間の方が多かったです。
加えて幸か不幸か、GraphQLは既存のRest APIを代替しているものなので、GraphQL特有の知識がなくチュートリアルを少々やった程度の理解でも、Rest APIの感覚でそれなりに開発ができてしまいます。
それによって後々修正する点が出てきたり、GraphQLの旨みがあまり活かせないと感じることが多々ありました。
自分たちがGraphQLを採用したことは後悔しておらず、今は良かったとは思っていますが、今回の教訓として得られたことは、新規サービスだから新しい技術を安易に採用するのは良くないということです。
GraphQLもAPIの技術の一種でエンドポイントごとに導入したりすることもできるので、既存の安定稼働しているサービスの方が導入はしやすいのではないかと思っています。
失敗談
次に具体的な自分たちのやらかしてきた失敗談を3つ紹介していきます。
スキーマ設計
まずGraphQLの一番の肝となるのがこのスキーマ設計です。しかしながら厄介なことに、最低限のインプットで開発を進めていると、自分のスキーマ設計が正しいのかどうかもわからないまま開発を進めることになります。
自分もそういった状態で開発を進めていたのですが、Youtubeに公開されている六本木GraphQLという勉強会のアーカイブ映像を見て、良くないスキーマ設計をしていることに気づきました。
そうならないためにもGraphQLを始める場合は、スキーマ設計についてインプットを意識的に増やしたり、知見のある人に聞いてみるなどをおすすめします。
スキーマ設計については上記の動画以外だと、以下の情報を参考にしたりしていました。
- GraphQLスキーマ設計ガイド 第2版
- 上記の勉強会でスピーカーを務めているvvakameさんの本
- Shopify GraphQL Design Tutorial
- ShopifyによるGraphQL設計のチュートリアル
- GitHub GraphQL API
データローダーを使っていなかった
GraphQLではN+1問題が起きやすい構造になっているため、それを解決するデータローダーという仕組みがあります。
弊社ではRailsでGraphQLを使っているため、リレーションが貼ってあれば特に気にせずに関連するモデルを読み込めていたので、データローダーの存在は意識せず、開発を進めていました。
もちろんN+1が起きていたことは把握していたので、preload等のRailsの機能を使って回避していました。しかしその方法で対処してしまうと関連するモデルの呼び出しが必要のないところでも、不必要にpreload等が走ってしまってしまうので、データローダーを使うべきでした。
Rubyにはgraphql-ruby標準のデータローダーもありますが、スターの数が多く、使いやすいと感じたgraphql-batchを使っています。
ApolloClientのキャッシュについての理解が浅かった
これはGraphQLではなくてApolloClientの問題ですが、ApolloClientを使ってる方は多いと思うので紹介させてもらいました。
ApolloClientにはキャッシュの機構が用意されており、特に何も考えずにGraphQLを叩いているとよしなにキャッシュして使ってくれます(便利!)。
しかし、キャッシュの管理は自分でやらなくてはならないため、Mutationでレコードの変更や削除などを行うと、何らかの方法でキャッシュを変更したり、キャッシュを使わないように設定を変更したりする必要があります。当時の自分はこれをあまり理解しておらず、ApolloClientのfetchPolicyでno-cacheを多用してしまっていました。
no-cacheを使うこと自体は悪くないのですが、キャッシュを使って問題ない箇所ではできるだけキャッシュを使いたいので、適材適所で使う場所を選ぶことが大事です。以下の3つがMutation後にも変更されたデータを正しく取得する方法で、このような具合で使い分けをしています。
- refetchQueriesを使って、クエリを再取得してキャッシュを更新する
- クエリを指定すれば自動でキャッシュ更新を掛けてくれるので楽
- 個人的にはこれを1番はじめに使うことを考える場合が多い
- キャッシュを手動で更新
- 記述量が増えるのと、若干わかりづらいのであまりやりたくない
- fetchPolicyを変更して、キャッシュを使わないようにする
- 基本的にキャッシュを使いたいので、あまりいじらない方がいい
- ただ多数のユーザーから更新される可能性があるレコードなどの場合は別
おわりに
今回は新規事業でGraphQLを採用した振り返りとやらかしてきた失敗を紹介させていただきました。細かい点まで広げると失敗談はもっとたくさんあるのですが、個人的にこのあたりは多くの人がハマってしまうんじゃないかなという3点をピックアップしました。
自分もGraphQLについての理解はまだまだだなと感じるところがたくさんあるので、これからも勉強しつつ、発信の方もできればなと思っています。今後ともブログなどご覧いただけると嬉しいです!