docs/docs/api-reference/schema-metadata-api/relationship.mdx
:::caution Deprecation
In versions v2.0.0 and above, the schema/Metadata API is deprecated in
favour of the schema API and the
Metadata API.
Though for backwards compatibility, the schema/Metadata APIs will continue to function.
:::
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 articlearticles of an authorThere are two kinds of relationships:
object relationships (e.g. author).array relationships (e.g. articles).The above represents the same table relationship from different
perspectives: there is a single author for every article
(one-to-one), but there may be multiple articles for every author
(one-to-many).
A table relationship may be one-to-one from both perspectives. For
example, given tables author and author_details, if the
author_details table has a primary key author_id which is a foreign
key to the author table's primary key id. In this case there will be
a single author for every author_details and a single details for
every author
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 3 ways in which you can create an object relationship.
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"
}
}
}
Create an object relationship details on author table, using
the foreign_key_constraint_on the author_details table's id
column:
POST /v1/query HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type": "create_object_relationship",
"args": {
"table": "author",
"name": "details",
"using": {
"foreign_key_constraint_on" : {
"table": "author_details",
"column": "author_id"
}
}
}
}
:::tip Supported from
Relationships via remote table are supported for versions
v2.0.0-alpha.3 and above.
:::
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"
}
}
}
}
}
:::info 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.
:::
| 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 |
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.
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"
}
}
}
}
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"
}
}
}
}
}
:::info 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.
:::
| 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 |
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"
}
}
| 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 |
:::info Note
Be careful when using cascade. First, try running the request without
cascade or cascade set to false.
:::
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."
}
}
| Key | Required | Schema | Description |
|---|---|---|---|
| table | true | TableName | Name of the table |
| relationship | true | RelationshipName | The relationship |
| comment | false | Text | Comment |
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"
}
}
| Key | Required | Schema | Description |
|---|---|---|---|
| table | true | TableName | Name of the table |
| name | true | RelationshipName | The relationship |
| new_name | true | RelationshipName | New relationship name |