Chapter 05無料公開

Microservice Architecture

okmttdhr
okmttdhr
2020.12.07に更新

Microservice Architectureは、以下のような特徴を持つ小さなアプリケーションを組み合わせるアーキテクチャです。

  • Loosely coupled, Highly cohesive
  • 疎結合なデプロイができる
  • ビジネスドメインで境界付けられている
  • 何らかの通信プロトコルでアクセスできる
  • 自律的なチームで開発される

Microservice Architectureについて知りたい方はBuilding Microservicesという書籍をおすすめします。

ここでは、Microservicesとのコミュニケーションにおいて、フロントエンドを中心に、どのようなパターンが有るかを紹介します。

Service Discovery

Service DiscoveryはBuilding Micro Frontendsという書籍にでていますが、フロントエンド側で複数のインターフェイスを抽象化したレイヤーをつくり、バックエンドとのやりとりを行うパターンです。

といってもなんてことはなく、例えば、以下のようなJSONをイメージしてもらえるといいと思います。実際は、Repository Patternなどで、リクエストを抽象化したレイヤーを作ることもあるでしょう。

{
  "micro_service_foo": {
    "v1": "https://api.foo.service.com/v1",
    "special": "https://api.foo.service.com/special"
  },
  "micro_service_bar": {
    "v1": "https://api.bar.service.com/v1",
    "v2": "https://api.bar.service.com/v2"
  }
}

Service Discoveryの良い点は、フロントエンドでの結合を自由に行うことができる点です。Micro Frontendsの文脈では、複数のコンポーネントがそれぞれ別のMicroservicesにリクエストする場合もあります。それらをApp Shellのレイヤーで自由に変えられるのは都合がいい場合があります。

また、JSONをAPIで返してもらうようなパターンもあります。

この場合、バックエンド側でのバージョンアップや環境の変更などに対応しやすくなります。このパターンはバックエンドのMicroservicesで使われるClient-side service discoveryからインスパイアされるものです。

Gateway Aggregation

Gateway Aggregationは、複数のMicroservicesへのリクエストを、ひとつのエンドポイント(API Gateway)にまとめるパターンです(Microsoft Cloud Design Patternsより)。

Service Discoveryであったようなクライアントでの抽象化レイヤーは消えてシンプルになり、パフォーマンスのオーバヘッドも改善します。

Backends for Frontends

Backends for Frontends (BFF)は、Gateway Aggregationとも似ていますが、ある特定のフロントエンドアプリケーションごとにインターフェイスを用意するパターンです(Microsoft Cloud Design Patternsより)。

Gateway Aggregationでは、以下のような問題が発生していました。

  • 各々のフロントエンドアプリケーションがほしいデータが異なることにより、データ構築の処理が発生する
  • あるアプリでは使用しないデータがインターフェイスに足されたり、冗長な処理が増える
  • すべてのプラットフォームを考慮することによる、バックエンドAPIの更新のしづらさ

よりアプリケーションに特化したインターフェイスを用意することにより、それぞれに最適化されたやり取りを行うことがこのパターンの目的です。

Netflixの場合

Netflixでは、API GatewayにGraphQL Federationを採用しているようです。

https://netflixtechblog.com/how-netflix-scales-its-api-with-graphql-federation-part-1-ae3557c187e2

GraphQL Federationの詳細は以下を御覧ください。

https://www.apollographql.com/docs/federation/
https://www.apollographql.com/docs/federation/federation-spec/

同社では、単純なAPI Gatewayだと以下のような問題があり、

  • Gatewayチームのドメイン知識不足
  • Gatewayへのつなぎ込みが手動で行われていた
  • 上記によるGatewayチームの負荷

それを解決するために、GraphQL Federationで各スキーマをマージ、Gatewayの責任範囲を小さくするアプローチをとっています。最終的に、下記のFederated GatewayのアーキテクチャとすることでOne Graph APIを実現しています。

ドメインに精通する各Microservicesチームがそれぞれのスキーマを提供し、GatewayチームはGraphの管理に徹するという点で、自律的な開発体制を構築していると言えるでしょう。後述する「BFFを誰が開発するか?」というトピックにもつながる気がします。

メリット・デメリット

API Gatewayをつくることのトピックとして、「誰がAPI Gatewayを開発するのか?」というのがあります。例えば、BFFをつくるなら、フロントエンドエンジニアの持ち物とするのが正しい気がしますが、実際はエンジニアのスキルや開発コストとの兼ね合いにもなるでしょう。

また、処理の共通化もひとつのトピックです。BFFでは、アプリケーションに特化したロジックが置かれるべきですが、複数のBFFで重複した処理が増えてくることがあります。それらに対して、基本的にはDuplication over the wrong abstractionとしながらも、どう切り出すべきか?本当に切り出すべきか?切り出したらどのチームが責務を負うか?というのは議論のポイントとなるでしょう。呼び出すMicroservicesとLoosely coupledになるような設計も必要になってきます。

Micro Frontendsの文脈では、API Gatewayをどのレベルで結合するか?結合せずにService Discoveryを使うか?という話にもなるでしょう。

まとめ

昨今の事情に合わせて、フロントエンドからMicroservicesとやりとりをする方法を紹介しました。

複数のMicroservicesと直接やりとりするのではなく、ひとつのフロントエンド(アプリケーション)に対してひとつのインターフェイスを用意することで、複雑さを抽象化しようとする動きが見られます。