💻

HasuraのComputed Fields

2023/01/23に公開

Hasura本家のドキュメント

https://hasura.io/docs/latest/schema/postgres/computed-fields/

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