【2022最新版?】Next.js+Prisma+PlanetScale+Firebase AuthでTodoアプリのテンプレート
こんにちは。気づけば年末です。
今年1年を振り返って、「Webアプリ新規で作ってないなぁ。Nextjsの変更も追えてないしPlanetScaleも触ってみたい」と思ったので、認証API付きTodoアプリを作ってみました。
結構実用的なテンプレートができたのではないかと思っています。
作ったもの
コードはこちら
ページ構成
-
/
: index -
/todo/ssr
: SSR で DB から Todo を取得して表示してます -
/todo/csr
: CSR で DB から Todo を取得して表示、フォームを使って投稿。
API
Next.js でバックエンドの API も構築しています。firebase のidToken
でBearer認証
しています。
GET /api/todos
POST /api/todos
DELETE /api/todos/{id}
感想
prisma
超便利。yarn prisma db push
でテーブル変更できるの便利すぎる
テーブル定義はこんな感じ
API Routes
何気に使うのは初めて。簡単なCRUDならこれで十分では??
公式のサンプルを見ると、methodでswitchさせるのがちょっと微妙だったので、
この方のコードをとても参考にさせていただきました。
最終的にはこんな感じ
アクセストークン(firebase auth匿名ログイン)の検証
せっかくなので、認証付きAPIを作ってみました。↑のapiRoute
の中に実装して共通化しました。
(本当はNext.jsのmiddleware
を使ってみたかったけど、エラー出てちょっと難しそうだったので今回はこっちで)
-
NextApiRequest
の型を拡張して、user
を追加
クライアント
Next.js 13のAppDirectoryを使いました
認証周り
Firebase Auth
の匿名ログインを使っています。
ログイン周りの処理の共通化はcatnoseさんのこちらの記事を参考にしています。
API叩くときは、axios
のinterceptor使って、idToken付けてます
ライフサイクル周りがちょっとハマった
firebaseログインチェック
が終わってからクライアントでGET /todos叩く
を行わないと、GET /todos
を叩くときにidToken
がうまく取れない。このタイミング調整に若干ハマりました。最終的にはisChecking
でログインチェック中は、ページをrenderしないようにしました。
'use client'
import { useCurrentUser } from '@/lib/client/hooks/useCurrentUser'
export default function TodosLayout({ children }: { children: React.ReactNode }) {
const { isChecking } = useCurrentUser()
if (isChecking) return <div>isLoginChecking...</div>
return (
<div className="min-h-screen flex flex-wrap">
<div className="w-full">{children}</div>
</div>
)
}
最近Nuxt
を触る機会が多いので、Nuxt
だとmiddleware
とか、onMounted
とか、名前がついてて、順番がわかりやすいよなとは感じました。
SSR時のrevalidateが怪しい
revalidate = 0
, dynamic = 'force-dynamic'
, fetchCache = 'force-no-store'
にして、DBからのgetTodos
をキャッシュしないようにしたいが、結構変更が反映されない
console.logで見たらgetTodos
が呼び出されないときが結構あるみたい
Githubのディスカッションにも上がってるが、バグってるのか、使い方が悪いのか...
(AppDirectory自体experimentalですし、ちょっと様子見かな)
気になってる点
-
terraform
でvercel
にデプロイ- awsではterraform使ってるのでvercelでも使ってみたい
-
PlanetScale
が結構遅い- POST、DELETEのAPIで2秒くらいかかるときがある。遅くね??なんか、まずい設定したかな...
Discussion