🐭

Supabaseの関数をNext.jsアプリから呼び出す

2022/03/04に公開

前回の記事でSupabaseの認証と認可について紹介しました。

https://zenn.dev/hrtk/articles/supabase-nextjs-database-authorization

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!';
$$;
  • createhello_worldという名前の関数を作成することを宣言します。orreplaceを指定することで、すでに同名の関数がある場合は更新します。
  • 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

環境変数のセットなどは次を参考にしくてださい。

https://zenn.dev/hrtk/articles/supabase-nextjs-database-authentication#next.jsアプリをセットアップ

Next.jsアプリから関数を呼びだす

ダッシュボードで表示している文字列を、Supbaseの関数を呼び出した結果を表示するようにしてみます。

contexts/user.tsxを次の内容に変更します。

components/message.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とういうステートにセットします。

ダッシュボードで先ほど作成したコンポーネントを読み込むようにします。

components/dashboard.tsx
@@ -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メールが表示されることを確認できます。

最終的なコードはこちらで参照できます。

https://github.com/hirotaka/examples/tree/atlanta-0.0.4/supabase-nextjs-database

おわりに

関数をうまく使えると、バックエンドへのリクエストを少なくしたり、クライアントでの処理の軽減が期待できます。

また、Supabaseではよく使われる処理が拡張として提供されているので、目的にあったものがあれば簡単に使えるのはうれしいです。

https://supabase.jp/docs/guides/database/extensions

関数はデータベースの処理と組み合わせるとより便利さが実感できます。

次回は、テーブルの操作と絡めて関数を作成してみます。

https://zenn.dev/hrtk/articles/supabase-nextjs-database-fucntion-table

参考

Supbaseの知識を深めるために、ドキュメントの翻訳に取り組んでいます。

https://supabase.jp/

関数について、こちらも参考にしてください。

https://supabase.jp/docs/guides/database/functions

GitHubで編集を提案

Discussion