Models
Introduction
In Hasura DDN, a model represents a collection of data objects within a data domain. Models act as the foundational elements (or "nouns") that define the data structure and behavior in your API. They can be backed by various data sources such as database tables, custom SQL queries, materialized views, or even external REST or GraphQL APIs.
Models bridge the gap between data connectors and the GraphQL API, enabling operations like insertion, updating, deletion, and querying with features like filtering, pagination, and sorting.
How models work
Lifecycle
You can quickly add models to your metadata using the CLI.
Models themselves are backed by types, which are derived using the schema of the data source they represent via a DataConnectorLink object. This means that when you add a model, Hasura DDN automatically generates the necessary types for you.
Once a model is declared, it becomes a central reference point within your metadata. Models are often associated with
Relationship
objects, allowing them to interact with other models, and with
Permissions
objects, which control access to the data they represent. Like all
other metadata objects, models are defined in an HML file.
You should update your models whenever you make changes to your data sources and, in turn, your DataConnectorLink objects. This ensures that your API remains in sync with your data.
To make a new model available in your supergraph, you'll need to create a new build using the CLI.
Examples
---
kind: Model
version: v1
definition:
name: Users
objectType: Users
source:
dataConnectorName: my_pg
collection: users
filterExpressionType: UsersBoolExp
orderableFields:
- fieldName: id
orderByDirections:
enableAll: true
- fieldName: name
orderByDirections:
enableAll: true
- fieldName: email
orderByDirections:
enableAll: true
- fieldName: createdAt
orderByDirections:
enableAll: true
graphql:
selectMany:
queryRootField: users
selectUniques:
- queryRootField: usersById
uniqueIdentifier:
- id
orderByExpressionType: UsersOrderBy
Field | Description | Reference |
---|---|---|
kind | Specifies the type of object being defined. In this case, it’s a model. | Model |
version | Indicates the version of the model's structure. | ModelV1 |
definition.name | The name of the model, representing the collection of data objects within this model. | ModelName |
definition.objectType | Defines the type of objects contained within this model. | CustomTypeName |
definition.source.dataConnectorName | The name of the data connector that backs this model, linking it to the actual data source. | DataConnectorName |
definition.source.collection | The specific collection within the data connector that this model maps to. | CollectionName |
definition.filterExpressionType | Specifies the type used for filtering the model's data within GraphQL queries. | CustomTypeName |
definition.orderableFields | A list of fields (in this example: id , name , email , createdAt ) that can be used to sort the data in this model. | OrderableField |
definition.graphql.selectMany.queryRootField | The root field in the GraphQL API for querying multiple objects from this model. Removing this will disable the ability to query and return an array of this model. | SelectManyGraphQlDefinition |
definition.graphql.selectUniques | Defines unique query root fields (e.g., usersById) and identifiers used to retrieve unique objects in GraphQL. Removing this will disable the abilty to query a single instance of this model. | SelectUniqueGraphQlDefinition |
definition.graphql.orderByExpressionType | The type name used for specifying how to order the data when querying this model in GraphQL. | GraphQlTypeName |
query UsersQuery {
users(where: { name: { _eq: "Bob" } }, order_by: { createdAt: Asc }, limit: 10) {
id
name
email
createdAt
}
}
The above example works because the earlier model definition includes the necessary configuration for filtering,
sorting, and pagination. Alternatively, if we'd set enableAll
to false
for the createdAt
field in the
orderableFields
section, the createdAt
field would not be available for sorting in the API.
Check out Global IDs for relay:
A Global ID is a unique identifier for an object across the entire application, not just within a specific table or type. Think of it as an ID which you can use to fetch any object directly, regardless of what kind of object it is. This is different from typical database IDs, which are often guaranteed unique only within a particular table.
Hasura's Global ID implementation can be used to provide options for GraphQL clients to elegantly handle caching and data re-fetching in a predictable and standardized way.
The Global ID generated by Hasura DDN follows the Relay Global ID spec.
As the example below shows, the user
object type has a field user_id
that uniquely identifies a user. The Global ID
for the user
object type will be generated using the user_id
field:
For the following request on a model which has enabled Global ID:
{
user_by_id(user_id: 1) {
id // Global ID
user_id
name
}
}
The response obtained should look like the following:
{
"data": {
"user_by_id": {
"id": "eyJ2ZXJzaW9uIjoxLCJ0eXBlbmFtZSI6IkFydGljbGUiLCJpZCI6eyJhcnRpY2xlX2lkIjoyfX0=",
"user_id": 1,
"name": "Bob"
}
}
}
Now, with the Global ID received above, the User
object corresponding to user_id: 1
can be retrieved, as shown
below.
{
node(id: "eyJ2ZXJzaW9uIjoxLCJ0eXBlbmFtZSI6IkFydGljbGUiLCJpZCI6eyJhcnRpY2xlX2lkIjoyfX0=") {
id
__typename
... on User {
name
}
}
}
The response to the above request should identify the User
with user_id: 1
.
{
"node": {
"id": "eyJ2ZXJzaW9uIjoxLCJ0eXBlbmFtZSI6IkFydGljbGUiLCJpZCI6eyJhcnRpY2xlX2lkIjoyfX0=",
"__typename": "User",
"name": "Bob"
}
}
Metadata structure
Model
The definition of a data model. A data model is a collection of objects of a particular type. Models can support one or more CRUD operations.
One of the following values:
Value | Description |
---|---|
undefined | |
undefined |
Example:
kind: Model
version: v1
definition:
name: Articles
objectType: article
globalIdSource: true
arguments: []
source:
dataConnectorName: data_connector
collection: articles
argumentMapping: {}
filterExpressionType: Article_bool_exp
orderableFields:
- fieldName: article_id
orderByDirections:
enableAll: true
- fieldName: title
orderByDirections:
enableAll: true
- fieldName: author_id
orderByDirections:
enableAll: true
graphql:
selectUniques:
- queryRootField: ArticleByID
uniqueIdentifier:
- article_id
description: Description for the select unique ArticleByID
selectMany:
queryRootField: ArticleMany
description: Description for the select many ArticleMany
orderByExpressionType: Article_Order_By
apolloFederation:
entitySource: true
description: Description for the model Articles
undefined
Key | Value | Required | Description |
---|---|---|---|
kind | Model | true | |
version | v2 | true | |
definition | ModelV2 | true | The definition of a data model. A data model is a collection of objects of a particular type. Models can support one or more CRUD operations. ModelV2 implements the changes described in rfcs/open-dd-expression-type-changes.md. |
ModelV2
The definition of a data model. A data model is a collection of objects of a particular type. Models can support one or more CRUD operations. ModelV2 implements the changes described in rfcs/open-dd-expression-type-changes.md.
Key | Value | Required | Description |
---|---|---|---|
name | ModelName | true | The name of the data model. |
objectType | CustomTypeName | true | The type of the objects of which this model is a collection. |
globalIdSource | boolean | false | Whether this model should be used as the global ID source for all objects of its type. |
arguments | [ArgumentDefinition] | false | A list of arguments accepted by this model. Defaults to no arguments. |
source | ModelSource / null | false | The source configuration for this model. |
filterExpressionType | CustomTypeName / null | false | The boolean expression type that should be used to perform filtering on this model. |
orderByExpression | OrderByExpressionName / null | false | The order by expression to use for this model. |
aggregateExpression | AggregateExpressionName / null | false | The name of the AggregateExpression that defines how to aggregate over this model |
graphql | ModelGraphQlDefinitionV2 / null | false | Configuration for how this model should appear in the GraphQL schema. |
description | string / null | false | The description of the model. Gets added to the description of the model in the graphql schema. |
ModelGraphQlDefinitionV2
The definition of how a model appears in the GraphQL API. Note: ModelGraphQlDefinitionV2 removed the order_by_expression_type
property. See rfcs/open-dd-expression-type-changes.md.
Key | Value | Required | Description |
---|---|---|---|
selectUniques | [SelectUniqueGraphQlDefinition] | true | For each select unique defined here, a query root field is added to the GraphQL API that can be used to select a unique object from the model. |
selectMany | SelectManyGraphQlDefinition / null | false | Select many configuration for a model adds a query root field to the GraphQl API that can be used to retrieve multiple objects from the model. |
argumentsInputType | GraphQlTypeName / null | false | The type name of the input type used to hold the arguments of the model. |
apolloFederation | ModelApolloFederationConfiguration / null | false | Apollo Federation configuration |
filterInputTypeName | GraphQlTypeName / null | false | The type name of the input type used to hold the filtering settings used by aggregates (etc) to filter their input before processing |
aggregate | ModelAggregateGraphQlDefinition / null | false | Configures the query root field added to the GraphQL API that can be used to aggregate over the model |
Example:
selectUniques:
- queryRootField: ArticleByID
uniqueIdentifier:
- article_id
description: Description for the select unique ArticleByID
selectMany:
queryRootField: ArticleMany
description: Description for the select many ArticleMany
aggregate:
queryRootField: ArticleAggregate
description: Aggregate over Articles
OrderByExpressionName
The name of an order by expression.
Value: string
undefined
Key | Value | Required | Description |
---|---|---|---|
kind | Model | true | |
version | v1 | true | |
definition | ModelV1 | true | The definition of a data model. A data model is a collection of objects of a particular type. Models can support one or more CRUD operations. |
ModelV1
The definition of a data model. A data model is a collection of objects of a particular type. Models can support one or more CRUD operations.
Key | Value | Required | Description |
---|---|---|---|
name | ModelName | true | The name of the data model. |
objectType | CustomTypeName | true | The type of the objects of which this model is a collection. |
globalIdSource | boolean | false | Whether this model should be used as the global ID source for all objects of its type. |
arguments | [ArgumentDefinition] | false | A list of arguments accepted by this model. Defaults to no arguments. |
source | ModelSource / null | false | The source configuration for this model. |
filterExpressionType | CustomTypeName / null | false | The boolean expression type that should be used to perform filtering on this model. |
orderableFields | [OrderableField] | true | A list of fields that can be used to order the objects in this model. |
aggregateExpression | AggregateExpressionName / null | false | The name of the AggregateExpression that defines how to aggregate over this model |
graphql | ModelGraphQlDefinition / null | false | Configuration for how this model should appear in the GraphQL schema. |
description | string / null | false | The description of the model. Gets added to the description of the model in the graphql schema. |
ModelGraphQlDefinition
The definition of how a model appears in the GraphQL API.
Key | Value | Required | Description |
---|---|---|---|
selectUniques | [SelectUniqueGraphQlDefinition] | true | For each select unique defined here, a query root field is added to the GraphQL API that can be used to select a unique object from the model. |
selectMany | SelectManyGraphQlDefinition / null | false | Select many configuration for a model adds a query root field to the GraphQl API that can be used to retrieve multiple objects from the model. |
argumentsInputType | GraphQlTypeName / null | false | The type name of the input type used to hold the arguments of the model. |
orderByExpressionType | GraphQlTypeName / null | false | The type name of the order by expression input type. |
apolloFederation | ModelApolloFederationConfiguration / null | false | Apollo Federation configuration |
filterInputTypeName | GraphQlTypeName / null | false | The type name of the input type used to hold the filtering settings used by aggregates (etc) to filter their input before processing |
aggregate | ModelAggregateGraphQlDefinition / null | false | Configures the query root field added to the GraphQL API that can be used to aggregate over the model |
Example:
selectUniques:
- queryRootField: ArticleByID
uniqueIdentifier:
- article_id
description: Description for the select unique ArticleByID
selectMany:
queryRootField: ArticleMany
description: Description for the select many ArticleMany
orderByExpressionType: Article_Order_By
aggregate:
queryRootField: ArticleAggregate
description: Aggregate over Articles
ModelAggregateGraphQlDefinition
The definition of the GraphQL API for aggregating over a model.
Key | Value | Required | Description |
---|---|---|---|
queryRootField | GraphQlFieldName | true | The name of the query root field for this API. |
description | string / null | false | The description of the aggregate graphql definition of the model. Gets added to the description of the aggregate root field of the model in the graphql schema. |
deprecated | Deprecated / null | false | Whether this aggregate query field is deprecated. If set, the deprecation status is added to the aggregate root field's graphql schema. |
subscription | SubscriptionGraphQlDefinition / null | false | Enable subscription on this aggregate root field. |
ModelApolloFederationConfiguration
Apollo Federation configuration for a model.
Key | Value | Required | Description |
---|---|---|---|
entitySource | boolean | true | Whether this model should be used as the source for fetching _entity for object of its type. |
GraphQlTypeName
The name of a GraphQL type.
Value: string
SelectManyGraphQlDefinition
The definition of the GraphQL API for selecting rows from a model.
Key | Value | Required | Description |
---|---|---|---|
queryRootField | GraphQlFieldName | true | The name of the query root field for this API. |
description | string / null | false | The description of the select many graphql definition of the model. Gets added to the description of the select many root field of the model in the graphql schema. |
deprecated | Deprecated / null | false | Whether this select many query field is deprecated. If set, the deprecation status is added to the select many root field's graphql schema. |
subscription | SubscriptionGraphQlDefinition / null | false | Enable subscription on this select many root field. |
SelectUniqueGraphQlDefinition
The definition of the GraphQL API for selecting a unique row/object from a model.
Key | Value | Required | Description |
---|---|---|---|
queryRootField | GraphQlFieldName | true | The name of the query root field for this API. |
uniqueIdentifier | [FieldName] | true | A set of fields which can uniquely identify a row/object in the model. |
description | string / null | false | The description of the select unique graphql definition of the model. Gets added to the description of the select unique root field of the model in the graphql schema. |
deprecated | Deprecated / null | false | Whether this select unique query field is deprecated. If set, the deprecation status is added to the select unique root field's graphql schema. |
subscription | SubscriptionGraphQlDefinition / null | false | Enable subscription on this select unique root field. |
SubscriptionGraphQlDefinition
The definition of the GraphQL API for enabling subscription on query root fields.
Key | Value | Required | Description |
---|---|---|---|
rootField | GraphQlFieldName | true | The name of the subscription root field. |
description | string / null | false | The description of the subscription graphql definition. Gets added to the description of the subscription root field in the graphql schema. |
deprecated | Deprecated / null | false | Whether this subscription root field is deprecated. If set, the deprecation status is added to the subscription root field's graphql schema. |
pollingIntervalMs | integer | false | Polling interval in milliseconds for the subscription. |
Deprecated
OpenDd configuration to indicate whether an object type field, relationship, model root field or command root field is deprecated.
Key | Value | Required | Description |
---|---|---|---|
reason | string / null | false | The reason for deprecation. |
GraphQlFieldName
The name of a GraphQL object field.
Value: string
AggregateExpressionName
The name of an aggregate expression.
Value: string
OrderableField
A field that can be used to order the objects in a model.
Key | Value | Required | Description |
---|---|---|---|
fieldName | FieldName | true | |
orderByDirections | EnableAllOrSpecific | true | Enable all or specific values. |
EnableAllOrSpecific
Enable all or specific values.
Must have exactly one of the following fields:
Key | Value | Required | Description |
---|---|---|---|
enableAll | boolean | false | |
enableSpecific | [OrderByDirection] | false |
OrderByDirection
Value: Asc
/ Desc
FieldName
The name of a field in a user-defined object type.
Value: string
ModelSource
Description of how a model maps to a particular data connector
Key | Value | Required | Description |
---|---|---|---|
dataConnectorName | DataConnectorName | true | The name of the data connector backing this model. |
collection | CollectionName | true | The collection in the data connector that backs this model. |
argumentMapping | ArgumentMapping | false | Mapping from model argument names to data connector collection argument names. |
Example:
dataConnectorName: data_connector
collection: articles
ArgumentMapping
Mapping of a comand or model argument name to the corresponding argument name used in the data connector. The key of this object is the argument name used in the command or model and the value is the argument name used in the data connector.
Key | Value | Required | Description |
---|---|---|---|
<customKey> | DataConnectorArgumentName | false |
DataConnectorArgumentName
The name of an argument as defined by a data connector.
Value: string
CollectionName
The collection in the data connector that backs this model.
Value: string
DataConnectorName
The name of the data connector backing this model.
Value: string
ArgumentDefinition
The definition of an argument for a field, command, or model.
Key | Value | Required | Description |
---|---|---|---|
name | ArgumentName | true | The name of an argument. |
type | TypeReference | true | |
description | string / null | false |
TypeReference
A reference to an Open DD type including nullable values and arrays. Suffix '!' to indicate a non-nullable reference, and wrap in '[]' to indicate an array. Eg: '[String!]!' is a non-nullable array of non-nullable strings.
Value: string
ArgumentName
The name of an argument.
Value: string
CustomTypeName
The name of a user-defined type.
Value: string
ModelName
The name of data model.
Value: string