コスパ最強アーキテクチャT3-Turboを紹介する

はじめに

個人開発ほど零細規模でもなく、モジュラモノリスやマイクロサービスを使うほど大規模でもないが、小〜中規模な開発の際にT3-Turboアーキテクチャを使うことでコスパよくシステム構築できます。名前の由来はT3-StackTurborepoになります。個人開発としては素晴らしいT3-Stackですが、T3-Stackではデメリットとなった密結合や拡張性の問題を、monorepoツールやサーバサイドを採用することで解消し、より大きなチーム開発でも対応可能になっています。

技術要素

2023年5月に行われたVercel Shipの中で、Vercel社がフルスタックな開発環境を目指していることがわかりました。このT3-Turboアーキテクチャでは、Vercel社が出している技術を中心に、それらと相性の良い技術を組み合わせて採用しています。

Turborepo

Vercel社によって開発されている、Typescrpit/Javascriptに特化したmonorepo管理ツールです。メリットは以下になります。
  • Rust製+並列化でビルドが早い
  • Remote Cachingによって、ビルドキャッシュをチームで共有できる
  • T3-Stackの時にはNextJSと密結合だったモジュールを分割できる
以下にフォルダ構成の例を示します。
Turborepoの細かい使用方法はここでは説明しませんが、appsフォルダの下にアプリケーションを、packagesフォルダの下にモジュールを配置しています。まとまったをモジュールとして切り出すことで、密結合を防ぎ、クリーンな設計に落とし込むことができます。
:::message Cloudflareは残念ながらmonorepoに対応していないため、次のNestJSはVercelにデプロイしましょう。 :::

NextJS(App Router)

https://nextjs.org/ NextJSはVercel社が出しているフロントエンドフレームワークです。App Router機能により、より直感的なルーティング、よりサーバーを活用したレンダリングが可能になりました。今後はPage Routerよりもこちらの開発に力を入れていくと思われます。

UI

T3-Stackでも採用されていたTailwindCSSを採用します。 https://tailwindcss.com/
続いて、UI Component LibraryはHeadlessなものを使います。HeadlessなUIとは、UI Componentを「機能」と「見た目」に分けそのうち機能のみを提供するというもので(見た目の部分はTailwindCSSが担う)、特にVercelが推しているSSRと相性がいいです。代表的なHeadless UI Component Libraryとして、Radix UIとMUI Baseがあります。 https://www.radix-ui.com/https://mui.com/base-ui/ これで十分と言いたいところですが、どちらのライブラリも用意されているComponentは数が貧弱で(むしろ2つの用意されているComponentは被っている部分も少なく、併用したとしても少し不十分)、まだまだMUIやMantineといったメジャーなUI Libraryにも頼る必要がありそうです。

NestJS(Nest-Graphile)

https://nestjs.com/ Typescriptを完全サポートしたNode系バックエンドフレームワークといえばNestJSです。加えてPostgraphileというライブラリを使用することで、GraphQL Engineによって簡単なCRUD処理は自動生成され、リゾルバまで自動で提供してくれます。 https://www.graphile.org/postgraphile/
PostGraphileに関しては別記事で紹介しています。 https://zenn.dev/ficilcom/articles/invitation-to-postgraphile
GraphQL Federationというアプローチをとることにより、フロントエンドからは1つのGraphQL APIだけ取り扱い、複数のサービスを跨いでデータを取得するリクエストが可能になり、尚且つ型安全に開発を進めることができます。GraphQL Federationについてはマネーフォワードさんのテックブログで詳しく解説されています。 https://moneyforward-dev.jp/entry/2021/06/30/graphql-federation/
PostGraphileで簡単なCRUD処理を行い、それ以外のリクエストに関しては、NestJSの実装を通して対応します。(以下、この方法をNest-Graphileと呼びます)
似たような方法として、HasuraとNestJSを併用してバックエンドを構築する方法があります。こちらはフロントエンドからの最初のリクエストをHasuraが受け取り、簡単なCRUD処理はそのままHasuraで処理し、それで対応できない場合はRemote Schema機能を使ってNestJSに流すというアプローチを取ります。 Nest-Graphileなら1つのサーバーでどちらも処理することがきます。
Hasura + NestJSの場合
Nest-Graphileの場合
Nest-Graphileはコンテナとしてデプロイする必要があるため、AWSやGCP以外で、コンテナ用のPaaSサービスを使います。Tokyo Regionがあるという点でfly.ioがいいと思いますが、個人的なおすすめはKoyebです。 :::message Heroku以外にも様々なコンテナ用PaaSサービスが出現しています。CLIツールの充実度や、Tokyo Regionの開設時期や、monorepoへの対応など、Watchが必要そうです。 :::

