🐰

Supabaseの拡張機能を使った関数をNext.jsアプリから呼び出す

2022/03/08に公開

前回の記事では、Supabaseに関数を作成して、Next.jsのアプリから呼びだしてトランザクション処理をしました。

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

今回は、拡張機能を使った関数をNext.jsから呼びだすします。

本記事は、Supbaseが公開している動画のコードをベースに、ステップバイステップで自身の環境で試せるようにアレンジしてお届けします。

https://www.youtube.com/watch?v=rARgrELRCwY

拡張機能を有効化

Supbaseのダッシュボードで拡張機能を有効にします。

Databaseで、サイドメニューの「Extensions」を選択します。拡張の一覧が表示されるので、検索ボックスに「http」と入力すると、一覧が絞り込まれます。

絞り込まれた一覧にある「HTTP」のトグルをオンにして有効にします。

これで、関数からHTTPコールができるようになります。

Kanya.rest

有効にした拡張機能を使って、Kanya.restのAPIを呼びだします。

https://kanye.rest/

このサイトは、カニア・ウェストというラッパーの歌詞をランダムで返してくれます。

https://ja.wikipedia.org/wiki/カニエ・ウェスト

APIをコールすると、次のようなJSONが返ってきます。

{
  quote: "Today is the best day ever and tomorrow's going to be even better"
}

関数を作成

それでは、関数を作成します。

次のSQLをSQL Editorで実行します。

create or replace function talk_to_kanye(name text)
returns text
language plpgsql
as $$
declare
  kayne_quote text;
begin
  select content::json->>'quote'
  into kayne_quote
  from http_get('https://api.kanye.rest/');

  return concat('Hey ', name, '. ', kayne_quote);
end;
$$;

拡張機能によりhttp_getという関数が使えるようになります。この関数にURLを引数で渡して実行すると、APIをコールできます。返ってきたレスポンスをcontent::jsonで取得して、quoteキーの内容を変数に格納します。

Netx.jsアプリから呼びだす

セットアップ

前回の記事をベースにしていきます。

degit経由で取得して、必要なパッケージをインストールします。

npx degit hirotaka/examples/supabase-nextjs-database#atlanta-0.0.5 supabase-nextjs-database
cd supabase-nextjs-database
npm install

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

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

コンポーネントを作成

関数を呼びだして、返ってきた内容を表示するコンポーネントを作成します。

componentes/kayne.tsx
import { useState, useEffect } from 'react'
import { useUser } from '@/contexts/user'
import { supabase } from '@/lib/supabase-client'

export default function Kanye() {
  const { user } = useUser()
  const [loading, setLoading] = useState(false)
  const [quote, setQuote] = useState()

  useEffect(() => {
    const rpcTalkToKanye = async () => {
      try {
        setLoading(true)
        const { data } = await supabase.rpc('talk_to_kanye', {
          name: user.name,
        })
        setQuote(data)
      } catch (error) {
        alert(error.message)
      } finally {
        setLoading(false)
      }
    }
    if (user) rpcTalkToKanye()
  }, [user])

  return (
    <div className="mt-6">
      <label className="block">Kanye Quote</label>
      <p className="mt-2">{loading ? '読み込み中...' : quote}</p>
    </div>
  )
}

rpcメソッドで関数名とユーザー名を引数で渡して実行します。返ってきた結果をquoteステートに保持します。

ダッシュボードに表示

先ほど作成したコンポーネントをインポートします。

ユーザーの名前が必要なので、プロフィールが作成済みの場合のみコンポーントを表示するようにします。

components/dashboard.tsx
@@ -2,6 +2,7 @@ import { useUser } from '@/contexts/user'
 import Message from '@/components/message'
 import Profile from '@/components/profile'
 import Counter from '@/components/counter'
+import Kanye from '@/components/kanye'
 
 export default function Dashboard() {
   const { logout, user } = useUser()
@@ -11,7 +12,12 @@ export default function Dashboard() {
       <h1 className="text-2xl">ダッシュボード</h1>
       <Message />
       <Profile />
-      {user.profile && <Counter />}
+      {user.profile && (
+        <>
+          <Counter />
+          <Kanye />
+        </>
+      )}
       <div className="mt-6">
         <button className="secondary" onClick={() => logout()}>
           ログアウト

ダッシュボードを表示すると、下の方にランダムで歌詞が表示されることを確認できます。

ここまでのコードはリポジトリーで確認してください。

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

おわりに

Supbaseでは、拡張機能が用意されているので、管理画面からトグルをオンにしてすぐに使えるので便利です。

どのような拡張機能が使えるかはこちらも参考にしてください。

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

参考

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

https://supabase.jp/

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

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

GitHubで編集を提案

Discussion