スーパーベース関数 (エッジではない)
スーパーベース
Firebase サービスに代わるオープンソースの代替手段
- データベース
- リアルタイム
- 認証
- 機能
- エッジ関数
しかし、待ってください。すでに機能があるのに、なぜエッジ機能が必要なのでしょうか?
Supabase 関数: PostgreSQL ツールボックス
データベース関数とも呼ばれる Supabase 関数は、本質的には PostgreSQL ストアド プロシージャです。これらは、SQL クエリ内から呼び出すことができる SQL コードの実行可能ブロックです。
エッジ機能: データベースを超えて
対照的に、Edge 関数は、Deno ランタイムで実行されるサーバー側の TypeScript 関数です。これらは Firebase Cloud Functions に似ていますが、より柔軟でオープンソースの代替手段を提供します。
Supabase: PostgreSQL プラットフォーム
Supabase は、Firebase のオープンソース代替としての役割を超えて、包括的な PostgreSQL プラットフォームに進化しました。 PostgreSQL 関数に対する最上級のサポートを提供し、それらの関数を組み込みユーティリティにシームレスに統合し、Supabase ダッシュボードから直接カスタム関数を作成および管理できるようにします。
基本的な postgres 関数の構造
CREATE FUNCTION my_function() RETURNS int AS $$ BEGIN RETURN 42; END; $$ LANGUAGE sql;
内訳:
- CREATE FUNCTION: このキーワードは、新しい関数を定義していることを示します。
- my_function(): これは関数の名前です。お好みの意味のある名前を選択できます。
- RETURNS int: 関数の戻り値の型を指定します。この場合、関数は整数値を返します。
- AS $$: これは関数本体の始まりであり、二重ドル記号 ($$) で囲まれて区切られています。
- BEGIN: これは、関数の実行可能コードの開始を示します。
- RETURN 42;: このステートメントは、関数が返す値を指定します。この場合、それは整数 42 です。
- END;: これは、関数の実行可能コードの終わりを示します。
- $$ LANGUAGE sql;: これは、関数が記述される言語を指定します。この場合は SQL です。
目的:
この関数は、整数値 42 を返す my_function という名前の単純な SQL 関数を定義します。これは、PostgreSQL の関数定義の構造と構文を示す基本的な例です。
覚えておくべき重要なポイント:
- my_function を任意の関数名に置き換えることができます。
- 戻り値の型には、テキスト、ブール値、日付、ユーザー定義型などの有効なデータ型を指定できます。
- 関数本体には、条件ステートメント、ループ、他の関数の呼び出しなどの複雑なロジックを含めることができます。
$$ 区切り文字は、言語に依存しない方法で関数本体を囲むために使用されます。
Postgres 関数は、関数に似ていますが、テーブルに対する挿入、更新、削除などの特定のイベントに反応する postgres TRIGGERS によって呼び出すこともできます
この関数を実行するには
SELECT my_function();
- この関数をリストするには
SELECT proname AS function_name, prokind AS function_type FROM pg_proc WHERE proname = 'my_function';
- この機能を削除するには
DROP FUNCTION my_function();
Supabase postgres 関数
組み込み関数
Supabase は postgres 関数を利用してデータベース内で特定のタスクを実行します。
サンプルの短いリストには以下が含まれます
-- list all the supabase functions SELECT proname AS function_name, prokind AS function_type FROM pg_proc; -- filter for the session supabase functions function SELECT proname AS function_name, prokind AS function_type FROM pg_proc WHERE proname ILIKE '%session%'; -- selects the curremt jwt select auth.jwt() -- select what role is callig the function (anon or authenticated) select auth.role(); -- select the session user select session_use;
ダッシュボード上の Supabase 機能ビュー
Supabase でこれらの関数の一部を表示するには、[データベース] > [データベース] でチェックを入れることができます。関数
便利な Supabase PostgreSQL 関数
ユーザーサインアップ時に user_profile テーブルを作成する
Supabase は、ユーザー データを auth.users テーブルに保存します。このテーブルはプライベートであり、直接アクセスしたり変更したりしないでください。推奨されるアプローチは、パブリック ユーザーまたは user_profiles テーブルを作成し、それを auth.users テーブルにリンクすることです。
これは、クライアント側の SDK を使用してユーザー作成リクエストと成功したサインアップ リクエストを連鎖させることで実行できますが、Supabase 側で処理する方が信頼性が高く効率的です。これは、TRIGGER と FUNCTION の組み合わせを使用して実現できます。
-- create the user_profiles table CREATE TABLE user_profiles ( id uuid PRIMARY KEY, FOREIGN KEY (id) REFERENCES auth.users(id), name text, email text ); -- create a function that returns a trigger on auth.users CREATE OR REPLACE FUNCTION public.create_public_user_profile_table() RETURNS TRIGGER AS $$ BEGIN INSERT INTO public.user_profiles (id,name,email) VALUES ( NEW.id, NEW.raw_user_meta_data ->> 'name', NEW.raw_user_meta_data ->> 'email' -- other fields accessible here -- NEW.raw_user_meta_data ->> 'name', -- NEW.raw_user_meta_data ->> 'picture', ); RETURN NEW; END; $$ LANGUAGE plpgsql SECURITY DEFINER; -- create the trigger that executes the function on every new user rowcteation(signup) CREATE TRIGGER create_public_user_profiles_trigger AFTER INSERT ON auth.users FOR EACH ROW WHEN ( NEW.raw_user_meta_data IS NOT NULL ) EXECUTE FUNCTION public.create_public_user_profile_table ();
let { data: user_profiles, error } = await supabase .from('user_profiles') .select('*')
- JWT 作成時にカスタム クレームを追加する (RBAC) supabse にこれに関する詳細な記事とビデオがあります。
テーブルが 2 つ必要です
- public.roles と public.role_permissions
-- Custom types create type public.app_permission as enum ('channels.delete', 'channels.update', 'messages.update', 'messages.delete'); create type public.app_role as enum ('admin', 'moderator'); -- USER ROLES create table public.user_roles ( id bigint generated by default as identity primary key, user_id uuid references public.users on delete cascade not null, role app_role not null, unique (user_id, role) ); comment on table public.user_roles is 'Application roles for each user.'; -- ROLE PERMISSIONS create table public.role_permissions ( id bigint generated by default as identity primary key, role app_role not null, permission app_permission not null, unique (role, permission) ); comment on table public.role_permissions is 'Application permissions for each role.';
ユーザー役割の例
id | user_id | role |
---|---|---|
1 | user-1 | admin |
2 | user-2 | moderator |
example of a role permission table
id | role | permission |
---|---|---|
1 | admin | channels.update |
2 | admin | messages.update |
3 | admin | messages.delete |
4 | admin | messages.delete |
5 | moderator | channels.update |
6 | moderator | messages.update |
user with user_id = user-1 will have admin and moderator roles and can delete channels and messages
users with user_id = user-2 can only update channels and messages with the moderator role
-- Create the auth hook function create or replace function public.custom_access_token_hook(event jsonb) returns jsonb language plpgsql stable as $$ declare claims jsonb; user_role public.app_role; begin -- Fetch the user role in the user_roles table select role into user_role from public.user_roles where user_id = (event->>'user_id')::uuid; claims := event->'claims'; if user_role is not null then -- Set the claim claims := jsonb_set(claims, '{user_role}', to_jsonb(user_role)); else claims := jsonb_set(claims, '{user_role}', 'null'); end if; -- Update the 'claims' object in the original event event := jsonb_set(event, '{claims}', claims); -- Return the modified or original event return event; end; $$; grant usage on schema public to supabase_auth_admin; grant execute on function public.custom_access_token_hook to supabase_auth_admin; revoke execute on function public.custom_access_token_hook from authenticated, anon, public; grant all on table public.user_roles to supabase_auth_admin; revoke all on table public.user_roles from authenticated, anon, public; create policy "Allow auth admin to read user roles" ON public.user_roles as permissive for select to supabase_auth_admin using (true)
then create a function that will be called to authorize on RLS policies
create or replace function public.authorize( requested_permission app_permission ) returns boolean as $$ declare bind_permissions int; user_role public.app_role; begin -- Fetch user role once and store it to reduce number of calls select (auth.jwt() ->> 'user_role')::public.app_role into user_role; select count(*) into bind_permissions from public.role_permissions where role_permissions.permission = requested_permission and role_permissions.role = user_role; return bind_permissions > 0; end; $$ language plpgsql stable security definer set search_path = ''; -- example RLS policies create policy "Allow authorized delete access" on public.channels for delete using ( (SELECT authorize('channels.delete')) ); create policy "Allow authorized delete access" on public.messages for delete using ( (SELECT authorize('messages.delete')) );
Improved Text:
Creating RPC Endpoints
Supabase functions can be invoked using the rpc function. This is especially useful for writing custom SQL queries when the built-in PostgreSQL APIs are insufficient, such as calculating vector cosine similarity using pg_vector.
create or replace function match_documents ( query_embedding vector(384), match_threshold float, match_count int ) returns table ( id bigint, title text, body text, similarity float ) language sql stable as $$ select documents.id, documents.title, documents.body, 1 - (documents.embedding <=> query_embedding) as similarity from documents where 1 - (documents.embedding <=> query_embedding) > match_threshold order by (documents.embedding <=> query_embedding) asc limit match_count; $$;
and call it client side
const { data: documents } = await supabaseClient.rpc('match_documents', { query_embedding: embedding, // Pass the embedding you want to compare match_threshold: 0.78, // Choose an appropriate threshold for your data match_count: 10, // Choose the number of matches })
Improved Text:
Filtering Out Columns
To prevent certain columns from being modified on the client, create a simple function that triggers on every insert. This function can omit any extra fields the user might send in the request.
-- check if user with roles authenticated or anon submitted an updatedat column and replace it with the current time , if not (thta is an admin) allow it CREATE or REPLACE function public.omit_updated__at () returns trigger as $$ BEGIN IF auth.role() IS NOT NULL AND auth.role() IN ('anon', 'authenticated') THEN NEW.updated_at = now(); END IF; RETURN NEW; END; $$ language plpgsql;
Summary
With a little experimentation, you can unlock the power of Supabase functions and their AI-powered SQL editor. This lowers the barrier to entry for the niche knowledge required to get this working.
Why choose Supabase functions?
- Extend Supabase's API: Supabase can only expose so much through its API. Postgres, however, is a powerful database. Any action you can perform with SQL statements can be wrapped in a function and called from the client or by a trigger.
- Reduce the need for dedicated backends: Supabase functions can fill the simple gaps left by the client SDKs, allowing you to focus on shipping.
- Avoid vendor lock-in: Supabase functions are just Postgres. If you ever need to move to another hosting provider, these functionalities will continue to work.
以上がスーパーベース関数 (エッジではない)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









