athome-developer’s blog

不動産情報サービスのアットホームの開発者が発信するブログ

API Gatewayを用いた、サーバーレスマイクロサービスでのAPI実装

初めまして、Cシステム開発グループの清水です。

2022年入社で、今年で2年目になります。
普段の業務では主に、AWSPythonを用いて不動産情報サイト アットホーム(以下ポータルサイト)の基盤周りの開発や、バッチ処理の開発を担当しています。


さて、皆さんはポータルサイトをご覧になったことはあるでしょうか?
ポータルサイトは、全国6万店以上の不動産会社からお預かりしている250万件の物件情報(2023年10月10日時点)など膨大な量のデータを管理しているとても大きなサイトです。
そんなポータルサイトですが、サービス開始から長い年月が経つので、時代に合ったデザインや操作性にするべく、リニューアルプロジェクトを進めることになりました。

そこで今回は、ポータルサイトがリニューアルで目指す「マイクロサービス化」について、そしてリニューアルの一環で、ポータルサイトの「家賃・価格相場ページ」をリプレースした際のお話と、その背景にあるアーキテクチャ選定のお話をしていきたいと思います。


ポータルサイトで採用しているアーキテクチャ

冒頭でもお伝えしましたが、ポータルサイトはリニューアルを経て、サイトを「マイクロサービス化」することを目指しています。「マイクロサービス化」は、システムを「マイクロサービスアーキテクチャ」で構成することで実現することができます。

また、今回リプレースすることになった相場サイトを含むサブシステムでは、「サーバーレスアーキテクチャ」というアーキテクチャを採用することになりました。

まずは、これらのアーキテクチャについての説明と、なぜ採用したのかを説明します。

マイクロサービスアーキテクチャとは

まずは、マイクロサービスアーキテクチャについてです。

マイクロサービスアーキテクチャは、モノリシックアーキテクチャの対となるようなアーキテクチャになります。
モノリシックとは、アプリケーション内に必要な機能が全て内包されており、一枚岩のようになっているアーキテクチャのことです。機能同士は密結合になっており、機能間の依存性は高くなる傾向にあります。

一方、マイクロサービスアーキテクチャは、アプリケーションに必要な機能ごとに「マイクロサービス」として分割されており、マイクロサービス同士がAPIを通じて連携することでアプリケーションを構成しています。 各マイクロサービスでは単一の機能を有しており、それぞれにデータモデルを持っており、マイクロサービス間の依存性は低くなっています。

では、マイクロサービスアーキテクチャにはどのようなメリットがあるのでしょうか?

①障害耐性が高い
機能ごとにマイクロサービスとして独立しているので、その機能で障害が発生してもアプリケーション全体に影響を及ぼさずに済みます。 また、障害発生時に、その機能のみを停止してメンテナンスできる点でも可用性が高いと言えます。

②開発に使用できる技術選択の幅が広がる
マイクロサービスアーキテクチャでは、機能ごとに開発を行うので、その機能の特性に適した言語や技術を選択することができ、開発する際の柔軟性が高くなります。

③開発単位が小さくなる
機能ごとに開発を行う関係上、企画→開発→テスト→リリースの1サイクルが小さい単位になります。そのため、新規サービスを早いサイクルでリリースしていくことが可能となり、アプリケーションの鮮度を保つことができます。

④機能単位での再利用が可能
新規にサービスを開発する際に、既存のマイクロサービスのAPIキーを払い出すことで、使いたい機能を簡単に再利用することができるので、開発工数を縮めることができます。

主に、これらの素晴らしいメリットがあるマイクロサービスアーキテクチャですが、もちろんデメリットも存在します。
機能間のデータのやり取りの際、API通信を使用する関係上、通信オーバーヘッドが発生してしまうことや、機能ごとにデータモデルをもつことで、機能間でのデータのやり取りの際にデータを整形しなければならないなど、モノリシックのメリットを失ってしまいます。

ポータルサイトリニューアルでは、サイトが大きく徐々にリプレースを進めなければならない点や、耐障害性の高さ開発した機能が再利用可能といったメリットを考慮し、アーキテクチャとして採用しています。

サーバーレスアーキテクチャとは

次に、サーバーレスアーキテクチャについてです。

