Next14でSupbaseを使ってみる
公式チュートリアルをやってデータの表示をやってみよう
Next14を使用して、Supabase公式を見ながら作成したnotesテーブルからデータの取得をやってみた。
Supabase プロジェクトの作成
database.newにアクセスし、新しい Supabase プロジェクトを作成します。
プロジェクトが起動したら、テーブルエディタで新しいテーブルを作成し、データを挿入します。
また、プロジェクトのSQLエディタで以下のスニペットを実行することもできます。これで、いくつかのサンプルデータを含むノートテーブルが作成されます。
-- Create the table
create table notes (
id bigint primary key generated always as identity,
title text not null
);
-- Insert some sample data into the table
insert into notes (title)
values
('Today I created a Supabase project.'),
('I added some data and queried it from Next.js.'),
('It was awesome!');
alter table notes enable row level security;
RLS ポリシーを追加することで、テーブルのデータを一般に読めるようにします:
create policy "public can read notes"
on public.notes
for select to anon
using (true);
Next.jsアプリの作成
create-next-appコマンドとwith-supabaseテンプレートを使って、次のように設定されたNext.jsアプリを作成します:
Cookieベースの認証
タイプスクリプト
Tailwind CSS
npx create-next-app -e with-supabase
Supabase環境変数の宣言
.env.exampleを .env.localにリネームし、Supabaseの接続変数を入力します:
NEXT_PUBLIC_SUPABASE_URL=<SUBSTITUTE_SUPABASE_URL>
NEXT_PUBLIC_SUPABASE_ANON_KEY=<SUBSTITUTE_SUPABASE_ANON_KEY>
こんな感じでやります。
Next.jsからSupabaseのデータをクエリする
app/notes/page.tsxに新しいファイルを作成し、次のように入力します。
これにより、Supabaseのノートテーブルからすべての行が選択され、ページにレンダリングされます。
import { createClient } from '@/utils/supabase/server';
export default async function Notes() {
const supabase = createClient();
const { data: notes } = await supabase.from("notes").select();
return <pre>{JSON.stringify(notes, null, 2)}</pre>
}
server.tsも必要なので作成する。
import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'
export function createClient() {
const cookieStore = cookies()
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return cookieStore.getAll()
},
setAll(cookiesToSet) {
try {
cookiesToSet.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options)
)
} catch(e) {
// The `setAll` method was called from a Server Component.
// This can be ignored if you have middleware refreshing
// user sessions.
console.error(`supabase connet error: ${e}`)
}
},
},
}
)
}
notes/のURLにアクセスするとJSONのデータが表示されると思います。
このままだと分かりにくいのでUIに表示できるようにJSONのデータを変換して表示しましょう。lists/page.tsx
を作成しましょう。
コードの説明をすると、コメントの通りnotesテーブルのスキーマのデータ型の定義に合わせてtypeでデータ型を定義しています。
Next14はServer Component(RSC)を使うことができて非同期関数のasyncを書くことができ「コンポーネント上から直接外部Web APIのデータを取得してレンダリングする」といったことが可能。
import { createClient } from "@/utils/supabase/server";
/**
* @type Note
* notesテーブルのスキーマのデータ型に合わせて定義
* @id number
* @title string
*/
type Note = {
id: number;
title: string;
};
/**
* @Server Component(RSC)
* Next14はServer Component(RSC)を使うことができて非同期関数のasyncを書くことができ
* 「コンポーネント上から直接外部Web APIのデータを取得してレンダリングする」
* といったことが可能
*/
export default async function Lists() {
const supabase = createClient();
const { data: notes, error } = await supabase.from("notes").select("id, title");
if (error) {
console.error("Supabaseクエリエラー:", error);
return <div>データの取得中にエラーが発生しました。</div>;
}
return (
<div>
<h1>ノート一覧</h1>
<ul>
{/* mapで新しい配列を生成する。 */}
{notes?.map((note: Note) => (
<li key={note.id}>{note.title}</li>
))}
</ul>
</div>
);
}
まとめ
Firebaseと比較すると使いやすそうだと思った。連携するための設定も予め公式が用意してくれているので親切なところがある。最近は日本国内のWeb開発でも使われてきているので自分も取り入れてみたいと思っていたりする。
Discussion