Computed fields / Hasura ドキュメント翻訳
TweetWhat are computed fields?
Computed fields
は動的に演算された擬似的な値 = virtual value、もしくは擬似的なオブジェクト virtual object です。Computed fields
はリクエストが発行された際に custom SQL function
を用いて演算されます。その際の演算には、テーブルのカラムの値を用いることができます。また必要であれば custom input
を使用することも可能です。
(訳注:Computed filed が活躍するのは、親テーブルの値を使って演算した値を生成したい場合である。例えば article テーブルの各種の値に加えて、article.category_id を元に、何らかの集計をした値を生成したい場合だ。)
Computed fields are virtual values or objects that are dynamically computed and can be queried along with a table’s columns. Computed fields are computed when requested for via custom SQL functions using other columns of the table and other custom inputs if needed.
Computed fields
は GraphQL API からのみアクセスできます。また Computed fields
を追加しても database schema に変更は生じません。
Note
Computed fields are only exposed over the GraphQL API and the database schema is not modified on addition of a computed field.
Supported SQL functions
以下の要件を満たした function だけが computed fileld
としてテーブルに追加することができます。
Only functions which satisfy the following constraints can be added as a computed field to a table. (terminology from Postgres docs):
- Function behaviour:
STABLE
もしくはIMMUTABLE
のどちらかであること - Argument modes: IN の場合のみ
- Table Argument: argument の一つは必ず table row type であること
- Return type:
SETOF <table-name>
もしくはBASE
type であること
- Function behaviour: ONLY STABLE or IMMUTABLE
- Argument modes: ONLY IN
- Table Argument: One input argument with a table row type
- Return type: Either SETOF
<table-name>
or BASE type
Computed fileds
で functios が使用される場合、その引数は table row を必ずとる必要がありますが、それに加えてそれ以外の引数をとることも可能です。追加の引数は、GraphQL API を使用する際に引数として渡すことで機能します。
Note
Functions used as computed fields can also accept other arguments other than the mandatory table row argument. Values for these extra arguments can be passed as arguments to the computed field in the GraphQL API.
Computed field types
Computed field
が返す値の type
は、SQL function の return type
に定義した type
によって、二種類に分類することができます。
Based on the SQL function’s return type, we can define two types of computed fields:
1. Scalar computed fields
SQL function の return type が Integer, Boolean, Geography
といった base type の場合、computed field は scalar type の値を返します。
Computed fields whose associated SQL function returns a base type like Integer, Boolean, Geography etc. are scalar computed fields.
例:
author
テーブルが first_name
と last_name
というカラムを持つとします。それぞれ type は text
です。
Example:
The author table has two text columns: firstname and lastname.
ではこれらのテーブルに対して author_full_name
という名称の SQL function を定義します。
Define an SQL function called authorfullname:
CREATE FUNCTION author_full_name(author_row author)
RETURNS TEXT AS $$
SELECT author_row.first_name || ' ' || author_row.last_name
$$ LANGUAGE sql STABLE;
今定義した SQL function を使って、full_name
という名称の computed filed
を author
テーブルに追加しましょう。
Add a computed field called full_name to the author table using the SQL function above.
結果として以下の query でデータを取得することができます。
Query data from the author table:
query {
author {
id
first_name
last_name
full_name
}
}
{
"data": {
"author": [
{
"id": 1,
"first_name": "Chris",
"last_name": "Raichael",
"full_name": "Chris Raichael"
}
]
}
}
2. Table computed fields
SQL function の return type が SETOF <table-name>
の場合、computed field は table type の値を返します。ここで返される table は、必ず track されている必要があります。
Computed fields whose associated SQL function returns
SETOF <table-name>
are table computed fields. The return table must be tracked to define such a computed field.
単純に author とそれが所持する article を取得するだけであれば、table relationship を定義するだけで実現可能です。
Example:
In a simple author <-> article schema, we can define a table relationship on the author table to fetch authors along with their articles.
ですが、サーチパラメーターを元に author の article を取得したい場合には、computed field
を使用する必要があります。
We can make use of computed fields to fetch the author’s articles with a search parameter.
filter_author_articles
という名称の SQL function を定義しましょう。
Define an SQL function called filterauthorarticles:
CREATE FUNCTION filter_author_articles(author_row author, search text)
RETURNS SETOF article AS $$
SELECT *
FROM article
WHERE
( title ilike ('%' || search || '%')
OR content ilike ('%' || search || '%')
) AND author_id = author_row.id
$$ LANGUAGE sql STABLE;
今定義した SQL function を使って、filtered_articles
という名称の computed filed
を author
テーブルに追加しましょう。
Add a computed field called filtered_articles to the author table using the SQL function above.
結果として以下の query でデータを取得することができます。
Query data from the author table:
query {
author {
id
first_name
last_name
filtered_articles(args: {search: "Hasura"}){
id
title
content
}
}
}
{
"data": {
"author": [
{
"id": 1,
"first_name": "Chris",
"last_name": "Raichael",
"filtered_articles": [
{
"id": 1,
"title": "Computed fields in Hasura",
"content": "lorem ipsum dolor sit amet"
}
]
}
]
}
}
Adding a computed field to a table
該当テーブルの Modify
テーブルに移動し、Computed fields
の Add
ボタンを押します。
Head to the Modify tab of the table and click on the Add button in the Computed fields section:
Console からの設定は v1.1.0 以上から可能になりました。
Supported from
Console support is available in v1.1.0 and above
Computed fields permissions
Computed field
へのアクセスコントロールの管理方法は computed field の type によって二通りにわかれます。
Access control to computed fields depends on the type of computed field.
Scalar computed field
の場合は、通常のカラムと同様 の方法で管理されます。Table computed field
の場合は、return type
として設定されたtable
に対するパーミンションコントロールが、そのまま適用されます。
- For scalar computed fields, permissions are managed similar to the columns permissions of the table.
- For table computed fields, the permissions set on the return table are respected.
Accessing Hasura session variables in computed fields
訳注: ほぼ Extend schema with SQL functions に同じ項目がありますのでそちらを参照ください。
It can be useful to have access to the session variable from the SQL function defining a computed field. For instance, suppose we want to record which users have liked which articles. We can do so using a table article_likes that specifies a many-to-many relationship between article and user. In such a case it can be useful to know if the current user has liked a specific article, and this information can be exposed as a Boolean computed field on article.
Create a function with an argument for session variables and add it with the addcomputedfield API with the session_argument key set. The session argument is a JSON object where keys are session variable names (in lower case) and values are strings. Use the ->> JSON operator to fetch the value of a session variable as shown in the following example.
-- 'hasura_session' will be the session argument
CREATE OR REPLACE FUNCTION article_liked_by_user(article_row article, hasura_session json)
RETURNS boolean AS $$
SELECT EXISTS (
SELECT 1
FROM article_likes A
WHERE A.user_id = hasura_session ->> 'x-hasura-user-id' AND A.article_id = article_row.id
);
$$ LANGUAGE sql STABLE;
POST /v1/query HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type":"add_computed_field",
"args":{
"table":{
"name":"article",
"schema":"public"
},
"name":"liked_by_user",
"definition":{
"function":{
"name":"article_liked_by_user",
"schema":"public"
},
"table_argument":"article_row",
"session_argument":"hasura_session"
}
}
}
Note
The specified session argument is not included in the argument options of the computed field in the GraphQL schema.
Supported from
This feature is available in v1.3.0-beta.1 and above
Computed fields vs. Postgres generated columns
訳注:実際に Posgres の Generated Columns
を使ったことがないため、正確な翻訳ができないのですが、Hasura としては Computed fields
の方が拡張性が高く、制限がない、さらに素直な実装になるということなので、こちらをおすすめしているようです。
Postgres, from version 12, is introducing Generated Columns. The value of generated columns is also computed from other columns of a table. Postgres’ generated columns come with their own limitations. Hasura’s computed fields are defined via an SQL function, which allows users to define any complex business logic in a function. Generated columns will go together with computed fields where Hasura treats generated columns as normal Postgres columns.