見た映画の感想を管理するアプリ「FilmDeX」を作った 前編

自分は映画が好きで、このサイトのブログでもそれなりに映画レビューの記事を書いてきた。ただ、ブログ記事は見た時に何となく書いているので、一覧性に欠ける。

自分は果たしてどれだけの映画を見てきたのか?それらはどんな映画だったっけ?誰が出演していたっけ?同じ監督の作品はどれくらい見てきただろうか?

そういう「僕が見た映画データベース」を作りたい欲求は5年ぐらい前から考えていた。当初は Rails で作ろうかなーと考え、作りかけたところで放置。Perl・PHP・Python CGI をイジイジしていた数年前もなんか出来ないかなーと考えていたが、形にならず。そして今回ようやく、Angular + NestJS でウェブアプリを作成した。その名も FilmDeX

↑ GitHub Pages で閲覧できる。

↑ GitHub リポジトリ。

エンドユーザの皆様としては、GitHub Pages で映画情報を見ていただくだけ。ただ、裏側は色々と試行錯誤したので、その経緯を以下に書いていく。

目次

安定の Angular

フロントエンドには安定の Angular を使った。皆なんで React や Vue を選択してわざわざ苦労してるんだろう?CSS-in-JS の話とか周辺ライブラリの選定とか、ホントいつまでやってんの?プロジェクトの設計じゃなくて早く実装しろよと思って見てる。

Angular はその辺フルスタックで全部用意されてるので、さっさと Angular Way に乗っちゃえば実装に専念できる。完全に TypeScript に対応しているのもスゲー楽。今回は頑張って any で逃げないようにコーディングしてみた。仕事でしょーもないウンコードばっかり見せられてゲンナリしているので、自分が思うキレイなコードを追求できて自己満足した。

NestJS を使ってみたかった

最終的には NestJS で作った部分をゴッソリ捨てたのだが、今回試しに使ってみた NestJS がとても実装しやすかった。

↑ NestJS の実装部分は削除してしまったので、v1 というタグ時点のコードを参照いただきたい。以降はこの v1 時点の構成について話す。

NestJS というアプリケーションサーバフレームワークは、TypeScript 製で、Angular に似た CLI やデコレータが用意されている。公式ガイドも豊富で、とても実装しやすかった。

映画情報の登録や更新は、管理画面で行えるような作りにしてみた。よくあるパスワード認証でログインしたあと、JWT (JSON Web Token) を発行し、それで API コール時に認証をかけるようにした。この辺の仕組みも NestJS のモジュールが存在していて、イイカンジに実装できる。調べればすぐ情報が出てくるので、NestJS の作り込みで困ることはほぼなかった。

データ永続化層については、ローカルでデータを保持したい思いから、SQLite を使うことにした。NestJS からは O/R マッパーの TypeORM を使ってイイカンジに接続できる。TypeORM はリレーションの扱いで若干苦労したけど、まぁ許容範囲内。キチンと作れば TypeScript のデコレータやクラスで作ったコードは、可読性は高い。

Node.js + SQLite を稼動させられる場所がない

NestJS での実装が気持ち良く、TypeORM も使いこなし、Angular 側から NestJS 側で作った .ts クラスを import して Universal TS だーみたいな感じでウキウキで開発していたワケだが、Node.js でアプリケーションサーバを作ってしまうと、それをデプロイ・稼動させられる PaaS のホスティングサービスがほとんどないことを思い出す。さらに、PostgreSQL や MySQL を提供している無料の PaaS はあるが、SQLite を提供している PaaS はほぼなかった。

free-for-dev なども参照したが、FaaS はそこそこあれど、やはり PaaS となるとほぼない。あったとしても SQLite に対応していなかったりする。

そうなると残るは IaaS に自前で置くしかない。Always Free の OCI に試しに置いてみたら、Angular も NestJS もちゃんとビルドでき、SQLite 部分込みで正常に動作した。一応問題はないのだが、Always Free VM は低スペックなので、ココに自分以外からのアクセスがあると、参照系だけといえどもサーバの負荷が気になってくる。

というのも、当初は NestJS 側で API を用意し、SQLite から都度全量を取得し、Angular で表示するような作りにしていたのだ。となると、画面を開くたびに SQLite への SELECT が発生するので、無料サーバにとっては負荷がかかるなーと。

参照専用のクライアントアプリにしようか…

SQLite に対してデータの追加・更新をするのは、レビューを書く自分だけ。エンドユーザの皆様はデータを参照するだけ。

だったら、SQLite DB からの参照を頻繁に行う必要はなく、データを JSON ファイルにでも吐き出しておいて、サーバサイドとは接続しない参照専用のクライアントアプリを作ったら良いんじゃないか?と考え始めた。

結果的にデータを JSON ファイルで持つなら、TypeORM と SQLite を省いて、NeDB あたりを使って JSON ファイルを直接読み書きしたら良かったのでは?とも思い始めてしまう。

見た映画の情報を一覧表示するデータベースとしては、個人的に求めていた UI・機能を実現できた。こんな映画見たなー、コレ面白かったなー、みたいなのを一覧化して、シリーズモノを検索して確認したりできる UI で、とりあえず僕の欲しいモノは作れた。

ただ、「個人の趣味のプロジェクトとして、完全無料でホスティングしたい」という要件が重たく、あれこれやっている内にイビツなプロジェクトになってきた。裏側の構成検討は後編で再検討する。