Customization

Learn how to add custom types, queries, subscriptions and middleware to the GraphQL API

You may need to add custom type definitions, queries and mutations to the GraphQL API. Tensei makes this easy by exposing a simple API to handle this.

Add custom types

You may use the .graphQlTypeDefs() method on the tensei instance to add custom type definitions:

export default tensei()
    .graphQlTypeDefs([`
        type aggregateComments {
            count: Int!
            average: Int!
        }

        extend type Query {
            aggregateComments: aggregateComments
        }
    `])

If you are developing a plugin, you may use the .extendGraphQlTypeDefs() method to extend the types:

plugin('Database backup plugin')
    .register(({ extendGraphQlTypeDefs }) => {
        extendGraphQlTypeDefs([`
            type DatabaseBackup {
                fileName: String!
                createdAt: String!
            }

            extend type Mutation {
                backupDatabase(databaseName: String!): Boolean!
            }

            extend type Query {
                getExistingBackups(): DatabaseBackup!
            }
        `])
    })

Add custom queries

All GraphQL queries in Tensei are defined using a GraphQlQuery instance. To create an instance, Tensei exports a graphQlQuery method. Let's define an example mutation using this method:

import { graphQlQuery } from '@tensei/core'

graphQlQuery('Get database backups') // Create a new GraphQLQuery instance, giving it a name
    .mutation() // Make this instance a mutation type. .query() and .subscription() are also supported
    .path('getDatabaseBackups') // Define the mutation, query or subscription path for this query
    .handle(async (parent, args, ctx, info) => {
        const backups = await ctx.manager.find('Backup', {}, { limit: 5 })

        return backups
    }) // Provide the resolver for this query
  • The graphQlQuery(name) method creates a new GraphQLQuery instance, giving it a name
  • The .mutation() method makes this instance a mutation type. .query() and .subscription() are also supported.
  • The .path() method assigns the specific path for this query.
  • The .handle() method defines the query resolver.

To register your custom queries with the tensei application, you may call the .graphQlQueries() method on the tensei instance:

import { tensei, graphQlQuery } from '@tensei/core'

export default tensei()
    .graphQlQueries([
        graphQlQuery('Get Purchases')
            .query()
            .path('getCustomerPurchases')
            .handle(async (parent, args, ctx, info) => ctx.user.purchases)
    ])

Likewise, if you are developing a plugin, you may use the .extendGraphQlQueries() method to add custom graphql queries to the api:

import { graphQlQuery } from '@tensei/common'

export default () => plugin('Get Purchases')
    .register(({ extendGraphQlQueries }) => {
        extendGraphQlQueries([
            graphQlQuery('Get Purchases')
                .query()
                .path('getCustomerPurchases')
                .handle(async (parent, args, ctx, info) => ctx.user.purchases)
        ])
    })