qiita.comはじめに現在、弥生では新しいサービスの開発を行っており、今後主流となりうる技術を積極的に取り入れる方針で進めています。本記事のタイトルにあるマイクロサービスアーキテクチャやGraphQLもそのようにして取り入れてきました。それらの技術を実際にプロダクトに適用するのは一筋縄ではいかず、いろいろな遠回りを行った末にどうにか適用できた、というのが実際のところでした。その過程については、前回12/16のもくテクにてお話させていただきました。APIのサービス群へ移行させることでした。もくテクの発表では、かなりの駆け足で移行の全体をお話ししたため、このGraphQLへの移行についてあまり詳しくご説明することができませんでした。そこで本記事では、RESTからGraphQLへ移行した過程について、少し掘り下げてご説明したいと思います。移行前のシステム構成は、以下の図のようになっていました。技術構成は以下のようになっていました。フロントエンド:Next.jsを使用。RoutesにGraphQLサーバーを立ててBFFとしている。APIとして各種機能をフロントエンドに提供。この構成において、BFFは以下のような役割を持っていました。GraphQLへのプロトコル変換を行う処理の実装が開発スピードを落としているということでした。そこで、この部分を見直し、今後の開発スピードを高める策を検討しました。移行方針GraphQLは使いたいフロントエンドとBFFの接続にはGraphQLを使用していましたが、これはそのまま使いたいと考えました。GraphQLのメリットは様々なところで語られていますが、クライアント側で取得するデータを決定できるという特徴が、やはりフロントエンドとの相性が良いということを実感していました。そこで、BFFより後ろのプロトコル変換部分を見直すことにしました。プロトコル変換は無くしたいプロトコル変換処理を作成するのは大変ですが、APIスキーマ等から自動生成を行う等の手段によって、ある程度はその労力を削減することはできると思います。プロトコル変換を行うレイヤーが存在すること自体が、開発のボトルネックになるのではないかと考えました。APIを直接提供するような構成にすることにしました。FederationGraphQLは、クライアント側から見えるエンドポイントを1つにするのがベストプラクティスとされています。APIにすることが望ましいです。Federation仕様です。Federationは、Netflixが採用したことで有名になった技術で、APIを束ねるゲートウェイが各APIの関連を理解して自動的にクエリの分配・結果の統合を行ってくれます。Federationを採用することにしました。Federationでは、各APIが他のAPIとどのように関連しているかをゲートウェイに示すために、独自のスキーマ拡張仕様が定義されています。Federationに対応したライブラリを使う必要があります。APIに置き換えていこうと思ったのですが、ライブラリの選定時点で頓挫してしまいました。C#のGraphQLライブラリで最も人気があったのはgraphql-dotnetですが、以下のような理由で我々にはマッチしていないと考えました。Firstを採用しています。Firstの方がスキーマ定義と実装との不一致が起こらないため、有効だと感じます。Firstの両方をサポートしているライブラリです。graphql-dotnet以外には実用レベルに至っていると感じられるライブラリが見つけられませんでした。APIを実装することは困難であると考えました。GraphQLC#での実装が難しいということがわかったため、他の選択肢を検討しました。GraphQLのサポートが強力なのはやはりJavaScript/TypeScriptベースのライブラリでした。FirstモードでFederation対応のAPI定義をサポートしているため、我々の要求にピッタリ合うという印象でした。docs.nestjs.comまた、NestJSを採用すれば、フロントエンドもバックエンドもTypeScriptで開発できるようになるため、1つの機能を開発する際のオーバーヘッドが削減できそうです。以上のことから、バックエンドの各サービスはNestJSを用いて開発することにしました。GraphQLのAPIに変更するということは、つまりバックエンドサービス群を新しい技術スタックでまるごと書き直すということになります。それをいきなり実行するのはリスクが高すぎるため、まずは新規機能のために開発するAPIサーバーを、この新しい技術スタックで作成してみることにしました。REST、BFF内でGraphQLへ変換)で開発していたときと比較し、機能が完成するまでのスピードが明らかに早くなったと感じました。単純に記述するコードの量が減りましたし、言語やプロトコルを頭の中で切り替える必要がなくなったので、作業効率もアップしたのだと思います。APIの実装方法に手応えを感じたため、これまでに作成してきた機能についても、新しい技術スタックへの置き換えを進めることにしました。APIを立てたものの、このAPIを既存のシステムにうまく接合することができていませんでした。この新しいAPIもBFFにぶらさげる形としたかったのですが、以下のような理由によりそれができませんでした。APIをまとめることはできるが、GraphQL以外のAPIをまとめることはできなさそうそのため、実は新しいAPIはフロントエンドから旧APIと別に呼んで、フロントエンドで結果をマージするという、かなり乱暴な暫定処置を行っていたのでした。(新しいAPIとこれまでのAPIがそれほど結びつきが強くないということも幸いし、この処置でどうにかなったのでした)しかし、このままではフロントエンドが複数のAPIエンドポイントを呼ぶ形になってしまい、複雑さが高くなってしまうのは明白です。APIに置き換えていくときに、全てのAPIを一気にGraphQLにするのではなく、APIサーバーを順番にGraphQLに書き直してシステムに接合していけるような方法が採れないと、移行のリスクが高くなってしまうと考えました。APIをまとめるサーバー」の2段構成にするアイデアでした。APIへ置き換えていきました。APIを提供していました。Gateway)として動作させるようにしました。Routesに配置します。APIだけが見える状態になります。APIとしては変化しないということになります。APIサーバーに書き直して、順次システムに接合する、ということが可能になります。Serverが必要なくなります。Gatewayがほとんど同じことをやっているため、これらを1つにまとめたいです。Gateway(名前が紛らわしいですね)を配置するようにします。ここまで実施すれば、GraphQLなマイクロサービス構成への移行が完了です。まとめこうして振り返ってみると、なんだか非常に遠回りをしたような気がします...。結果としてすっきりした技術構成へ移行することができましたし、移行過程でGraphQLまわりに関する知見を深めることができたと思います。この記事が、GraphQLへの移行を試みる方の参考になればうれしいです。Interface」を使ってRESTクライア...こんにちは、情報システム部エンジニアの小坂です。Mi...2020-12-11君のプログラミング言語は輝いているかこんにちは、Misoca開発チームの黒曜(@kokuyouwind)です。今年もアドベ...2019-11-21木曜の夜はもくテク!!(Misoca冬のLT大会のご案内)こんにちは。弥生は第23回Quesに協賛します。引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。