🕍

PMF達成の立役者!Full TypeScript Architecture の選定背景と構成

2023/12/10に公開

はじめに

みなさんこんにちは、物流業界の価値最大化をミッションに掲げるアセンド株式会社で取締役CTOを務めている丹羽です。

今回はアセンドの Full TypeScript Architecture の選定背景とその構成を紹介します。

アセンドでは社会課題である物流危機の中心にいる運送会社に対し、課題解決の第一歩として業務と経営のデジタル化を実現する All-in-One な運送管理SaaS「ロジックス」を開発しています。アセンドは12月06日にプレスリリースをした通りシリーズAの資金調達し、無事にプロダクトとして PMF (Product Market Fit) を一定達成したと言えます。

https://prtimes.jp/main/html/rd/p/000000023.000071415.html

3年前に開発をスタートしたロジックスはフロントエンド、バックエンド、クラウドのIaCに至るすべてを TypeScript で開発することを選択しました。振り返ってみても FullTS でなければ PMF を達成することはできなかったと考えています。直近ではエンジニアの採用が進んでおり新規メンバーから Full TypeScript Architecture について質問を受けることも増えました。今回は PMF の達成と今後のさらなるプロダクトの進化を支える Full TypeScript Architecture について、選定した背景と構成についてまとめます。


また、本記事はTypeScript Advent Calendar 2023の10日目の記事となります!現在企画中の TypeScript の大規模カンファレンス TSKaigi の運営チームの雑談からこのアドベントカレンダーができました。丹羽も運営コアメンバーとして参画していることから、1つテックブログを投稿することとしました!

https://qiita.com/advent-calendar/2023/typescript

Full TypeScript の選定に至った背景

3年前の当時、シード期の資金調達をしたばかりのアセンドは初期メンバーがなんとか開発したバックエンドはPython、フロントエンドはJavaScriptという構成で既に技術的負債だらけの初期プロダクトを抱えていました。 SaaS とは継続的に開発し顧客へ価値を届けるものであるにも関わらず、既に手をつけられない魔物となっていたのです。
当時、副業で手伝っていた丹羽はその状況を心配し、企業ミッションへの共感を根底にプロダクトを作り直すべきと考え勝手にリプレイスプランを作成して代表に提言をしました。(またこの提言があり取締役CTOのオファーをされました)

アセンドは社会課題解決を志し創業し、お金がない故にデジタル化が遅れた産業・運送業界を対象に選びました。そんな運送業に対して SaaS を開発し提供することは当時から大きなチャレンジであると理解していました。特に以下の壁があると考えていました。

  • お金がない産業ゆえに、事業成長には長い時間と資金がかかることが想定される。
  • アナログで業務の最適化が進んでしまっており、システムによる業務代替には高いユーザビリティが求められる。
  • 運送の業務は複雑性と多様性があり、深いドメイン知識を獲得してSaaSとして共通化・汎用化が必要となる。


当時のアーキテクチャ検討の際にまとめたドキュメント

これを受けてリプレイス後のアーキテクチャには以下の特性が必要であると整理しました。特にエンジニア一人一人の高い開発生産性とプロダクト・ドメインへの深い理解が重要と考えています。

  • 圧倒的な一人あたりの開発生産性が出せること
    • プレA含め2.5億円という限られた資金で進化の遅い業界に事業を作るとき、多量のエンジニアを抱えることはできない
    • お金がなくスポットライトもあたらない業界を対象に関心をもつエンジニアはなかなかいない
    • エンジニアを育て、一人あたりの圧倒的な開発生産性で押し切るしかない。
    • (結果シード期の2年は、4名で 5.67 deploys/day という生産性で走り切りました)
  • エンジニアが技術軸ではなくプロダクト軸で開発に向き合えること
    • 業務アプリで高いユーザビリティを実現するには、フロントのUIだけでなくデータモデルレベルでユーザビリティを考えるべき。
    • 1機能の開発にエンジニアがオーナーシップを持ち、仮説検証を繰り返し課題とドメインを学べる状態とする。
    • ゆえにフロントとバックエンドでエンジニアを分けず、機能毎にエンジニアをアサインしやすいようにする。
  • 複雑なドメインを扱えるほど言語を含め表現力が高いこと
    • トラック運送には多様な運び方があり、重量のあるものや体積の嵩張るものや液体など、定期便やスポット便・近距離や長距離・共同配送や中継輸送など輸送形態は様々で、この多様な案件・業務をSaaSで統一的なデータとして扱うために柔軟性が言語には必要。
    • 一方で複雑な業務ロジックを扱うために言語には型付けのある固さも必要。