何かしらの開発を行う際に、必ず考えなければならないことが「サーバーのプロビジョニングや運用、冗長化、セキュリティー対策などのインフラストラクチャ(以下インフラ)に関する事柄です。
これらにかかる開発工数は少なくなく、負担になってしまいます。

そこで、クラウドサービスで提供されている、フルマネージドのサーバーレスサービスを開発に利用することで、インフラ面でのさまざまな考慮・負担を軽減しよう、という方針のアーキテクチャがサーバーレスアーキテクチャになります。

これによって、開発者が機能の実装に集中できるようになり、開発効率の向上が見込めます。
また、サーバーレスサービスは、使用した分だけ料金を支払う「従量課金制」であるため、常時稼働していなければならないオンプレのサーバーよりもコスト面で優れているというメリットもあります。

ただし、特定のクラウドサービスのサーバーレスサービスを利用することになるので、ベンダーロックインとなってしまい、システム構築後に他のクラウド環境に移行することが難しくなります。
また、利用するクラウド環境によってサポートされている言語や開発環境に縛られる、というデメリットもあります。

そんなサーバーレスアーキテクチャをリプレースに採用した理由として、やはり、インフラ面での負担軽減というのが大きく、また、フルマネージドのサービスが多く、若手の技術者でも容易にリリースすることができる敷居の低さといったものが挙げられます。

この、サーバーレスアーキテクチャを、マイクロサービスアーキテクチャのマイクロサービスに適用したものが「サーバーレスマイクロサービス」であり、相場サイト含むポータルサイトのサブシステムの構成となっています。

API Gatewayを用いたAPIの実装

これまでは、ポータルサイトリニューアルのアーキテクチャ、さらに、相場サイト含むサブシステムのアーキテクチャについて説明してきました。
ここからは、実際に私が、相場サイトのAPIAPI Gatewayを用いてサーバーレスで実装したことについて、流れを追って説明していきたいと思います。

しかし、そもそもAPI Gatewayとは?となると思いますので、まずはそちらから説明させてください。

API Gatewayとは

API Gatewayとは、Amazon Web Serviceで提供されている、APIに関するフルマネージドのサービスです。
APIに関するさまざまな機能を有しており、

などの機能をサーバーレス環境で利用することができます。

このAPI Gatewayを利用することで、APIを簡単に実装することができ、私もこれらの機能を活用してAPIを実装することができました。
それでは、実際に私が作業したAPIの実装手順を見ていきましょう。 ※手順をもとに個人のAWSアカウントで試される際は、請求にご注意ください。

API実装手順の紹介

ステップ1:APIの定義

まずは、APIの定義をするところから始めていきます。
今回はRESTful APIを採用しているので、各URIごとにアクセスパターンを洗い出し、アクセスパターンごとにどのHTTPメソッドが必要かを割り出します。

そのアクセスパターンを元に

  • どういったパラメータでAPIにリクエストがくるのか
  • クライアントにレスポンスする際のデータ形式
等をYAMLファイルに記述していきます。

このYAMLファイルがそのまま、このAPIの仕様書となるので、この段階で必要な設定や情報をすべて記述しておく必要があります。

ステップ2:APIのデプロイ

次に、先ほど定義したAPI仕様書を元に、APIをデプロイしていきます。

API Gatewayでは、コンソール画面上でのAPI作成や、AWS SAMのコマンドラインで直接デプロイするなど、さまざまなデプロイ方法をサポートしています。
今回は、プロジェクトに必要なAWSリソースをCloudFormationでスタックとして作成・管理しているので、他のリソースと一緒にAPI Gatewayのリソース情報も含めデプロイしていきます。

APIが作成されると、API GatewayのコンソールにAPIの情報が表示されるようになります。 この作成されたAPIが、マイクロサービスとしてのアクセスエンドポイントとなり、データのやり取りを担うことになります。

APIの情報を更新したい際は、コンソールから直接パラメータや設定を変更することもできますし、修正したAPI仕様書を再デプロイすることでも更新できます。

ステップ3:APIエンドポイントの作成

さて、APIを作成できたので、次にAPIエンドポイントを作成していきましょう。

今回はサーバーレスアーキテクチャを採用しているので、

  • イベント駆動である
  • 関数単位での処理を実行する

