Schema/Metadata API Reference: Relationships

Introduction

When retrieving data from tables, it is very helpful if we can also fetch the related data alongside the columns. This is where relationships come in. They can be considered as pseudo columns for a table to access the related data.

For a simple article/author schema, the following relationships exist:

  • author of an article
  • articles of an author

There are two kinds of relationships:

  • one-to-one or object relationships (e.g. author).
  • one-to-many or array relationships (e.g. articles).

create_object_relationship

create_object_relationship is used to create an object relationship on a table. There cannot be an existing column or relationship with the same name.

There are 2 ways in which you can create an object relationship.

1. Using foreign key constraint on a column

Create an object relationship author on article table, using the foreign_key_constraint_on the author_id column:

POST /v1/query HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type": "create_object_relationship",
    "args": {
        "table": "article",
        "name": "author",
        "using": {
            "foreign_key_constraint_on" : "author_id"
        }
    }
}

2. Manual configuration

This is an advanced feature which is mostly used to define relationships on or to views. We cannot rely on foreign key constraints as they are not valid to or from views. So, when using manual configuration, we have to specify the remote table and how columns in this table are mapped to the columns of the remote table.

Let’s say we have a view called article_detail which has three columns article_id and view_count and average_rating. We can now define an object relationship called article_detail on the article table as follows:

POST /v1/query HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type": "create_object_relationship",
    "args": {
        "table": "article",
        "name": "article_detail",
        "using": {
            "manual_configuration" : {
                "remote_table" : "article_detail",
                "column_mapping" : {
                    "id" : "article_id"
                }
            }
        }
    }
}

Note

It is easy to make mistakes while using manual_configuration. One simple check is to ensure that foreign key constraint semantics are valid on the columns being used in column_mapping. In the previous example, if it was allowed, a foreign key constraint could have been defined on article table’s id column to article_detail view’s article_id column.

Args syntax

Key Required Schema Description
table true TableName Name of the table
name true RelationshipName Name of the new relationship
using true ObjRelUsing Use one of the available ways to define an object relationship
comment false text comment

ObjRelUsing

Key Required Schema Description
foreign_key_constraint_on false PGColumn The column with foreign key constraint
manual_configuration false ObjRelUsingManualMapping Manual mapping of table and columns

Note

There has to be at least one and only one of foreign_key_constraint_on and manual_configuration.

ObjRelUsingManualMapping

Key Required Schema Description
remote_table true TableName The table to which the relationship has to be established
column_mapping true Object (PGColumn : PGColumn) Mapping of columns from current table to remote table

create_array_relationship

create_array_relationship is used to create an array relationship on a table. There cannot be an existing column or relationship with the same name.

There are 2 ways in which you can create an array relationship.

1. Using foreign key constraint on a column

Create an array relationship articles on author table, using the foreign_key_constraint_on the author_id column of the article table:

POST /v1/query HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type": "create_array_relationship",
    "args": {
        "table": "author",
        "name": "articles",
        "using": {
            "foreign_key_constraint_on" : {
                "table" : "article",
                "column" : "author_id"
            }
        }
    }
}

2. Manual configuration

This is an advanced feature which is mostly used to define relationships on or to views. We cannot rely on foreign key constraints as they are not valid to or from views. So, when using manual configuration, we have to specify the remote table and how columns in this table are mapped to the columns of the remote table.

Let’s say we have a view called article_detail which has four columns author_id, article_id, view_count and average_rating. We can now define an array relationship called article_details on the author table as follows:

POST /v1/query HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type": "create_array_relationship",
    "args": {
        "table": "author",
        "name": "article_details",
        "using": {
            "manual_configuration" : {
                "remote_table" : "article_detail",
                "column_mapping" : {
                    "id" : "author_id"
                }
            }
        }
    }
}

Note

It is easy to make mistakes while using manual_configuration. One simple check is to ensure that foreign key constraint semantics are valid on the columns being used in column_mapping. In the previous example, if it was allowed, a foreign key constraint could have been defined on the author table’s id column to article_detail view’s author_id column.

Args syntax

Key Required Schema Description
table true TableName Name of the table
name true RelationshipName Name of the new relationship
using true ArrRelUsing Use one of the available ways to define an array relationship
comment false text comment

ArrRelUsing

Key Required Schema Description
foreign_key_constraint_on false ArrRelUsingFKeyOn The column with foreign key constraint
manual_configuration false ArrRelUsingManualMapping Manual mapping of table and columns

ArrRelUsingFKeyOn

Key Required Schema Description
table true TableName Name of the table
column true PGColumn Name of the column with foreign key constraint

ArrRelUsingManualMapping

Key Required Schema Description
remote_table true TableName The table to which the relationship has to be established
column_mapping true Object (PGColumn : PGColumn) Mapping of columns from current table to remote table

drop_relationship

drop_relationship is used to drop a relationship (both object and array) on a table. If there are other objects dependent on this relationship like permissions and query templates, etc., the request will fail and report the dependencies unless cascade is set to true. If cascade is set to true, the dependent objects are also dropped.

An example:

POST /v1/query HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type": "drop_relationship",
    "args": {
        "table": "article",
        "relationship": "article_detail"
    }
}

Args syntax

Key Required Schema Description
table true TableName Name of the table
relationship true RelationshipName Name of the relationship that needs to be dropped
cascade false Boolean When set to true, all the dependent items on this relationship are also dropped

Note

Be careful when using cascade. First, try running the request without cascade or cascade set to false.

set_relationship_comment

set_relationship_comment is used to set/update the comment on a relationship. Setting the comment to null removes it.

An example:

POST /v1/query HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type": "set_relationship_comment",
    "args": {
        "table": "article",
        "name": "article_detail",
        "comment" : "has extra information about an article like count etc."
    }
}

Args syntax

Key Required Schema Description
table true TableName Name of the table
relationship true RelationshipName The relationship
comment false Text Comment

rename_relationship

rename_relationship is used to modify the name of an existing relationship.

An example:

POST /v1/query HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type": "rename_relationship",
    "args": {
        "table": "article",
        "name": "article_details",
        "new_name": "article_detail"
    }
}

Args syntax

Key Required Schema Description
table true TableName Name of the table
name true RelationshipName The relationship
new_name true RelationshipName New relationship name