これらの諸条件を鑑みて、1エンジニアが無理なくフロントとバックエンドを開発でき、固さと柔軟性を持った言語として TypeScript を選定しました。
当時はまだ Full TypeScript の事例はほとんどなく不安もありましたが、上記の合理的な背景があったため強い決断を取ることができました。また TypeScript はフロントエンドを中心に活用され言語ナレッジが溜まってきていたことや、Severless を中心にJS/TSが活用されていたことでサーバサイドでの利用事例も溜まりつつありました。
3年前に始まったスタートアップやプロダクトで FullTS を選択しているものは意外と多くあり、FullTSの時代の変革点にあったように思います。

Full TypeScript Architecture の構成

フロントエンドとバックエンドを TypeScript に統一すると決め、合わせてクラウドのIaCでの管理においてもTSが利用できそうだったので同じくTSに統一しました。各領域の個別の選定についても触れておきます。

フロントエンド

  • React
    • 丹羽が2017年からReactを利用していたことや、初期プロダクトもReactであったことから継続して React を利用することとしました。
    • 個人的には React の方がライブラリとしての書き方の矯正力が強く、複数人での開発や業務アプリなど複雑性の高いアプリケーションにおいては堅牢に開発がしやすいとも考えていました。
  • Create React App (現在はNext.js)
    • ゼロコンフィグの恩恵を享受するために CRA を選択しました。特にスタートアップとしてwebpackの調整をする労力をかけたくないことからベストプラクティスに乗ることとしました。
    • 現在はCRAはメンテナンスされないと話が立ったことから、Next.jsに移行しています。Next.jsはゼロコンフィグの恩恵を受けるために選択しており、深くは利用していないのが現状です。
  • Bulma
    • CSS Framework として Bulma を利用しています。
    • ロジックスは業務アプリであり優れた美しいUIは必要でないことから、手軽かつ軽量に利用できるCSS Frameworkを頼ることとしました。またバックエンド出身のCSS不得手なエンジニアも多くなるため、CSS-in-JSを前提としたものを導入することはやめました。
    • デザイナーの採用ができ1段高いUIを作る方針が見えたタイミングでデザインの高度化を図る予定です。

バックエンド

  • Express.js
    • 2021年当時はJSベースのサーバーサイドといえば Express.js が代表でした。機能性が薄くカスタマイズ性があることが逆によく、ドメイン駆動設計のレイヤードアーキテクチャを選択しています。
    • Express に強いこだわりはなく薄くしか利用していないため、将来的に良い代替があれば移行すれば良いと考えています。
  • InversifyJS
    • Dependency Injection を実現するために InversifyJS を利用しています。
    • インタフェース定義に基づいて責務を分け疎結合でキレイに層を分離することを強制するためにDIの仕組みを重視してわざわざ入れています。
    • 一時期 Nest.js への移行も検討しましたが、層の命名や切り方に Nest.js 側の思想が強くありすぎて考え方に合わない部分もある一方で旨みが少ないことから見送りました。
  • Prisma
    • ORMにはPrismaを利用しています。初期はMongoDBでmongooseを利用しており、Prismaの実用性が高くなったことから移行しています。
    • 特にスキーマ定義に基づいて、TypeScriptの方がついたClientを生成してくれることにありがたさを感じています。

Infrastructure as Code / Tools

この章は簡単な紹介となります。
IaCにTypeScriptを利用したことでT、erraformに比べてコードの補完が聞きやすく、また定義に関してライブラリ内に飛ぶことができるため初学者でもコードベースで全体像がわかりやすいというメリットがありました。

またSlackのChatOpsでデプロイの自動化をしていますが、ChatBotをBoltで開発しています。

終わりに

今回はアセンドの Full TypeScript の選定背景と構成について紹介しました!
各技術を選定した背景を記載することで将来に刷新すべきときに決断をサポートできるドキュメントとして活用してもらいたいと、メンバーに対して思っています。

またCTOとして初期から、事業をみて経営と技術の融合した考え方を持つことが少しでもできたのではと考えており、これからCTOとなる方々への一例となれば幸いであると考えています。

最後に TSKaigi のお知らせです!
2020年にコロナの直撃を受け TSConfJP が中止となり、それ以来 TypeScript の大規模なカンファレンスは途絶えていました。この状況は日本国内のTypeScriptの知見共有が滞ることに繋がると考えています。特にFull TypeScriptの事例はこの2,3年で出現し、アセンドではFullTSという高い開発生産性の恩恵を受けていることから、よりTypeScriptの活用事例が広められる環境がつくられるべきと考えています。
「日本に TypeScript の大規模カンファレンスをもう1度!」ということで、有志で集まり 2024年春開催 に向けて数千人規模のイベントを企画中です!丹羽もこの活動のコアメンバーとして参画しています。
良いイベントとなるよう作り上げていきますので、ぜひご参加ください!

https://tskaigi.org/

アセンドプロダクトチーム

Discussion