8
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

HonoAdvent Calendar 2024

Day 8

HonoとCloudflareのサービスでHeadless CMSを作った

Posted at

HonoとCloudflareのサービスでHeadless CMSを作った

作ったと言ってますが、まだまだ開発途中です。ただ、メインの機能は大体実装しました!

TL;DR

  • honoとcloudflare workers, pagesの相性は最強レベル
  • honoを利用することで、フルスタックアプリケーションのバックエンド部分に変更をほとんど加えないまま、フロントエンド部分を差し替えられる
  • honoとvitest、@cloudflare/vitest-pool-workersの組み合わせのDXは素晴らしい
  • 実装方法によっては意外とレスポンスが遅い

経緯

ある日Xで

HonoHub

という、HonoをベースとしたHeadless CMSのOSSを見つけました。
HonoとVite, Drizzle, Zodベースでありすごくモダンで触ってみたい!と思い早速試してみました。
ただ、ドキュメントではDBがneonというpostgresベースのDBaaSを紹介されており、自分はここでCloudflare D1を使いたかったため、断念しました。
https://honohub.dev/quickstart#setting-up-hono-hub

ないなら自分で試してみようと思い、1から作ってみることにしました。

github

edge-cms

機能

  • 管理画面上でのデータスキーマ作成
  • 記事CRUD機能
  • ユーザー認証機能(認可処理は未実装)

技術スタック

Hono, Vite, Zodベースは変更せず、Cloudflareのサービスのみで運用できるように技術選定を行いました。

  • Cloudflare群
    • Cloudflare workers (with service bindings)
    • Cloudflare D1 (Sqlite)
    • Cloudflare R2
    • Cloudflare Pages
  • 言語
    • Typescript
    • SQL
  • フレームワーク
    • Hono
    • Vite
    • React Router v7
  • ライブラリ
    • テストライブラリ
      • vitest
    • バリデーションライブラリ
      • zod
    • モノレポツール
      • turbo
    • リンタ&フォーマッタ
      • biome
    • DB
      • sqlc
    • UI
      • shadcn/ui

Web API構築はHonoとzodを利用しており、apiのコアの依存パッケージはHonoとzodのみです。
管理画面はRemixで構築しました。開発途中でReact Router v7が安定版リリースしましたので、React Router v7に乗り換えました。UIは主にshadcn/uiを利用しました。

スクリーンショット 2024-12-08 16.04.03.png

ディレクトリ構造

TurboRepoを利用し、モノレポを採用しています。

.
├── README.md
├── apps
│   ├── admin
│   ├── docs
│   └── sandbox
├── biome.json
├── lefthook.yml
├── package.json
├── packages
│   ├── auth
│   └── core
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── renovate.json
└── turbo.json

ポイント

ここまで、概要をざっくり説明してきましたが、今回Honoを採用してみてすごく良かった点を紹介します。

テストが異常に簡単

Hono公式にもドキュメントがあり、セットアップが簡単にできました。

@cloudflare/vitest-pool-workers/configを利用します。
Cloudflare D1等Cloudflareサービスをモックするために以下のようにvitest.config.tsを設定します。

import path from "node:path";
import {
	defineWorkersProject,
	readD1Migrations,
} from "@cloudflare/vitest-pool-workers/config";

export default defineWorkersProject(async () => {
	// Read all migrations in the `migrations` directory
	const migrationsPath = path.join(__dirname, "db");
	const migrations = await readD1Migrations(migrationsPath);

	return {
		test: {
			globals: true,
			setupFiles: ["./test/apply-migrations.ts"],
			poolOptions: {
				workers: {
					singleWorker: true,
					wrangler: {
						configPath: "./wrangler-test.toml",
						environment: "production",
					},
					miniflare: {
						// Add a test-only binding for migrations, so we can apply them in a
						// setup file
						bindings: { TEST_MIGRATIONS: migrations },
					},
				},
			},
		},
	};
});

テスト時に使用するwrangler-test.tomlを作成します。

name = "core"
main = "./src/index.ts"
compatibility_date = "2024-01-01"
compatibility_flags = ["nodejs_compat"]


[env.production.vars]
AUTH_SECRET = "test"
JWT_SECRET = "test"

[[env.production.kv_namespaces]]
binding = "KV"
id = "00000000000000000000000000000000"

[[env.production.r2_buckets]]
binding = "R2"
bucket_name = "r2-bucket"


[[env.production.d1_databases]]
binding = "DB"
database_name = "database"
database_id = "00000000-0000-0000-0000-000000000000"

ここまで行うと、vitestでwatchオプションを使用しながら、快適に実装を進めることができます!

フロントエンドとの密な連携を実現しながら、フロントエンドのフレームワークに依存しない

honoのRPCを使用することにより、型安全にAPIにアクセスできます。
しかもhonoはWeb標準に則って実装されており、Web標準のRequest, ResponseをIOにとるサーバーサイドフレームワークであれば簡単に結合できます。
つまり、Next,Remix,Nuxt等のフルスタックフレームワークのサーバーサイド部分でHonoを利用できるということです。

Honoでサーバーサイドを実装することで、型安全なRPCを実現しながらフレームワークを柔軟に差し替えることができ、これは大きなメリットだなと思いました。

原因は調査中だが、意外とレスポンスが速くなかった。

ログイン機能等もhonoで実装したのですが、意外とレスポンスが速くなかったです。これはD1とのやりとりも必要かつキャッシュも使えない?からと思われます。とは言っても許容できないような遅さではないので、時間があったら調査しようと思います。

まとめ

HonoとVite、そしてCloudflareのサービスは非常に相性が良く、特に小規模から中規模のサービス開発において大きな利点があると考えています。
これらを組み合わせることで:

  • 開発速度の大幅な向上が見込める
  • 各機能間の連携を密に保ちながらも、適度な独立性を維持できるため保守性が高い
  • Cloudflareのサービスを活用することでコスト面でも優位性がある
    以上の特徴から、実務での採用を検討する価値が高いスタックだと考えています。
8
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?