スタートアップスタジオのゼロイチ開発を効率化させる技術選定 (バックエンド編)
はじめに
はじめまして、株式会社ispecのCTOで、Backend Teamのリーダーをやっている山田です。
今回は、ispecが展開するスタートアップスタジオ事業でプロジェクトを開始する際にどのような技術選定をしているのか、について紹介したいと思います。
背景
ispecは、スタートアップ企業様にプロダクト開発のための技術力・デザインを提供することで、プロダクトのゼロイチからグロースまでをサポートしています。
その中でispecのエンジニア組織は、ゼロイチの開発をいかに早く、高い品質で行うことができるか、という課題に常に取り組んでいます。これを実現することによって、スタートアップ企業様とispecの双方に、ビジネス的なメリットを生み出すことができます。
早くて高品質のゼロイチ開発を実現するために、ispecでは様々な角度から技術的な施策を実施しています。
今回は、開発を開始する際に行う「技術選定」に焦点を当て、「品質とスピードを保つために、どの技術をどの基準で選定しているのか」について紹介をしていこうと思います。
第一弾はバックエンド編です。
目標
バックエンドの技術選定において、達成したい目標は以下の二つです。
1→10を見据えたスケーラブルなアーキテクチャ
1→10を見据え、ソフトウェアで使われている技術やビジネスロジックが柔軟に変更であることを目指します。
「柔軟に変更可能」という言葉はかなり乱用されがちですが、ispecが目指しているアーキテクチャは、あらゆるレイヤーで高凝集かつ疎結合である状態を実装することで、「柔軟に変更可能」な状態を実現する、というものです。
詳細は後述しますが、
- PubSubパターンでサービス・モジュール毎の関心事の凝集性を高め、モジュール間を疎結合に保つ
- ドメイン駆動設計を用いてビジネスロジックをドメイン層に、技術的複雑性をインフラ層に凝集させ、ドメイン層とインフラ層を結合にする
などの戦術を社内に浸透させることで、柔軟に変更可能なソフトウェアを設計・実装しています。
ビジネス的な都合を考慮できる開発スピード
スタートアップにとって、リリースが来月になるか再来月になるかはかなりクリティカルな問題であるため、開発スピードは本質的に重要です。
技術選定の段階から、開発スピードの向上を考慮することで、例えば以下のような効果を得ることができます。
- IaCのTerraformを利用することで、共通のTerraformモジュールをあらかじめテンプレート化しておき、再利用性を高めることができる
- モジュラモノリスアーキテクチャを採用することで、複数人が同時に違うモジュールを開発できる
技術選定の段階から、その技術が開発スピードにどう影響するかを考慮することで、開発スピードを高めています。
選定する技術と基準
技術選定においては、「技術を統一し標準化する箇所」と「プロジェクト固有に選定をする箇所」を明確にしています。
バックエンドの開発言語は基本的にGo言語に統一をしています。元々はRuby on Railsも使用していたのですが、プロジェクト固有に柔軟にアーキテクチャを設計しやすいという点と、Go言語の言語仕様のシンプルさが学習コストの低さに繋がるため、キャッチアップをしやすいという点で2020年の1月から社内のほぼ全てのバックエンド開発の言語をGo言語に統一しています。
これ以降、Go言語のバックエンドアプリケーションの開発に必要な共通モジュールなどを少しずつ溜め込んでおり、それらを活用することである程度の開発効率化を実現できています。具体的な共通モジュールについては今後紹介していこうと思いますが、
- Sentryへのエラー通知を簡単に実装できるパッケージ
- errorをHTTPステータスコードなどにハンドリングをしやすくするためのラッパー
- データベース接続を伴うテストを簡単に実行するためのヘルパー
などが実装されており、プロジェクト間で再利用されています。
システム設計
基本的にはモジュラモノリスのサーバーと、必要に応じてマイクロサービスを実装するような形をとっています。
ispecは、俗人化の防止や開発効率の向上を考慮して、一つのプロジェクトになるべく複数メンバーが参加するような形式を取っています。
複数人でゼロイチの開発を素早く行うためには、アプリケーションやモジュールを疎結合に保ち、お互いの作業に影響がでないようにすることが必要です。一方、初期段階でマイクロサービスアーキテクチャを実施するのは、インフラの運用コストが非常に高いのと、サービス毎にチームやメンバーを当てられるほどの工数をかけられないため、現実的ではないと判断しています。
そのため、モジュラモノリスアーキテクチャを採用することで、サービスをモジュールごとに分割し、それらが参照しないように疎結合に保ったまま実装を進めることで開発効率をあげつつ、インフラの運用コストが低くなるようにしています。
モジュラモノリスのモジュール間のやりとりは基本的にPubSubパターンを使っていますが、詳細は別の記事で紹介します。
モジュラモノリスの設計に関しては、以下の記事を参考にしながら実装をしています。
- Shopifyはいかにしてモジュラモノリスへ移行したか
- Deconstructing the Monolith: Designing Software that Maximizes Developer Productivity
インフラ設計
モジュラモノリスで実装されたAPIサーバーをコンテナとして動かし、そのコンテナからデータストアにアクセスをするという、割とベーシックなインフラ設計で実装をすることが多いです。
データストアに使用するミドルウェアは、リレーショナルデータベースとしてMySQL、全文検索としてElasticsearch、キャッシュのストアとしてRedisを使用することが一般的です。サービスの特性や求められるパフォーマンスに応じてどのミドルウェアを使うかを選定しています。
コンテナを動かすクラウドのサービスは、Amazon ECSかAmazon EKSのどちらかを使用しています。RedashやLocustなど、AWSでマネージされていないOSSのツールを積極的に導入したい場合や、機械学習の処理をするAPIのようなComplicated-subsystemをマイクロサービスとしてデプロイしたい場合などは、デプロイのコストを下げるためにEKSを使用していますが、そうでない場合は基本的にECSを使用しています。
インフラのプロビジョニングにはTerraformを使っており、命名規則を揃えるためにプロジェクト間で共通のTerraformモジュールを使用するようにしています。
API設計
APIの設計はGraphQLとRESTの二つをプロジェクトに応じて選定しています。管理画面のようなシンプルなCRUDで簡潔するようなものであればRESTで開発をしていますが、エンドユーザー向けのアプリケーション用のAPIはGraphQLを選定することが多いです。
一般的にGraphQLの方がGo言語で実装する際の初期の実装コストが高いと考えています。便利なライブラリで言えば、
あたりが代表的ですが、ispecではアーキテクチャの柔軟性などを考慮し、ミニマルなAPIを提供している後者のgraph-gophers/graphql-goを採用しています。
ミニマルなライブラリを使用している以上、かなり多くのコードを自前で実装をする必要性がどうしても出てきてしまいます。 一方で、エンドユーザー向けのアプリケーションは、「同じリソースに複数画面でアクセスしているが、画面毎に情報が違う」のようなケースが比較的多く発生します。
エンドユーザー向けのアプリケーション開発に関しては、GraphQLの実装コストを払っても十分なリターンが得られる場合が多いため、GraphQLが採用されることが多いです。
GraphQLのAPIをGo言語でどのように実装しているかや、開発効率をどのようにあげているかについては、また別の記事で紹介します。
ソフトウェアアーキテクチャ
アーキテクチャはMVCかクリーンアーキテクチャの二つをプロジェクトに応じて選定しています。一番の選定基準は、「ビジネスロジックと技術的な都合のどちらかが複雑かどうか or 複雑になる可能性がどれくらい高いか」で決めています。
クリーンアーキテクチャで実装をする際は、ドメイン駆動設計のプラクティスを多く取り入れ、ビジネスロジックをドメイン層に凝集させ、技術的な都合をインフラ層に逃がすような実装をしています。一方でMVCで実装をする際は、Modelの層にビジネスロジックを実装するようにしていますが、MVCの性質上、Modelに技術的な都合が入ってしまいうため、ビジネスロジックと技術的な都合がひとつのレイヤーに入ってしまいます。
そのため、「ビジネスロジックと技術的な都合のどちらかが複雑かどうか or 複雑になる可能性がどれくらい高いか」でMVCかクリーンアーキテクチャを選定しています。選定の割合としてはクリーンアーキテクチャとMVCが7:3くらいになっています。
ソフトウェアアーキテクチャの設計を考える際には、以下の書籍などを参考にしています。
まとめ
この記事では、ispecが開発を始めるときの技術選定について紹介しました。
統一することでメリットを得られる箇所と、統一をしないでサービスの特性に合わせる箇所のバランスが非常に難しく、私がCTOになった3年前からかなり試行錯誤をしていく中で今の形になっています。今後も試行錯誤を続けていくので、選定技術や基準のアップデートもされていくことになると思います。
この記事では紹介できなかった個別の施策や社内ツールの詳細に関しては、また別の記事で紹介していこうと思います。
おわりに: 採用情報
ispecでは更なる事業拡大を見据え、エンジニア職にて新しいメンバーを募集しています。
採用サイトでは各求人の詳細だけでなく、ispecで大切にしている価値観や、メンバーの紹介記事も掲載しております。
- 技術へのこだわりやプロダクト愛を活かして働きたい
- フルリモート、フルフレックス下で最大限のバリューを発揮したい
- 心理的安全性の高い環境の中、チームで成果をあげてみたい
Discussion