Skip to main content
  • @Relation - A relation that is a single value (one-to-one, many-to-one)
  • @FilterableRelation - A @Relation that enables filtering the parent by fields of the relation DTO.
  • @UnPagedRelation - An array of relations (e.g, many-to-many, one-to-many) that returns all of the related records.
  • @FilterableUnPagedRelation - An @UnPagedRelation that enables filtering the parent by fields of the relation DTO.
  • @OffsetConnection - A connection that represents a collection (e.g, many-to-many, one-to-many) that uses offset based pagination.
  • @FilterableOffsetConnection - An @OffsetConnection that enables filtering the parent by fields of the connection DTO.
  • @CursorConnection - A connection that represents a collection (e.g, many-to-many, one-to-many) that uses cursor based pagination.
  • @FilterableCursorConnection - A @CursorConnection that enables filtering the parent by fields of the connection DTO.
@FilterableUnPagedRelation, @FilterableOffsetConnection, and @FilterableCursorConnection are not supported by mongoose!
When loading relations a dataloader that is scoped to the request will be used. This prevents the n+1 problem.
In the following examples we are going to use the following entities.
todo-item/todo-item.entity.ts

@Relation​

A relation that is a single value (one-to-one, many-to-one)

Example​

Based on the entities defined above we can add a todoItem relation to the SubTask by creating the following SubTaskDTO with a @Relation decorator.
sub-task/sub-task.dto.ts
The @Relation decorator lets nestjs-query know to expose the following endpoints:
  • subTask.todoItem - A query to retrieve the SubTasks TodoItem
  • setTodoItemOnSubTask - A mutation to set the TodoItem on a SubTask.
  • removeTodoItemFromSubTask - A mutation to remove a TodoItem/SubTask relation.
    • NOTE This does not typically remove either record just removes the relation.
To set up the resolver you can use the NestjsQueryGraphQLModule.
sub-task/sub-task.module.ts
@ptc-org/nestjs-query-graphql will then automatically create the following graphql definition:
The following mutations will also be automatically exposed.
If remove.enabled was set to true a removeTodoItemFromSubTask mutation would also be exposed with the same arguments as setTodoItemOnSubTask.

@FilterableRelation​

The @FilterableRelation extends the @Relation decorator exposing the ability to filter the DTO that defines the relation by relation properties.
The @FilterableRelation decorator will only work with relations defined by the orm used (e.g. typeorm, sequelize). If your relations are federated or you are using mongoose you cannot use the @FilterableRelation decorator.

Example​

In this example we’ll use the same Entities defined above to create a graphql endpoint that allows filtering SubTasks by TodoItems.
sub-task/sub-task.dto.ts
Notice the use of @FilterableRelation instead of @Relation, by using the @FilterableRelation version nestjs-query will allow filtering on the todoItem relation. The module definition remains the same.
sub-task/sub-task.module.ts
When querying for SubTasks you can now also filter on todoItem properties. In this example we’ll find all subTasks that are related to a todoItem with a title that starts with Created.

@UnPagedRelation​

You can also use the @UnPagedRelation decorator to define a relation that does not use paging and returns an array of all the related records.

Example​

Based on the entity definition above we can define a TodoItemDTO with a subTasks relation.
todo-item/todo-item.dto.ts
When specifying a many relation a couple of endpoints will automatically be generated. In this example the following are generated.
  • todoItem.subTasks - A query endpoint to retrieve a TodoItems SubTasks.
    • The subTasks property will accept a query to allow you to filter, and sort results.
    • The subTasks will be returned as an array of results.
  • addSubTasksToTodoItem - A mutation to add SubTasks to a TodoItem.
To set up the resolver you can use the NestjsQueryGraphQLModule.
todo-item/todo-item.module.ts
The generated schema will contain a TodoItem type like the following.
The following mutations will also be automatically exposed.
If remove.enabled was set to true a removeSubTasksFromTodoItem mutation would also be exposed with the same arguments as addSubTasksToTodoItem.

@FilterableUnPagedRelation​

