DenoでHonoやReactを使ったテンプレートを作ってみた

gif

Deno で本格的な Web システムを作るためテンプレートを作ってみた。

backend と frontend で完全に分かれていて RESTful API で通信するようにした。

仕様

  • deno-vite-react-template
  • deno-hono-api-template
    • Hono による RESTful API サーバー
      • RPC も使いたかったけど今回は汎用性を考えて不採用
    • PostgreSQL
    • migrate によるマイグレーション管理
    • kysely による SQL ビルディング
    • djwt による JWT 認証
    • deno_mocha によるテスト
      • deno test では afterAll などにバグがあったため
    • zod によるバリデーション
  • 共通
    • VS Code Devcontainer で開発できるようにしてある
    • Linter, Formatter に Biome を使用。 Biome は速くてよい
    • spacetime 便利

機能

  • email/password によるサインイン
  • 多言語対応 ( i18n )
  • タイムゾーンや日付の表示形式の変更
  • ダークモード
  • 認可 (Roles, Permissions)
  • Todo リスト (CRUD のサンプルとして)
  • 招待 URL によるサインアップ
  • 各種テスト (frontend 側が途中)

設計的な部分

email/password によるサインイン

JWT による email / password サインイン。 特筆することはないけど、 Hono の middleware の jwt がなんとなく使いづらかったので djwt というライブラリで自作した。 djwt はシークレットキー以外にも公開鍵秘密鍵での JWT の sign/verify が出来たのでそれを採用してみた。

generate-jwt-key.ts を用意したのでこれで鍵が作れる。

多言語対応 ( i18n )

色々ライブラリを調べたけど、結果的には jotai を活用して単語帳を作ることにした。

この単語帳を次のコンポーネントで扱えるようにする

<Trans>Hello</Trans>

みたいにすると単語帳に Hello に対する単語があれば日本語に変換してくれるし、なければ英語のまま表示する。

一応、 printf のフォーマットで変数も埋め込めるようにした。

タイムゾーンや日付の表示形式の変更

これもライブラリを使わず自作。

spacetime にタイムゾーン変換やフォーマット機能があるので その入力方式をフロント側で設定してバック側でDBに保存するというシンプルな方式。

これも便利コンポーネントを用意しておいた。

ダークモード

Chakra UI のダークモード機能に乗っかっているが、これは Cookie とかに記録する方式なので DB 保存でも良い気がする。

認可 (Roles, Permissions)

認可も最近はライブラリを使わず DB のテーブル構成でなんとかしている。

マイグレーションファイル をみると DB の作りがわかると思うのだが、

users -> users_roles -> roles -> roles_permissions -> permissions

というリレーションがある。 機能名を permissions テーブルに設定しておいて、それを roles に割り当てる。 users には roles を割り当て、 permissions は直接見ないようにする。 これにより、「ユーザーにはロールを割り当てる」「ロールには権限を割り当てる」という構造ができ、 認可を管理しやすくなる。

これは UI を見たほうがわかりやすいかもしれない。

users_roles roles_permissions

サーバー側では次のように permissionChecker という middleware で permission 名を指定しておいて、 サインイン中のユーザーがその permission を持っていなければ機能が使えないようにしている。

app.post("/", permissionChecker("todos"), async (c) => {
  //...
})

フロント側も Can というコンポーネントで同じようなことができるようにした。

Todo リスト (CRUD のサンプルとして)

CRUD のサンプルのつもりで簡単な TODO リスト機能を作っておいたけど、結構認可とかユーザー設定のほうも CRUD が多くなったのでそっち見たほうがいいかもしれない。

招待 URL によるサインアップ

invitations

discord みたいにトークン付きの URL からサインアップできるようにしてある。

「コピー」ボタンをクリックすると招待URLをコピーできて、これを招待したい人に渡す。

トークンが有効であれば、サインアップ画面が出てくる。

sign up

各種テスト (frontend 側が途中)

サーバー側は models と routes のテストを書いてある。

Deno の標準の Test 機能で十分かと思ったが AfterAll 系の callback 処理で不具合があって、 async がからむとうまく動かなかったので、 deno_mocha を使うことにした。 今のところ大丈夫そう。

frontend 側のテストも vitest + happy-dom で作るつもりだが、まだ出来ていない。

まとめ

今後の開発でよく使うであろう機能をとりあえずテンプレートに出来たのは役に立ちそうだ。 色々とオレオレな仕様なので他の人は使いづらいかもしれないが、適当に改造して使ってほしい。

具体的な動かし方とかはもう少し README あたりに記載が必要だと思うので追々対応する予定。

Deno, Hono, Vite, あたりの組み合わせた動かし方は本当に資料が少なくて、今回の テンプレート公開が誰かの役に立ったら嬉しい。

私は個人的に作っている FAM というシステム (Discord クローンみたいなもの) で このテンプレートを活用していくつもりだ。


掲示板にコメントする
※どの記事のコメントかわかるように本文に記事タイトルなどを入れてください。
一覧に戻る