💻
HasuraのComputed Fields
Hasura本家のドキュメント
Computed Fieldsとは?
実際のテーブルには存在しないフィールド。例えばusersテーブルに first_name, last_name が定義されているとして、full_name
として返したい時に定義するフィールドのこと。
frontendで表示する時に計算してもいいが、ロジックが複雑な場合はbackend(GraphQL server)で計算して返してあげると、frontendの実装が楽になる。
Hasuraでどうやって実現するのか?
HasuraではPostgreSQLのCustom SQL Functionsで実現する。
例えばHasuraのドキュメントにある例を抜粋。
CREATE FUNCTION author_full_name(author_row authors)
RETURNS TEXT AS $$
SELECT author_row.first_name || ' ' || author_row.last_name
$$ LANGUAGE sql STABLE;
-
CREATE FUNCTION ~
で関数を定義 -
()
の中が引数の定義 -
RETURNS ~
で戻り値の型を定義 -
$$〜$$
までが関数の本体 -
LANGUAGE sql
でSQLベースの関数であることを宣言 -
STABLE
- DBの値を更新することはできないタイプの関数
Hasura上の制限
- Function behavior: ONLY STABLE or IMMUTABLE
- STABLE, IMMUTABLEはDBの値を更新することができない
- DBの値を更新できる
VOLATILE
というタイプもあるが、これはサポートされていない
- Argument modes: ONLY IN
- OUTモードという値を更新できるものもPostgreSQLにはあるが、それは使えないらしい
- Table Argument: One input argument with a table row type
- 引数にはテーブルの行しか指定できない
- Return type: Either SETOF <table-name> or BASE type
- 戻り値にはテーブルの複数の行、もしくはINTEGER, TEXT, TIMESTAMPのようなBASE typeしか指定できない(あんまりちゃんと理解してない)
関数を定義してみた
user_tickets.used_at から7日後のexpired_atを計算してcomputed fieldとして返す関数。
CREATE OR REPLACE FUNCTION public.user_tickets_expired_at(user_ticket_row user_tickets)
RETURNS timestamp with time zone
AS $$
SELECT user_ticket_row.used_at + CAST('7 days' as INTERVAL)
$$ LANGUAGE sql STABLE;
Hasuraでの定義
ドキュメント通りやれば良さそう。
Discussion