The @FilterableUnPagedRelation extends the @UnPagedRelation decorator exposing the ability to filter the DTO that defines the relation by relation properties.
The @FilterableUnPagedRelation decorator will only work with relations defined by the orm used (e.g. typeorm, sequelize). If your relations are federated or you are using mongoose you cannot use the @FilterableUnPagedRelation decorator.

Example​

In this example we’ll use the same Entities defined above to create a graphql endpoint that allows filtering TodoItems by SubTasks.
todo-item/todo-item.dto.ts
Notice the use of @FilterableUnPagedRelation instead of @UnPagedRelation, by using the @FilterableUnPagedRelation version nestjs-query will allow filtering on the subTasks relation. The module definition remains the same.
todo-item/todo-item.module.ts
When querying for TodoItems you can now also filter on subTasks properties. In this example we’ll find all todoItems that are related to a subTasks that are completed.

@OffsetConnection​

Example​

Based on the entity definitions above we can create a TodoItemDTO with a connection to the subTasks.
todo-item/todo-item.dto.ts
When specifying a @OffsetConnection relation a couple of endpoints will automatically be generated. In this example the following are generated.
  • todoItem.subTasks - A query to retrieve a TodoItems SubTasks.
    • The subTasks property will accept a query to allow you to filter, page and sort results.
    • The subTasks property will return a offset based connection to page through results.
  • addSubTasksToTodoItem - A mutation to add SubTasks to a TodoItem.
To set up the resolver you can use the NestjsQueryGraphQLModule.
todo-item/todo-item.module.ts
The generated schema will contain a TodoItem type like the following.
The following mutations will also be automatically exposed.
If remove.enabled was set to true a removeSubTasksFromTodoItem mutation would also be exposed with the same arguments as addSubTasksToTodoItem.

Total Count Example​

Enabling totalCount can be expensive. If your table is large the totalCount query may be expensive, use with caution.
The totalCount field is not eagerly fetched. It will only be executed if the field is queried from the client.
When using the @OffsetConnection decorator you can enable the totalCount field. The totalCount field will return the total number of records included in the connection.
todo-item/todo-item.dto.ts
The generated graphql will include a TodoItemSubTasksConnection with a totalCount field.

@FilterableOffsetConnection​

The @FilterableOffsetConnection extends the @OffsetConnection decorator exposing the ability to filter the DTO that defines the relation by relation properties.
The @FilterableOffsetConnection decorator will only work with relations defined by the orm used (e.g. typeorm, sequelize). If your relations are federated or you are using mongoose you cannot use the @FilterableConnection decorator.

Example​

In this example we’ll use the same Entities defined above to create a graphql endpoint that allows filtering TodoItems by subTasks.
todo-item/todo-item.dto.ts
Notice the use of @FilterableOffsetConnection instead of @OffsetConnection, by using the @FilterableOffsetConnection version nestjs-query will allow filtering on the subTasks relation. The module definition remains the same.
todo-item/todo-item.module.ts
When querying for TodoItems you can now also filter on subTasks properties. In this example we’ll find all todoItems that have subTasks that are completed.

@CursorConnection​

Example​

Based on the entity definitions above we can create a TodoItemDTO with a connection to the subTasks.
todo-item/todo-item.dto.ts
When specifying a @CursorConnection relation a couple of endpoints will automatically be generated. In this example the following are generated.
  • todoItem.subTasks - A query to retrieve a TodoItems SubTasks.
    • The subTasks property will accept a query to allow you to filter, page and sort results.
    • The subTasks property will return a cursor based connection to page through results.
  • addSubTasksToTodoItem - A mutation to add SubTasks to a TodoItem.
To set up the resolver you can use the NestjsQueryGraphQLModule.
todo-item/todo-item.module.ts
The generated schema will contain a TodoItem type like the following.
The following mutations will also be automatically exposed.
If remove.enabled was set to true a removeSubTasksFromTodoItem mutation would also be exposed with the same arguments as addSubTasksToTodoItem.

Total Count Example​

