Supabaseの関数をNext.jsアプリから呼び出す
前回の記事でSupabaseの認証と認可について紹介しました。
Supabaseでは、ミドルウェアを介さずに、クライアントが直接データベースに接続するアーキテクチャーを実現できます。
このようなアーキテクチャーを構築する上で、もう1つ便利な機能として関数があります。
Supabaseでは、データベースにRESTfulなAPIを自動で生成し、基本的なデータ操作ができます。関数を利用することで、より複雑な処理をバックエンドで処理できるようになります。
今回は、Supabaseで関数を作成して、この関数をNext.jsアプリから呼びだすまでの手順をご紹介します。
Supbaseで関数を作成
プロジェクトのダッシュボードから、SQL Editorを開きます。
「+ New query」ボタンをクリックすると、「SQL snippets」の下に「New Query」が作成されます。
次のSQLを入力します。
create or replace function hello_world()
returns text
language sql
as $$
select 'Hello world, Supabase!';
$$;
-
create
でhello_world
という名前の関数を作成することを宣言します。or
にreplace
を指定することで、すでに同名の関数がある場合は更新します。 -
returns
に型を渡すことで、この関数の返り値の型を指定します。ここでは、テキスト型を返します。 -
language
に関数で処理するために使用する言語を指定します。ここでは、SQLを使用します。その他にも、plsqlやJavaScriptなど利用できます。 -
as
句に処理の内容を、$$
で囲んで記述します。
「RUN」をクリックするとSQLが実行され、関数が作成されます。
関数を呼びだすために、新しくスニペットを作成するか、先ほどのエディターの中身を次の通り変更します。
select hello_world()
「RUN」をクリックします。関数の実行結果(Results)を確認できます。
Next.jsアプリをセットアップ
作成した関数を呼びだすために、Next.jsアプリをセットアップします。
前回の記事で作成したものをベースに追加していきます。
degit経由で取得して、必要なパッケージをインストールします。
npx degit hirotaka/examples/supabase-nextjs-database#atlanta-0.0.3 supabase-nextjs-database
cd supabase-nextjs-database
npm install
環境変数のセットなどは次を参考にしくてださい。
Next.jsアプリから関数を呼びだす
ダッシュボードで表示している文字列を、Supbaseの関数を呼び出した結果を表示するようにしてみます。
contexts/user.tsx
を次の内容に変更します。
import { useState, useEffect } from 'react'
import { useUser } from '@/contexts/user'
import { supabase } from '@/lib/supabase-client'
export default function Message() {
const { user } = useUser()
const [loading, setLoading] = useState(false)
const [message, setMessage] = useState()
useEffect(() => {
const rpcHello = async () => {
try {
setLoading(true)
const { data } = await supabase.rpc('hello_world')
setMessage(data)
} catch (error) {
alert(error.message)
} finally {
setLoading(false)
}
}
if (user) rpcHello()
}, [user])
return (
<div className="mt-6">
<p>{loading ? '読み込み中...' : message}</p>
</div>
)
}
user
に値が入っている(ログインしている状態)とき、先ほど作成した関数を呼びだすようにします。
関数を呼びだすには、Supabaseクライアントのrpc
メソッドに呼び出したい関数名を渡します。
Supabaseで関数が実行されて、その結果をmessage
とういうステートにセットします。
ダッシュボードで先ほど作成したコンポーネントを読み込むようにします。
@@ -1,4 +1,5 @@
import { useUser } from '@/contexts/user'
+import Message from '@/components/message'
import Profile from '@/components/profile'
export default function Dashboard() {
@@ -7,9 +8,7 @@ export default function Dashboard() {
return (
<div className="max-w-md mx-auto">
<h1 className="text-2xl">ダッシュボード</h1>
- <div className="mt-6">
- <p>Hello, {user.email}!</p>
- </div>
+ <Message />
<Profile />
<div className="mt-6">
<button className="secondary" onClick={() => logout()}>
実行結果の文字列「Hello world, Supabase!」が画面に表示されることを確認できます。
動的なメッセージを表示
固定的な文字列を表示したので、次に動的な結果を表示してみます。
SQL Editorで次のSQLを入力して、実行します。
create or replace function hello_world()
returns text
language sql
as $$
select concat('Hello, ', auth.email(), '!');
$$;
すでに、hellow_world
という名前の関数は作成しているので、replace
により関数の処理が更新されます。
auth.email()
が実行されると、ログインしているユーザーのEメールを取得します。その結果と文字列を連結して返すようにします。
先ほどの、画面を再読み込みすると、Eメールが表示されることを確認できます。
最終的なコードはこちらで参照できます。
おわりに
関数をうまく使えると、バックエンドへのリクエストを少なくしたり、クライアントでの処理の軽減が期待できます。
また、Supabaseではよく使われる処理が拡張として提供されているので、目的にあったものがあれば簡単に使えるのはうれしいです。
関数はデータベースの処理と組み合わせるとより便利さが実感できます。
次回は、テーブルの操作と絡めて関数を作成してみます。
参考
Supbaseの知識を深めるために、ドキュメントの翻訳に取り組んでいます。
関数について、こちらも参考にしてください。
Discussion