という特性を満たすために、API仕様書に記述しておいたアクセスパターンごとに、Lambda関数をAPIエンドポイントとして作成していきます。
各エンドポイントに設定されたLambda関数にプログラムを記述しデプロイすることで、エンドポイントURLにリクエストがあった際に関数がイベント実行され、処理を実行するようになります。

その際、必要であれば、データストレージにS3、データベースにDynamoDB、キューにSQSなど他のさまざまなサーバレスサービスと連携し、ビジネスロジックを実現させていきます。

ステップ4:APIのテスト

エンドポイントを実装したことで、APIはリクエスト/レスポンスができる状態になりました。
しかし、APIをリリースするためには、正常にAPIが動作するかを確認しなければなりません。
そこで、仮のアクセスパターンを想定し、実際に作成したAPIにリクエストを実行しテストしてみましょう。

今回テストする想定ケースはこちらになります。

まず、クライアントが、「所在地が東京都」で「物件IDが0001」の物件情報が欲しい、とAPIにリクエストを送ります。
APIは、それらの受け取った情報をエンドポイントであるLambda関数に伝え、関数を実行します。
Lambda関数が処理を実行し、処理結果を指定のフォーマット(今回はJSON型)でAPIに返却し、APIはそれをクライアントにレスポンスする、という流れです。


では、このテストケースでテストを実施していきましょう。

API Gatewayのコンソールには、メソッドごとにテスト画面が用意されており、ここに必要な情報を記入することでテストを実行することができます。 クエリ文字列にリクエストデータを、ヘッダーに必要な情報を記入しテストボタンをクリックします。

すると、APIが実行され結果が表示されます。 ここで、

  • そもそもレスポンスは返ってきているのか
  • 返ってきたデータは正しいものかどうか
  • レイテンシーが異常に高くなっていないか
などを確認し、問題がなければ無事にテスト完了となります。

ステップ5:APIの公開

APIのテストが問題なく終了すれば、いよいよAPIを公開していきます。

ただし、誰にでも公開するわけにはいきません。公開する範囲に制限を設けないと、悪意のある攻撃者に狙われてしまうかもしれないからです。

そこで、上記の問題を解決するために、APIキーという認証キーをAPIに設定していきます。 APIキーを設定することで、APIキーを知っているクライアント、つまり安全なクラアントからのみアクセスを可能にすることができるのです。

まずは、API GatewayのコンソールからAPIキーの作成を選択しキーを作成します。
次に、使用量プランを作成し、そこに用意したAPIキーを設定します。
使用量プランとは、APIキーに対してクォータ、レート、バーストを設定できるものです。 これらをAPIキーに設定することで、APIに対する異常な大量アクセスなどを防ぐことができます。

この使用量プランと作成したAPIを紐づけ、クライアントにAPIキーを払い出すと、クライアントがAPIにアクセスできるようになります。 これらの一連の流れを経てAPIの公開が完了すると、マイクロサービスのエンドポイントが実装完了となります。

まとめ

いかがでしたでしょうか。
今回は、ポータルサイトのリニューアルや、サブシステムのリプレースに採用されているアーキテクチャの説明と、API Gatewayを用いたAPI実装手順をご紹介させていただきました。

私は、今回のプロジェクトで初めてAPI実装することになりました。
最初は、API Gatewayについてあまりよく分からないまま作業していたのですが、APIの定義→デプロイ→開発→テスト→公開と、一連の流れに沿って作業していくことで、API Gatewayに対しての理解を深めることができました。
また、作業する中で、細かい設定やチェックなどを簡単に実装できるAPI Gatewayの便利さに驚かされもしました。

そして、システム開発の背景あるアーキテクチャについて理解することで、システム全体を俯瞰できたことや、アーキテクチャの特性を理解し、システムに最適なアーキテクチャを選定することの大切さ・難しさを知ることもできました。

今回経験できたことは、自分がシステム設計を担う機会が訪れた際に役立つものだと思うので、ぜひ今後の開発に活かしていきたいと思います。
また、他にも興味深い技術について、ご紹介できそうなことがあれば記事にしたいと思います。
最後までお読みいただき、ありがとうございました。