Web アプリのアーキテクチャ
本章では、生産性の高い状態で継続的に開発していくために、Web アプリのアーキテクチャについて議論した内容について紹介します。
技術スタックの現状
これまでのリニューアル、リノベ、リファインメントによりプロダクトのUIがアップデートされ、それに伴いフロントエンドの技術スタックもアップデートされてきました。 現在技術スタックは大きく4世代存在し、v1〜v4 と呼ばれています。
v1
Haml / SCSS / AngularJS & jQuery & Backbone.js
v2
TypeScript + React + Redux + redux-thunk / styled-components / webpack
v3
TypeScript + React + Redux + redux-thunk / styled-components / webpack / SSR
v4
TypeScript + React(Next.js) + GraphQL / styled-components
最新のバージョンは v4 です。現在でも v4 以前の古い世代の技術スタックで書かれたコードが存在します。
開発における基本方針
新規開発やページのリニューアルのタイミングでは可能な限り v4 で開発することを推奨します。 v4 アーキテクチャの各アプリケーション上で開発を行い、 GraphQL サーバーを経由して各マイクロサービスと通信を行うようにします。
v4 アーキテクチャのアプリケーションについて
v4 のアーキテクチャのアプリケーションは以下の2つが存在します。
wantedly-frontend
ユーザーサイト
wantedly-admin-frontend
企業向けユーザーサイト
対象に記載がある通りそれぞれのアプリケーションがユーザーサイトと企業向けユーザーサイトに分かれています。 対象となる機能がユーザー向けであるか、企業向けであるかをもとに開発するべきアプリケーションを確認してください。
GraphQLサーバーについて
WantedlyにはGraphQLサーバーが以下の2種類存在します
wantedly-graphql-gateway
visit-api-node
サーバーが2つ存在する経緯等については Wantedly Visit で BFF GraphQL サーバーを辞めた理由 を参照ください。 新規ドメインの query/mutation は基本的に wantedly-graphql-gateway に用意されます。
実装における共通方針
技術方針の決定プロセス
新しい技術やライブラリを導入する際は以下の手順で進めます:
Frontend Chapter で議論を行う
撤退可能な状態・最小規模で導入する
Architecture Decision Record (ADR) に記録する
振り返りを行う
振り返りをもとに判断を行い、必要であれば広く導入する
小さく試す限りにおいては上記の手順はSkipしても問題ありませんが、判断に困る場合は上記に従うことを推奨します。
SSR
SSR が可能なアーキテクチャにおいては SSR は必ず行う前提で実装を行います。 一方で SSR の際、つまりサーバーサイドで多数の GraphQL の呼び出し等をすると TTFB (Time to First Byte) が遅くなる原因になります。

そのため、何をサーバーサイドで同期的に取得し、何をクライアントサイドで非同期的に取得するかを個々のページで考慮する必要があります。 例えばファーストビューで表示されるコンテンツ SEO に必要な meta 情報はサーバーサイドで同期的に取得する必要があります。 一方でパーソナライズされたコンテンツ、例えばユーザーへおすすめのコンテンツなどはクライアントサイドで非同期的に取得を行っても問題ありません。

画面の性質を考慮した上で適切な設計を行うようにしてください。
状態管理
Web アプリの状態管理は以下の3種類に分けることができます。
1
サーバーデータキャッシュ
サーバーから取得したデータをクライアント側でキャッシュしているもの
2
グローバルな状態
複数画面/コンポーネントで保持するUIの状態
3
ローカルな状態
単一のコンポーネントが保持するUIの状態
これらの状態管理をそれぞれの技術スタックで以下のように状態管理を行ないます。
1. サーバーデータキャッシュ
v1
-
フロントエンドでのデータキャッシュは行なっていない
v2, v3
Redux Store
一部 React Query を利用している
v4
Apollo InMemoryCache
-
2. グローバルな状態
v1
-
単一の状態管理を持たない
v2, v3
Redux Store
-
v4
-
必要に応じた Context API を利用した状態管理はあるが Redux のように中央集権の状態管理は持たない
3. ローカルな状態
v1
-
単一の状態管理を持たない
v2, v3
Redux Store / useState
Redux Store が存在する場合は Redux Store を利用している
v4
useState
-
前述のとおり v4 では Redux のような中央集権的な状態管理の仕組みは存在しません。 これはグローバルな状態管理のために Redux, Jotai, Zustand などのライブラリを使用しない、という判断ではありません。 v4 において複雑な状態管理が必要になった際には新規にライブラリを導入するという判断は可能です。 技術方針の決定プロセスの手順に従い導入を進めるようにしてください。
v4 へのマイグレーション・移行
wantedly/wantedly の v1 スタックのページについてはリノベ・リニューアルのタイミングで積極的に v4 への載せ替えを推奨とします。 移行については以下のいずれかの方針で進めることを推奨します。
v1 から v4 へ完全移行(GraphQL API への移行も含む)
v1 から v4 へフロントエンドを移行(GraphQL APIは対応せず、既存のエンドポイントを利用する)
v1 から v2, v3 へ、その後 v4 へ段階的に移行する
どのような方針で進めるべきか迷った場合はまずは Frontend Chapter で相談をしてみてください。
話を聞きに行きたい
Slack: #frontend_chapter
もっと知りたい
最終更新