Database

Vercel Postgrasの元になったNeonDBがおすすめです。 https://neon.tech/ Vercel PostgresはNeonDBをベースに作られていますが、まだまだ機能を再現しきれていない部分も多く(他のStorage系サービスも同様)、本家を使うと良いでしょう。NeonDBには以下のような特徴があります。
  • ServerlessなPostgresDB
  • DBスキーマをブランチ管理できる
  • VercelのPreview機能に合わせてNeonのブランチを切れる
また、ORMにはPrismaを使います。 https://www.prisma.io/ PrismaはNode/Typescript専用のORMです。同様の他のORM候補としてKyselyDrizzleがあります。
以下の手法でPrismaのデータスキーマ変更をNeonにMigrateします。 https://neon.tech/docs/guides/prisma-migrate
:::message このアーキテクチャでは、ORMをデータスキーマ定義にのみ使用します。 :::
:::message alert 執筆時点でNeonは東京リージョンに対応していません。ただし、対応する方針はだしています。 :::

Storage

Vercel Blobの元になったCloudflare R2がおすすめです。 https://www.cloudflare.com/ja-jp/developer-platform/r2/ AWS S3互換で、低レイテンシ・高スループットを実現しています。

Redis

Vercel KVの元になったUpstashがおすすめです。 https://upstash.com/ Redisストレージ等を提供します。

T3-Turboのメリット

  • フロントもバックもフルTypescript構成なため、型安全で堅牢な上に、フルサイクルエンジニアの開発リソースを最大限効率的に活用できます。
  • AWSやGCPといったパブリッククラウドを使わなずに済むため、インフラの運用管理コストを最小限に抑えられます。
  • クエリや型の自動生成によって、開発効率が爆速になります。

T3-Turboの限界

これで中規模くらいまでのサービスなら対応可能でしょう。Nodeの限界がこのアーキテクチャの限界と言えそうです。これで限界ならIaaSへ移行や、モジュラモノリス/マイクロサービスの採用を検討した方が良いでしょう。

将来性

モバイルアプリ化に関して

モバイルアプリの開発によく使われるFlutterに関しては、Turborepoの管理対象外となります。Turborepoの管理可能な中では、Expo(React Native)が第一候補になります。 https://expo.dev/ ただ執筆時点ではまだα版ですが、Tauri Mobileを利用することで、NextJSで構築したWebサービスをモバイルアプリ化する方法があり、こちらを検討した方が良いかもしれません。 https://tauri.app/blog/2022/12/09/tauri-mobile-alpha/

モジュラモノリス・マイクロサービスへの拡張

NextJSはフロントエンドの主流となり、NestJSもBFFとしてよく使われれる技術です。Turborepoでは管理できないものの、NsetJSをBFF化することで、他の言語のマイクロサービスを採用することができます。

まとめ

T3-Turboアーキテクチャで作った全体像が下図のようになります。(あくまで1例であり、プロダクトの要件によって最適なサービスを取捨選択してください)
まだまだ発展途上な部分はありますが、T3-Turboを使うことで、モダンな技術スタックかつ開発効率、保守性、拡張性に優れた開発体験を得ることができます。資金/時間などのリソースが限られている新規事業、スタートアップにとっても使い勝手が良く、Ruby on RailsやLaravelに変わる手段として今後主流になりそうです。