Supabase とは#
supabase は、Firebase の代替となるオープンソースの BaaS プロジェクトです。さまざまな現代アプリケーションに必要な安定した、強力で、使いやすく、拡張可能なバックエンド機能を提供します。Supabase は PostgreSQL データベースと RESTful API に基づいて構築されており、認証、リアルタイムデータプッシュ、ストレージ、その他の一般的なバックエンドサービスを提供します。
サーバーを購入する必要はなく、簡単な SQL 文とデータベースの知識を持っていればバックエンドサービスを作成できます。もちろん、その機能は非常に強力で、この記事では Next.js での使用方法のみを紹介します。
Supabase の使用#
学習タスクの内容は公式ドキュメントを詳細に読む必要があります。
公式ドキュメント Use Supabase with NextJS の内容に基づいて、使用手順は以下のように分かれています。
ここでは、supabase を使用してブログの閲覧数を保存します。
プロジェクトの作成とテーブルの作成#
https://app.supabase.com/projects からプロジェクトを作成します。
SQL エディタまたはグラフィカルインターフェース DataBase を使用して、Views という名前のテーブルを作成します。
ここではグラフィカルインターフェースを使用して、Database の右上隅にある New table を使用して Views テーブルを作成します。
列の slug はブログのタイトルを示し、count は対応するブログのアクセス数を示します。
Next.js プロジェクトの作成#
npx create-next-app@latest --typescript
supabase-js のインストール#
npm install @supabase/supabase-js
supabase の作成#
ルートディレクトリに lib フォルダを作成し、supabase.ts という名前のファイルを作成します。
import { createClient } from '@supabase/supabase-js';
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL as string;
const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_KEY as string;
export const supabase = createClient(supabaseUrl, supabaseKey);
project_url と supabase_key はプロジェクトの設定オプションで見つけることができます。
同様に、key を公開することはお勧めしません。env.local に保存できます。
💡 tips: Next.js で env.local を使用するには、NEXT_PUBLIC プレフィックスを追加する必要があります。そうしないとエラーが発生します。
CRUD#
詳細なコマンドはJavaScriptドキュメントで確認できます。
ブログ記事ページを開くときに、現在のブログの閲覧数を取得する必要があります。次のように使用できます。
fetch(`/api/views`);
pages/api/views ディレクトリに index.ts を作成します。
import { supabase } from '@/lib/supabase';
import type { NextApiRequest, NextApiResponse } from 'next';
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
try {
let { data } = await supabase.from('Views').select('*');
return res.status(200).json(data);
} catch (e: any) {
console.log(e);
return res.status(500).json({ message: e.message });
}
}
SQL 文のように書くことで、Views テーブルからすべてのデータを取得できます。
また、post で slug を渡すことで、対応するデータを取得することもできます。
同時に、ブログ記事ページを開くときに、現在のブログの閲覧数を 1 増やす必要があります。そのためには、post リクエストで slug パラメータを渡すことができます。
fetch(`/api/views/${slug}`, {
method: 'POST'
});
pages/api/views ディレクトリに[slug].tsを作成します。
import { supabase } from '@/lib/supabase';
import type { NextApiRequest, NextApiResponse } from 'next';
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
try {
const slug = req.query?.slug as string;
if (!slug) {
return res.status(400).json({ message: 'Slug is required.' });
}
const { data } = await supabase
.from('Views')
.select('count')
.eq('slug', slug);
const views = !data?.length ? 0 : Number(data[0].count);
if (req.method === 'POST') {
if (views === 0) {
await supabase.from('Views').insert({ count: views + 1, slug: slug });
return res.status(200).json({
total: views + 1
});
} else {
await supabase
.from('views')
.update({ count: views + 1 })
.eq('slug', slug);
return res.status(200).json({
total: views + 1
});
}
}
if (req.method === 'GET') {
return res.status(200).json({ total: views });
}
} catch (e: any) {
console.log(e);
return res.status(500).json({ message: e.message });
}
}
新規作成には insert を使用し、更新には update を使用します。これで閲覧数を supabase に保存できます。
その他の機能#
また、supabase はバケットストレージ機能もサポートしています。私のプロジェクトでは og 画像を supabase に保存しています。
今後のプロジェクトでも supabase を使用し、Firebase の代替とします。