16
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Cloudflare Pages/D1】個人開発のためのローリスクなクラウドを探し求めてCloudflareに出会う【Next.js】

Posted at

はじめに

以前こんな記事を書いたのですが、

個人開発でWebサービスの作るのに
リスクを下げることの重要性を痛感したことがありました。

なので、また懲りずに新しいWebサービスを作ったのですが、
できるだけローリスクを心がけて開発した。

ここで心がけたローリスクっていうのは、
開発と運用にかかるコスト・学習コスト・保守コスト
をできるだけ低くすることで、
失敗しても受けるダメージを少なくするということです。

ローリスクのために色々考えていたら、
無料で使える枠が多くて、D1が正式にリリースされた
Cloudflareが良さそうだったので、
その話を中心に書きたいと思います。

宣伝

ローリスクを意識しすぎるとその分クオリティが低くなってしまいそうですよね。
なので宣伝ついでに実物を見てもらえると幸いです。

前回に続きまた推し活系のWebサービスを作りました。
今回の推したいむは推しと推しのイベントを登録して、
推しのスケジュールをファン同士で共有して、
その中から自分が参加するイベントをフォローするこで、
自分の推し活カレンダーがつくれるサービスです。

環境

構築環境とそれを選んだ理由

Cloudflare Pages

フロントエンドサーバー

  • 無料で無制限のサイト・無制限のリクエスト・無制限の帯域幅・500回のビルド/月
  • 商用利用可能
  • データベースも一緒に構築可能

Cloudflare D1

データベースサーバー

  • 5GBまで無料
  • SQL

Next.js

フロントエンドフレームワーク

  • 使い慣れてる
  • ネットに記事が多い
  • ライブラリが豊富

Tailwind CSS

CSSフレームワーク

  • Cloudflare Pagesと相性がいい
  • Next.jsと相性がいい
  • CSSが苦手でも使える
  • デザインが苦手でもそっれぽくなる

shadcn/ui

CSSフレームワーク

  • Tailwind CSSと相性がいい
  • Next.jsと相性がいい
  • デザインが苦手でもさらにそっれぽくできる

Drizzle ORM

ORM

  • Cloudflare D1との相性がいい

Hono

バックエンドフレームワーク

  • Drizzleと相性がいい

つまずきポイント

Cloudflare Pages・D1はまだあまり日本語での記事が少なく、
つまずきポイントがいくつかあったので解説したいと思います。

Next.js

Next.jsをNext.jsでビルドするにはランタイムをEdge Runtimeに設定します。
Firebase AuthなどEdge Runtimeに対応していないライブラリがあるので、
その辺の注意が必要です。

Firebase Auth

Edge Runtime に対応していないため断念
next-firebase-auth-edgeを使えばいけるかもしれない?

Firebase Auth が使えなくてもGoogle認証するだけなので NextAuth を使用する

NextAuth.jsはv5

NextAuth v4 は Edge Runtime に対応していないので
2024/2/14時点ではbetaをインストールしないとCloudflare pagesでビルドできない

$ npm install next-auth@beta

Chakra UI

Cloudflare pages で Emotion に依存しているUIフレームワークは使えない
代わりに Tailwind CSS と shadcn/ui を使用

環境変数でAUTH_TRUST_HOST=true

clodflare Page でデプロイしたら
/api/auth/session が 500 Internal Sever Error でログインしようしても
Sever error と表示されてしまう
image.png
環境変数に AUTH_TRUST_HOST=true を追記する必要がある

NEXTAUTH_URL="http://localhost:8788/api/auth"
でAPIからauth()呼び出すしてもnullにならなくなる

wrangler.toml
[vars]
GOOGLE_CLIENT_ID=【hoge.apps.googleusercontent.com】
GOOGLE_CLIENT_SECRET=【GOOGLE_CLIENT_SECRET】
NEXTAUTH_SECRET=【Secret】
NEXTAUTH_URL="http://localhost:8788/api/auth"
AUTH_TRUST_HOST=true

HonoからD1接続

まず cloudflare のページで D1 の設定をし、
HonoからD1を呼び出そうとしたらエラーが出ました。

api/[...route]/route.tsx
import { Hono } from "hono";
import { drizzle } from "drizzle-orm/d1";
import { users } from "../../../../schema";

export const runtime = "edge";

// This ensures c.env.DB is correctly typed
type Bindings = {
  DB: D1Database;
};

const app = new Hono<{ Bindings: Bindings }>().basePath("/api");

app.get("/user", async (c) => {
  const result = await drizzle(process.env.DB).select().from(users).all();
  return c.json(result);
});

export const GET = app.fetch;
export const POST = app.fetch;

で process.env.DB でenvにDBがないと怒られます。
なので process から Bindings に接続できるように
以下の追記をします。

env.d.ts
declare global {
  namespace NodeJS {
    interface ProcessEnv {
      DB: D1Database;
    }
  }
}

このままだとローカルで試すとデータベースが空になってしまうので
以下を追記

wrangler.toml
[[ d1_databases ]]
binding = "DB" # i.e. available in your Worker on env.DB
database_name = "oshitime"
database_id = "10cc517a-17a4-4e13-9095-57babdd91e2e"
migrations_dir = "drizzle/migrations"
preview_database_id = "DB" # <-- 特にこれ注意
...

これ試しに実行して確認

$ npm run pages:preview   

さいごに

Cloudflareは心配になるくらい無料で使用可能な枠がでかいです。
個人開発でその辺をネックに感じていた人は検討の余地大アリです。
あと推したいむX(Twitter)アカウントの方もよろしくお願いします。

16
3
0

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
16
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?