この記事は マイナビ Advent Calendar 2021 23日目の記事となります。
Firebaseの代替になるのでは?と巷で話題のSupabaseを試してみました。
FirebaseはNoSQLでデータを扱うことに対して、SupabaseはデータベースにPostgreSQLを使用していると聞いて、興味が沸きましたので、今回触れてみたいと思います。
Supabaseとは
「Firebase Alternative」を謳っており、オープンソースとして公開されています。
いわゆるBaaS(Backend As A Service)と呼ばれるサービスです。
2021年12月現在、提供されているサービスはDatabase、Authentication、Storageの3つとなっています。(近いうちにFunctionsが公開されそうです。)
個人的には馴染みのあるSQLでデータを扱うことができるのは結構熱いなと思います。
NoSQLは少し癖があり、学習コストもそこそこ高いのがネックだったと思うので、RDBの選択肢が増えるのはバックエンドエンジニアにとっては朗報だと感じます。
Work
今回は、公式が公開しているTODOリストアプリを動かしてみたいと思います。
また、実際に手を動かして実装を進めたい方向けに、ハンズオン形式のチュートリアルがあります。
アカウント作成
まずはアカウントを作成します。
現在はGitHubアカウントでのログインのみとなっております。
プロジェクトを作成
ログインが完了後、イケてる管理画面が表示されますので、今回使用するサンプルのプロジェクトを作成したいと思います。
ボタンを押下後、以下のフォームが表示されます。
プロジェクト作成後、APIキー、URLが確認できるようになります。
後ほど利用するので、メモしておきましょう。(管理画面からいつでも確認できます。)
## データベースを作成
先にアプリで使用するテーブルを作成したいと思います。
サイドバーに表示されているSQL editorのアイコンをクリックし、以下のSQLを入力します。
CREATE TABLE lists (
uuid text,
id bigserial PRIMARY KEY,
inserted_at timestamp without time zone DEFAULT timezone('utc' :: text, now()) NOT NULL,
updated_at timestamp without time zone DEFAULT timezone('utc' :: text, now()) NOT NULL
);
CREATE TABLE tasks (
task_text text NOT NULL,
complete boolean DEFAULT false,
id bigserial PRIMARY KEY,
list_id bigint REFERENCES lists NOT NULL,
inserted_at timestamp without time zone DEFAULT timezone('utc' :: text, now()) NOT NULL,
updated_at timestamp without time zone DEFAULT timezone('utc' :: text, now()) NOT NULL
);
alter publication supabase_realtime add table lists;
alter publication supabase_realtime add table tasks;
RUNボタンを押下後、テーブルが作成されていることが確認できます。
サンプルコードをclone
データベース作成後は、サンプルのコードをcloneします。
git clone https://github.com/supabase/supabase.git
.envファイルを作成
まずは、サンプルコードが保存されている階層に移動します。
cd supabase/examples/react-todo-list-collaborative
移動した階層に.env
ファイルを作成し、先程メモしたAPIキーとURLを入力し、保存します。
REACT_APP_SUPABASE_URL=<your-supabase-url>
REACT_APP_SUPABASE_KEY=<your-supabase-key>
アプリを動かしてみる
サンプルのコードを動かす準備できましたので、実際に動かしてみます。
先程の階層で以下のコマンドを実行します。
npm install
npm start
その後、ブラウザで以下の画面が表示されます。
new task list
ボタンを押下後、TODOリスト画面が表示されます。
add task
ボタンでタスクを追加後、管理画面を確認すると、しっかりデータが登録されていました。
コードを見てみる
サンプルコードでは、カスタムフックにSupabaseの呼び出し部分がまとめられています。
以下、ソースからデータ操作部分を抜粋
export const addTask = async (task_text, list_id) => {
try {
let { data, error } = await supabase.from('tasks').insert([{ task_text, list_id }])
if (error) {
throw new Error(error)
}
return data
} catch (error) {
console.log('error', error)
}
}
export const updateTask = async (task_id, values) => {
try {
let { data, error } = await supabase.from('tasks').update(values).eq('id', task_id)
if (error) {
throw new Error(error)
}
return data
} catch (error) {
console.log('error', error)
}
}
export const createList = async (uuid) => {
try {
let { data, error } = await supabase.from('lists').insert([{ uuid }])
if (error) {
throw new Error(error)
}
return data[0]
} catch (error) {
console.log('error', error)
}
}
export const fetchList = async (list_uuid) => {
try {
let { data, error } = await supabase
.from('lists')
.select(`*, tasks(*)`)
.eq('uuid', list_uuid)
.single()
if (error) {
throw new Error(error)
}
return data
} catch (error) {
console.log('error', error)
}
}
データの操作部分も.from
や.select
といった、馴染みのある単語を使用しているので分かりやすいですね!
感想
現在担当しているプロジェクトでFirebaseを使用しているのですが、正直NoSQLの作法に中々慣れず苦労していました。
SupabaseのようにRDBでデータを扱えると、学習コストも低く、設計もより簡単にできるだろうなと感じています。
まだベータ版ということもあり、本番での運用が難しいところではありますが、今後の発展がとても楽しみです。
参照