運営しているWebサービスをリアーキテクチャした話を整理する

運営しているWebサービスをリアーキテクチャした話を整理する

2023年7月5日
アーキテクチャ

運営しているWebサービスが複雑化してきたので、リアーキテクチャやリファクタリングをしました。まだまだなところは多いですが、一旦整理したのでまとめておきます。

背景

自分が作ったWebサービスは、元々メディア的な属性が強かったのですが、認証機能やCRUDする機能など動的な機能が増えてきて、ロジック部分が多くなり複雑化してきました。

また、サーバーレスということもありフロントでのコード量が増え、なんとかアーキテクチャを見直さないと大変そうな感じがしていました。

そして一番の理由がテストが書きづらいかったところです。元々メディア的な運営の仕方でSSGしていたこともあり、ほぼ静的ページであったため、デプロイ前のgenerateがテスト代わりのようになっていました。

しかし、動的な機能が増えるとSSGでは検知できないため、テストを書く必要があり、いざ書こうと思うと非常に書きにく設計となっていました。

今後の運用性・拡張性を考えてもリアーキテクチャは急務であり、非常に優先度の高い重要なタスクとして取り掛かりました。

色々考えたことを整理する

・フレームワークに依存した作りをやめたい

・レイヤリングしたい

・DIしたい

・UTの導入

・ライブラリに依存したドメインを使わないようにしたい

・共通化したい

・型エラー直したい

ざっくりこんなことを考えており、1つ1つこなしていきました。感覚的な意識の部分としては、「依存性をなくして抽象的かつ中長期的に開発生産性の高いものにしたい」ということをぼんやり考えてました。

そんな中で、Nuxt3 + TypeScriptで開発しているのですが、ロジック部分などなるべくフレームワークに依存するような書き方はやめたいと考え、テストの書きにくさだったり、汎用性だったりを考えたときに、なるべく抽象性の高い書き方にしたく、素のTypeScriptで書くようにしました。

また、ドメインに関する情報の増加や複雑性もあり、DDD + Clean Architectureを導入することにしました。一部Firebaseライブラリのドメインを使っていましたが、そこへの依存度が高くなってしまい、Firebaseを辞めたときやバージョンアップで気付かぬうちに使えなくなってたというのをなくしたい気持ちがありました。

その上で、JestによるUTを導入し、安全かつ見通しの良い、開発していて楽しい開発体験を目指しました。

今回は、DDD + Clean Architectureを導入したリアーキテクチャのところを一部まとめておきたいと思います。

DDD + Clean Architectureの導入してリアーキテクチャする

構成としてはこんな感じで、srcの下にそれぞれレイヤリングして配置しています。modules.tsに依存関係を書いています。

依存関係としてはusecaseはgatewayとpresenterに依存しており、gatewaはdriverに依存しているといった形です。

本当はportなどのインターフェイスを作って依存性逆転して綺麗な形にしたいのですが、一旦このような形になっています。

usecaseではビジネスロジックを記述しており、garewayを通してデータの取得や登録などをしています。また、presenterを経由してstateの管理をしています。

gatewayではusecaseとdriverの橋渡しとして、driverからのデータをdomainに変換したりしています。データの取得・登録の実装部分はdriverで書いています。DBやAPIなど変更したとしても、driverを変えれば影響がないようにdriverからentityに詰めてgatewayに返すようにし、gatewayでdomainに詰め替えるようにしているところです。

ここまでレイヤリングすると、あとはusecaseを呼び出すだけで済むので、だいぶスッキリしました。

今後はTDDで進めたいと思っていますが、既存の部分に関してはガッとリアーキテクチャしてから、テスト書きました。テストはJestを使っており、jest-whenライブラリを活用しつつ書いています。

今後について

一旦基盤はできたので、今後は適宜リファクタリングしながら、保守性の高い設計に向けて改善を続けたいと思っています。

ドメインも全部なかったりまだ伸び代もあるので、常に改善する気持ちで開発し続けることが大事になりそうです。

あとはSSGベースでやってますが、SSRにしていきたい感あります。ちょっとコスト的にどれだけ高くなるのか心配ですが、チャレンジしたいと思っています。

あとE2Eも書きたいと思っています。Cypressでちょっとやりましたが、放置してしまってるので、どこかで本腰入れてやりたいと思っています。やはりテストで担保されていないと、いつ壊れるかわからないですし、そうした状況下で開発するのは結構しんどいと思います。

品質の担保かつ生産性の向上のためにも、よりより開発・設計を追求していきたいです。