🌃

Check! ぼくがこれから小さなサービスを作るなら on Azure

2020/12/06に公開

Prologue

Code Polaris アドベントカレンダー 第一日目のエントリーです。(執筆時点ですでにもう過ぎています、ごめんなさい _(:3」∠)_

Code Polaris では、コミュニティに集うメンバーで一緒に開発してみよう!という企画を進めています。細かな経緯は Epilogue をご覧ください🌱

今回は発起人の私主導でベースを決めることになったので、そこで考えた構成をまとめてみます。なお、私が普段から Microsoft Azure を利用しているので、ここでも Azure を利用します。

なお、この記事は、スキルセットやレベルが異なる広い層を想定して書いているので、ふわっとした内容になっています。ご了承ください🙏

これから小さなサービスを作るなら

今回の想定は、下記の要件を満たしたいとします。

要件 検討事項
手軽に使いたい ウェブサービスでの提供
小規模だが独自の処理が必要 バックエンドのコンピュートが必要。小規模なら FaaS で事足りそう
ユーザーごとにデータを保持したい 認証機構とデータベースが必要
できるだけコストは抑えたい 腕の見せどころ

フロントエンド + API のシンプル構成

  • フロントエンドとバックエンド(API)の実装を分ければ分業しやすい
  • API での実装は、ビジネスロジックに専念しやすい
  • フルスタックのフレームワークを使わず軽量な実装も選択できる
  • インタラクティブな UI は API と相性が良い
  • コストを抑えやすい
  • スケールしやすい
  • UIの刷新やクライアントのバリエーションを展開しやすい

いつのころからか、この構成以外に考えられなくなりました😳

FaaSの充実と、フロントエンドのフレームワークの充実。これらの2点により、柔軟でスケールしやすい フロントエンド + API の構成が普及してきているように思います。

コストを抑えやすい

フロントエンドとして扱う静的サイトのホスティングは、動的サイトのそれに比べて安価に済ませやすいです。

静的サイトのホスティングサービスは、 NetlifyVercel などの専属のものから、AWS AmplifyAzure Static Web Apps など各クラウドプラットフォームでも提供されるようになりました。簡易なものであれば、 GitHub Pages も便利ですし、ストレージのサイトホスティングの機能を利用することもできます。

専属のものは、低価格で始めやすい反面、サービスが成長してくるとコストが大きくなる傾向があるようです。クラウドプラットフォームの場合は、そのプラットフォーム自体の学習コストが懸念されますが、周辺サービスへの連携も含めると総合的にコストを抑えられる場合もあります。プロジェクトやサービス規模によって解は異なり、検討しがいのある点でもあります。

APIにおいては、小規模であれば静的サイトホスティングに付随するAPIサポートで十分のりきれるでしょう。また、トラフィックの量や処理の特性によって、FaaS (Function as a Service) や PaaS (Platform as a Service) を用いることで、負荷やコストの最適化を調整することができるでしょう。成長が見えているサービスの場合は、FaaS や PaaS などの選択肢が多いクラウドプラットフォームの利用が適していると考えます。

スケールしやすい

負荷の傾向によって、フロントエンドとバックエンドをわけることで、無駄なくスケールさせることができます。

サービスが成長し、トラフィックが増えたり、データの増加により処理時間が長くなったりと、バックエンドに負荷がかかるようになってくるので、これを適切にスケールさせることが重要になってきます。このとき、フロントエンドとバックエンドが同じサーバーから配信されていると、フロントエンドまでスケールすることになり無駄が発生します。また、スケールを想定していないとセッション管理など見落としがちになるので、最初から分けて考えた方がリスクが減るでしょう。

また、フロントエンド側はそもそも負荷がかかりにくいですが、トラフィックが増えてくる場合は CDN などを用いて負荷分散することができます。

スケールのしやすさは、コストの最適化にも一役買いますね。

UIの刷新やクライアントのバリエーションを展開しやすい

APIをベースに構成すると、UIの刷新もフロントエンドだけで完結できたり、モバイルアプリなどの別のクライアントを導入しやすいでしょう。

APIが増えてきたり、クライアントが複雑化、多様化してくると、APIの使い勝手が釣り合わなくなってくることもあります。その場合は、BFF (Backends for Frontends) と呼ばれるデザインパターンを用いて、クライアントに適した中間のAPIを用意することで、中心となるAPIはそのままに拡張性を高めることができます。

https://docs.microsoft.com/ja-jp/azure/architecture/patterns/backends-for-frontends

認証とデータベースはどうする?

前述でも触れた専属の静的サイトホスティングサービスを選択する場合、それ自体が認証機構やデータベースを持っていることは少ないようです。調べてみると、Google Firebase の Authentication や Firestore を利用したり、認証には Auth0(認証・認可)、データベースには FaunaDB(初めて知りました)などといった外部サービスと連携させるようです。

サービスが成長するにつれ、ユーザー数が増え、データ量が増え、サービスが拡張されていくことを考えたとき、外部サービスのつなぎ合わせがネックになってくることもあるでしょう。度重なる外部サービスのAPIコールのレイテンシが処理時間に影響したり、トラフィックの増加によりコストが増大することも懸念されます。

ここで提案したいのは、クラウドプラットフォームの採用 です。クラウドプラットフォームは、様々な形態のサービスを提供する中で、各サービスをより良く接続する方法を提供してくれています。たとえば、バックエンドのコンピュートリソースとデータベースは同じネットワーク内に配置することができて、そうすれば、レイテンシも改善されるし、トラフィックによるコスト加算も抑えられます。インターネット経由ではなく、仮想ネットワーク内の通信であればよりセキュアです。データのバックアップや分析基盤への連携もできるでしょう。認証機構も持ち合わせてますし、各サービス間をまたがせることもできるでしょう。クラウドプラットフォームならこれができるのです。( Microsoft Azure では可能です。おそらく AWS もできると思います。ほかは調べ切れておりません🙏)

フロントエンド + API を Microsoft Azure で構成する

さて、前置きが長くなりましたが、上記考察を踏まえて、フロントエンド + API をクラウドプラットフォームで実現する構成をご紹介します。クラウドプラットフォームには、私が慣れている Microsoft Azure を用います。(ほかのクラウドは勉強不足ですごめんなさい!)

Azure Static Web Apps + Azure Functions + Azure Cosmos DB の強力タッグ

名称 説明
Azure Static Web Apps 静的サイトをホスティングするためのサービス。詳細は後述。
Azure Functions いわゆる FaaS で HTTP トリガーをはじめとしたさまざまなイベントに対する処理をホストできる。サポートする言語は C#, JavaScript/TypeScript, Java, Python, PowerShell。
Azure Cosmos DB NoSQL データベース。書込み性能や可用性が高く、Change feed によるイベント連携も秀逸。Free レベルサーバーレス機能(プレビュー)が登場しコストの最適化をしやすくなりました。

まだプレビューではあるものの、期待が高まる Azure Static Web Apps を利用すると、こんなシンプルな構成で フロントエンド + API の構成を実装することができます。

Azure Static Web Apps の特徴

  • GitHub Actions によるデプロイ(CI/CD) が前提になっており、手軽にデプロイできる
    • 指定したブランチに更新があると自動的にデプロイされる(ワークフローを更新することでカスタマイズ可能)
    • プルリクエストに対してステージングを構成できる(プレビューの段階では 1つまで)
  • Azure Functions を用いた APIサポート(FaaS機能) を利用できる
  • 簡単な設定で、下記のプロバイダーによる 認証 を利用できる
    • Azure Active Directory
    • GitHub
    • Facebook
    • Google
    • Twitter
  • カスタムドメインを設定できる
  • プレビューの間は無料
    • 参考: 価格 - Static Web Apps
    • APIサポートについては Azure Functions の従量課金プランが計上されますが、多少のトラフィックなら無料の範囲内に収まります(参考: 価格 - Functions

Static Web Apps はAPIサポートとして Azure Functions を内包しているので、実質2つのリソースを建てるだけでこの構成が実現できます。

Azure Functions や Azure Cosmos DB の連携

ここでは Azure Functions や Cosmos DB の詳解を割愛しますが、こちらのリポジトリで簡単な実装を行ったのでご参考になるかと思います。

https://github.com/dzeyelid/line-liff-with-azure-handson

余談: サービスの成長に伴う拡張の考察

ちなみに、上記は最小構成ですが、サービスの成長に伴い拡張する場合も柔軟に対応できると考えています。いくつか例に挙げます。

  • バックエンドのコンピュートリソースとデータベースをセキュアにつなげたい
    • Static Web Apps のAPIサポートから Azure Functions に移行し、VNET統合とサービスエンドポイントを用いてデータベースと接続する
  • バックエンドでより複雑な処理を行いたい
    • Static Web Apps のAPIサポートから Azure FunctionsAzure Web Apps (PaaS)に移行する
  • Azure FunctionsAzure Web Apps でも同じ認証プロバイダーで実装できる
  • データベースを変えたい、増やしたい
  • Azure Cosmos DB (NoSQL) は書き込みが得意だが集計は得意でないため、CQRS パターンを用いて最適化したい
    • Azure Cosmos DB の Change feed 機能を用いて、Azure FunctionsAzure SQL Database に反映し、集計に用いるなど

そして、ウェブサービスとしての拡張だけでなく、IoT や機械学習、分析基盤への連携などもプラットフォーム内で完結できることは、開発を強力にサポートしてくれることでしょう。

ゆめが広がりますね!✨

Epilogue

(結局うまくまとめられた気がしないままエピローグへ…

ここまでお読みくださりありがとうございます!端的にまとめたかったのですが、長編になってしまいました。

さて、さらに余談ではありますが改めてご紹介します。Code Polaris は、女性エンジニアを応援するコミュニティです。エンジニア業界は、改善してきているとはいえまだまだ男女比に差があり、女性エンジニアの立場は、相談しにくかったり、仲間を見つけにくかったり、何かと不便が絶えない状況です。ですが、そんな理由で彼女たちの輝くはずのパワーが制限されてはとてももったいない!彼女たちが安心して技術に取り組めるように、このコミュニティを作りました。

みんな技術大好きっこなので、技術のスキルアップにもコミュニティで取り組んでいきたい!

そんな想いから、みんなで作ってみるプロジェクトに向けて動き出しました🙌

Code Polaris はテクノロジーカットではなくみなの技術スタックが異なり、足並みがそろいにくかったので、発起人の私がえいやで最初の環境を決めてしまうことになりました。そのときに考えた構成をまとめたものが本記事です。

次の課題は、どうやってオンラインで顔を合わせたこともないメンバーでこれを作っていくかが課題ですが、それができるようになったらこのコロナ禍の中、みな胸張って仕事に活かせるようになると思います。日進月歩ですがみなで楽しんで進んでいきます🚀🐱‍🏍

Discussion