Typescriptこんにちは、以下のツイートをしたところ、予想外に反響をいただいたので記事を書いてみることにしました。Repositoryの構築がきれいにできなくて途中でTypeORMに移行しました。2019年1月9日TypescriptだとORMはSequelizeよりTypeORMのほうが、いろいろ整備されて良さそうです。依存性注入のライブラリであるTypeDIとのつなぎこみも楽なのでTypeORMのほうが圧倒的におすすめ。Architectureに基づいてプロジェクト構成をつくる。各モジュールはinterfaceに依存するようにして、ユニットテスト時にモックに差し替えられるようにする。DIを用いて、実装を注入するようにして、モックに差し替えられるようにする。今回つくるもの以下を作ってみたいと思います。外部とのやりとりはfirebaseとDB(Postgresql)です。プロジェクトの構成プロジェクト構成プロジェクトのtreeはこちらです。webpack.config.dev.jsそれぞれの構成要素の説明それぞれの部分について、説明していきます。Architectureの基本的な用語などは、いい記事がいっぱいあるので省略させていただきます(おいEntityUseCaseGatewayControllerRepositoryあの有名な図を内側から外側に順に、説明していくイメージを持っていただければ。string;}データを保持するクラスとして、Userのentityを宣言し、各種値の定義しています。データベースのテーブルとEntityは1対1で、保持するようにしてます。}}UseCaseにビジネスロジックを書きます。今回は、firebaseとdbに登録する処理をUseCaseに記載しています。その後、実装を書いていきます。後に説明しますが、userRepositoryとfirebaseGatewayは、interfaceに依存しており実装に依存していないため、モックに差し替えが可能です。UseCaseが思いっくそ、firebaseに依存してるやんけ!とコメント受けてコード変更しました。}}Gatewayは主にAPIなどの外部との接続を担保します。今回は、実質firebaseとのライブラリをラップしているだけなので少々、冗長です。実際の運用だと、無くしてしまって、直接firebaseのライブラリを叩くのが良いです。他のAPIを自力で実装する場合などでゴリゴリロジックを書く場合は、こういった形でGatewayを設けると良いと思います。}}Controllerはrouting-controllersで、ルーティングもデコレータで記述してます。非常にSpringライクですね。github.comUseCaseにビジネスロジックを書いていて、それを呼び出すだけので、非常にシンプルです。}}RepositoryはTypeORMのレポジトリパターンをそのまま踏襲してます。DBにアクセスする際のデータの処理方法を記載していくイメージ。TypeDIの制約でinterfaceを定義できませんでした。あとで試してみたら、普通にinterfaceを定義できたので更新しました。その他インターフェースと実装の命名規則について実装例を見ていると以下の2パターンが多いようです。}}個人的には1のパターンだと、実際に利用するのは、IHogeHogeになります。(HogeHogeはIHogeHogeに後から注入される。)違和感があるので2の命名規則が個人的には好みです。TypeDIによる依存性注入について実装に依存することを避けるため、TypeDIという依存性注入ライブラリを利用しました。Springライクにデコレータで依存性注入がサクッと行えるので非常に便利です。Factoryfactory.create();今後Updateするポイント以下のポイントがまだ不十分なので今後UpdateしていきFirebaseGatewayのせいでUseCaseがinfraに依存してしまっている。Entityは単に、データを保持するクラスじゃない!という話もあるらしいので、そこらへんコメントもらえると泣いて喜びます*2:これもコメントもらえると泣いて喜びます。月別アーカイブ著書はてなブログをはじめよう!pco2699さんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。