TypeScript ORM

この Note は Architectural Decision Record ( ADR ) の下書きです。Official ではありません。

個人的な意見ですが、大谷さんの試合を見ていると、のんびり昼寝しているのは罪悪感を感じさせられます ⚾️

https://full-count.jp/2024/05/06/post1545990/

それでいて、最高の Team player！

## Status
- [ ] 提案済み
- [ ] 承認済み
- [ ] 破棄

## Context
- 私たちは Product の構築を進めている。このドキュメントでは、私たちが選択した最終的な ORM (Object-Relational Mapping) とその背後にある理由を説明することを目的としている。
- Product の特性上、ORM のオーバーヘッドは許容する。ORM は多少のオーバーヘッドが存在する。高トラフィックは要件に存在しないため、ORM によるオーバーヘッドは甘受する必要がある。
- 技術選定の前提条件は以下の通りである。
    1. 安定している必要がある。現状は少数精鋭の Team であるため破壊的仕様変更は回避する必要がある。
    1. サポートされているデータベース。RDBMS 以外の適合は考慮しない。DynamoDB など。
    1. Migration 機能 [^16] が必要である。仕様変更などの Database Schema 変更履歴を管理する必要がある。

|ORM|Description <br> by ChatGPT|GitHub Star|Migration|
|----|----|----|----|
|Prisma[^6] [^9]|Node.jsやTypeScriptで使用するためのモダンで強力なORM（Object-Relational Mapping）ライブラリです。Prismaは、データベースとの通信を容易にするための抽象化レイヤーを提供し、開発者がデータベースとのやり取りを行う際に生じる多くの手間を省きます。|37,300|Prisma Migrate[^17]|
|MikroORM[^5] [^10]|JavaScriptやTypeScriptで書かれたデータベースアクセスとORM（Object-Relational Mapping）を行うためのツールです。このツールは、Node.jsやブラウザーで動作し、主にJavaScriptのランタイムで動作するデータベースを操作するために使用されます。|7,200|Migrations[^18]|
|TypeORM[^4] [^11]|TypeScriptとJavaScriptで書かれたオブジェクトリレーショナルマッピング（ORM）フレームワークです。このフレームワークを使用することで、データベースとのやり取りをオブジェクト指向の形式で行うことができます。|33,400|Migrations[^19]|
|Sequelize[^3] [^12]|Node.jsで使用されるPromiseベースのORM（Object-Relational Mapping）ライブラリです。データベースとのやり取りを簡素化し、データモデルをJavaScriptオブジェクトとして扱えるようにします。|29,100|Migrations[^20]|
|Drizzle[^2] [^13]|Node.jsのための軽量なORM（Object-Relational Mapping）ライブラリです。ORMは、データベースとオブジェクト指向プログラミング言語の間でデータをマッピングするためのツールであり、開発者がSQLクエリを直接書く必要なく、データベースとのやり取りを行うことができます。Drizzle ORMは、Node.jsのプロジェクトでのデータベース操作を簡素化することを目的としています。|20,000|Migrations[^21]|
|Objection.js[^7] [^14]|Node.js プラットフォームで動作する ORM（Object-Relational Mapping）ライブラリです。このライブラリは、JavaScript の非同期性を活用して、データベースとのやり取りを行います。Objection.js は、特に PostgreSQL、MySQL、SQLite などのリレーショナルデータベースと連携するために設計されています。|7,200|N/A|
|Bookshelf[^8] [^15]|Node.jsのためのORM（Object-Relational Mapping）ライブラリです。ORMは、データベースとのやり取りを簡略化し、オブジェクト指向のアプリケーション開発を支援します。Bookshelfは、特にNode.jsとともに使用することを意図しており、特にExpress.jsと組み合わせて使うことが一般的です。|6,300|N/A|
|sqlc-gen-typescript[^1]|sqlc の Description です。この ORM は比較的新しいため、ChatGPT は学習していません。 <br> Go言語向けのSQLクエリビルダーおよびORM（Object-Relational Mapping）ツールです。Go言語は静的型付け言語であり、SQLCはこの言語の型安全性を活かしつつ、SQLクエリを書くための強力なツールとして機能します。|176|N/A|

## Decision
`todo`
- Maybe we will opt for this one. `Prisma` or `TypeORM` or `Sequelize` or `Drizzle`
- 私は Prisma を一度経験している。できれば sqlc のような軽量な ORM がいいと思う。

## Consequences
- 学習曲線。ORM を学習し実装するまでの学習曲線が必要になる。これは個人に依存する。
- パフォーマンス。Context で述べたとおり、多少のオーバーヘッドは存在する。Cache 利用や正規化/Snapshot 属性など適当な設計が必要になる。

## Compliance
- Query の Review と共に統計情報を利用して Slow Query が存在しないか確認する。

## Notes
- Author: @danny-yamamoto


[^1]: https://github.com/sqlc-dev/sqlc-gen-typescript
[^2]: https://orm.drizzle.team/
[^3]: https://sequelize.org/
[^4]: https://typeorm.io/
[^5]: https://mikro-orm.io/
[^6]: https://www.prisma.io/
[^7]: https://vincit.github.io/objection.js/
[^8]: https://bookshelfjs.org/
[^9]: https://github.com/prisma/prisma
[^10]: https://github.com/mikro-orm/mikro-orm
[^11]: https://github.com/typeorm/typeorm
[^12]: https://github.com/sequelize/sequelize
[^13]: https://github.com/drizzle-team/drizzle-orm
[^14]: https://github.com/vincit/objection.js
[^15]: https://github.com/bookshelf/bookshelf
[^16]: https://qiita.com/to3izo/items/7b8d44021cb386de2ef7#%E3%83%9E%E3%82%A4%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A8%E3%81%AF
[^17]: https://www.prisma.io/docs/orm/prisma-migrate
[^18]: https://mikro-orm.io/docs/migrations
[^19]: https://typeorm.io/migrations
[^20]: https://sequelize.org/docs/v6/other-topics/migrations/
[^21]: https://orm.drizzle.team/docs/migrations