🎧

MVP 開発で Next.js・Supabase を採用してみた

2024/08/08に公開

概要

友人と開発中のプロダクトで、Supabase を採用しました。この記事は、採用理由や活用してみての感想です。

アーキテクチャ

アーキテクチャの概略図は次の通りです。

  • フロントエンドは Next.js で構築しています。
  • データベースや認証基盤には Supabase を採用しています。

選定理由

フロントエンドの技術・開発にフォーカスできることを目指したアーキテクチャにしています。
フロントエンドはメンバーが使い慣れている Next.js を採用しました。
また、フロントエンドに集中するためにバックエンドを手軽に構築し、更新することができる Supabase を採用することにしました。
サーバ、インフラのリソースを持たずに済むこともポイントの一つでした。

背景

背景として

  • チームメンバーが少数
  • 開発スピードを重視してできるだけ早くプロダクトを開発したい

といった状況でした。そのため、バックエンドやインフラ周りはプラットフォームに頼り、フロントエンドの開発に集中できる状態を目指していました。

検討した代替案

Firebase

  • Firebase の NoSQL よりも、Supabase が採用している Postgres のRDB構成のほうが設計に慣れている
  • プロダクトとして高度な検索機能が必要になりそう

といった理由から Supabase を採用しました。

活用方法

ローカル環境は、Supabase CLI を使って構築しています。

Supabase CLIを使うことで、ローカルに本番環境と同じテーブル・各種設定、シードデータ入りのインスタンスを用意しています。
また、自動テストやGitHubへのプルリクエスト後のCI実行も行っています。

テスト

Supabase では、クエリが期待どおりのデータを返すかなどを確認するために自動テストを作成できます。
https://supabase.com/docs/guides/database/testing

Github Actionsを利用して各種テストケースを走らせています

test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
      - uses: supabase/setup-cli@v1
        with:
          version: latest

      - run: supabase db start
      - run: supabase db lint
      - run: supabase test db

...

公式が提供しているサンプル。
https://github.com/supabase/supabase-action-example/blob/main/.github/workflows/ci.yaml

マイグレーション

マイグレーション管理も、Supabase CLIを利用しています。
https://supabase.com/docs/reference/cli/supabase-migration-new

本番環境へのマイグレーションは、GitHub Actionsで行っています。

name: Migration

on:
  push:
    branches: 
      - 'main'
    paths:
      - 'supabase/migrations/**' # migrationsディレクトリ配下に変更があったときのみ起動
  workflow_dispatch:

jobs:
  migrate:
    runs-on: ubuntu-latest
    environment:
      name: production
      url: ${{ steps.deploy.outputs.url }}
    env:
      SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
      SUPABASE_DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
      SUPABASE_PROJECT_ID: ${{ secrets.SUPABASE_PROJECT_ID }}
      DATABASE_URL: ${{ secrets.DATABASE_URL }}

    steps:
      - uses: actions/checkout@v4

      - name: Setup Supabase CLI
        uses: supabase/setup-cli@v1
        with:
          version: latest

      - name: Link Supabase Project
        run: supabase link --project-ref ${{ env.SUPABASE_PROJECT_ID }}

      - name: Deploy Migrations
        run: supabase migration up --linked

クライアントライブラリ

supabase-js を利用しています。
https://github.com/supabase/supabase-js?tab=readme-ov-file

また、 Supabase CLIで、データベースの型情報を生成することができます。

supabase gen types typescript --project-id "$PROJECT_REF" --schema public > types/supabase.ts

代替案

マイグレーション管理やクライアントライブラリに Prisma を利用するか考えました。
https://supabase.com/partners/integrations/prisma
https://www.prisma.io/docs/orm/overview/databases/supabase
公式ドキュメントや導入記事もあるのですが、
Supabase SDK や CLI で完結するのにあえて入れる必要もないと感じ(Supabaseに依存したくないという観点はある)、外部ORM は採用しませんでした。

導入してみての所感

  • supabase-cliを使ったローカルの環境構築が簡単
  • ダッシュボードが使いやすい

環境構築は非常にスムーズに行うことができました。
開発も、今のところ大きく困ったことはなく体験が良いです。
運用に関する知見はこれからです。

その他

Makefile

Makefile を利用して環境構築を簡単に終わらせられるようにしています。

.PHONY: setup-local
setup-local: ## ローカル環境用のセットアップを行う
	@if [ ! -e .env.local ]; then \
  		cp .env.template .env.local; \
	fi
	@if ! brew list supabase >/dev/null 2>&1; then \
  		brew install supabase/tap/supabase; \
	fi
	@if ! command -v dotenv >/dev/null 2>&1; then \
  		npm install -g dotenv-cli; \
	fi
	@$(MAKE) generate

run-supabase: ## supabase 起動
	supabase start

run-dev: ## npm run dev
	npm run dev

.PHONY: run
run: setup-local run-supabase migrate-up run-dev ## ローカルでアプリケーションを起動する

.PHONY: migrate
migrate: ## supabase cliで マイグレーションファイルを作成する
	@read -p "migration 名を入力: " name; \
	supabase migration new $$name

migrate-up:
	supabase migration up

...

Discussion