Enabling totalCount can be expensive. If your table is large the totalCount query may be expensive, use with caution.
The totalCount field is not eagerly fetched. It will only be executed if the field is queried from the client.
When using the @CursorConnection decorator you can enable the totalCount field. The totalCount field will return the total number of records included in the connection.
todo-item/todo-item.dto.ts
The generated graphql will include a TodoItemSubTasksConnection with a totalCount field.

@FilterableCursorConnection​

The @FilterableCursorConnection extends the @CursorConnection decorator exposing the ability to filter the DTO that defines the relation by relation properties.
The @FilterableCursorConnection decorator will only work with relations defined by the orm used (e.g. typeorm, sequelize). If your relations are federated or you are using mongoose you cannot use the @FilterableConnection decorator.

Example​

In this example we’ll use the same Entities defined above to create a graphql endpoint that allows filtering TodoItems by subTasks.
todo-item/todo-item.dto.ts
Notice the use of @FilterableCursorConnection instead of @CursorConnection, by using the @FilterableCursorConnection version nestjs-query will allow filtering on the subTasks relation. The module definition remains the same.
todo-item/todo-item.module.ts
When querying for TodoItems you can now also filter on subTasks properties. In this example we’ll find all todoItems that have subTasks that are completed.

Virtual Relations​

You may run into a case where you have a virtual relation that does not exist in the database. nestjs-query supports this through the RelationQueryService.

Options​

The following options can be passed to all relation/connection decorators, to customize functionality.
  • relationName - The name of the relation to use when looking up the relation from the QueryService
  • nullable - Set to true if the relation is nullable.
  • complexity - Set to specify relation complexity. For more info see complexity docs
  • disableRead - Set to true to disable read operations.
  • update
    • enabled - Set to true to enable update operations.
    • description - The description of the update operation.
    • complexity - Set to specify relation complexity. For more info see complexity docs
    • decorators=[] - An array of custom PropertyDecorator or MethodDecorators to add to the endpoint.
  • remove
    • enabled - Set to true to enable remove operations.
    • description - The description of the remove operation.
    • complexity - Set to specify relation complexity. For more info see complexity docs
    • decorators=[] - An array of custom PropertyDecorator or MethodDecorators to add to the endpoint.
  • allowFiltering - Set to true to allow filtering on the relation.
  • guards=[] - An array of guards to add to update and remove endpoints.
  • interceptors=[] - An array of interceptors to add to update and remove endpoints.
  • pipes=[] - An array of pipes to add to update and remove endpoints.
  • filters=[] - An array of filters to add to update and remove endpoints.
guards, pipes, interceptors and filters will not work by default with relation endpoints. See https://docs.nestjs.com/graphql/tooling#execute-enhancers-at-the-field-resolver-level

Custom Relation Name​

Sometimes you may want to expose a relation that has a different name when persisted from the graphql property. To do this use the relationName property.

GraphQL lookahead​

This functionality only works for typeorm!
When you want to optimze your database queries you can set enableLookAhead, this will join and select the relation when it’s being fetched in the query.

Disable Reads​

To disable the read queries you can set the disableRead option to true.

Disable filter or sorting in relations​

To disable the filter or sorting of relations you can set the disableFilter or/and disableSort option to true.
This is not available in relation as it will only fetch one record.

Enable Updates​

To enable the update mutations you can set the update.enabled option to true.

Enable Removes​

To enable the remove mutations you can set the remove.enabled option to true.

Guards, Pipes and Filters​

NOTE guards, pipes, interceptors and filters will not work by default with read endpoints. See https://github.com/nestjs/graphql/issues/295 In this example we’ll just demonstrate using a guard but the same pattern applies for pipes, filters and interceptors To set up a guard for endpoint you can use the guards option. Assume we have the following auth guard that checks for a certain header and value.
auth.guard.ts
We can then add it to our relations
Now any requests that go to the update or remove endpoints will require the guard.

Relation Mixin​

If you are using the resolvers individually you can use the following mixins to add relations functionality.

Relatable​

When using The Relatable mixin adds all relations functionality to a resolver. In this example we expose on read endpoints for todo items with the relations defined on the TodoItemDTO.
todo-item/todo-item.resolver.ts