最終更新: a few seconds agoRemove Netlify-related code from main (grafted, HEAD)

データベース・データ保管

概要

バックエンドには MongoDB を利用する。

DB 接続には公式の mongodb NPM パッケージを利用する。最新版はデフォルトで Promise に対応しているので async/await との相性は良好。

アプリケーション起動時に DB との接続を確立し、依存性注入で使いまわす。

Mongoose という ORM 的なラッパが有名だが利用しない。今回スキーマ回りを自力で JSON Schema で処理する必要があり、Mongoose を使うメリットが乏しいため。

ただし直接 Node.js のメソッドを叩くとバリデーションや時間処理など我々のアプリ固有の処理が行えないので、モデルとなる薄いラッパを被せる。db/createCollectionAccessor.js を参照。

モデルは Mongo の各コレクション毎に対応するものが作成され、models として各所に注入される。

基本的な使用例

具体的なコードについてはテストケースも参照。

export function getuserHandler({ models }) {
	export async function getUserHandler(ctx, next) {
		// URLに含まれるパス
		const id = ctx.params.userEmail;

		// 指定したキーに対応するユーザを1件取得する。
		// `ctx.models.user` は既にコレクションおよびスキーマと
		// 関連付けられており、データに誤りがあった場合は
		// 例外がスローされる。
		// その例外は自動的に上位の `errorHandler` で処理するので自前処理は不要。
		const user = await models.user.findByIdOrFail(userEmail);
		ctx.body = user;
	}
}

export function putUserHandler({ models }) {
	export async function putUserHandler(ctx, next) {
		// JSON Schemaによるバリデーションが行われるので例外は勝手に処理される。
		await models.user.insertOne(ctx.request.body);
	}
}

DB のマイグレーション

src/scripts/migration.js を参照。

「ストレージ」の概念について

src/storage の中身を参照。

システムでは大きなバイナリファイル(以下 BLOB)を扱う必要があり、これらは DB に直接保管しないので、これを扱う方法を標準化する。

  • DICOM ファイル自体 (*.dcm)
  • ラベルのボクセルデータ(塗り絵データ)
  • CAD プラグインからの出力

現時点ではローカルのファイルシステムないしローカルファイルシステムにマウントされた NAS に保管するもののみ準備しているが、この部分は「ストレージ」として抽象化されている。AWS S3 互換のオブジェクトストレージ(含:Amazon S3, Google Cloud Storage, Azure BLOB Storage)を将来的に使えるようにする。