NestJS Logo

Interfaces

Like many type systems, GraphQL supports interfaces. An interface is an abstract type that defines a set of fields that a type must include to implement the interface (see interfaces in the GraphQL documentation).

Code first#

In the code first approach, you define a GraphQL interface by creating an abstract class annotated with the @InterfaceType() decorator, exported from the @nestjs/graphql package.


import { Field, ID, InterfaceType } from '@nestjs/graphql';

@InterfaceType()
export abstract class Character {
  @Field(() => ID)
  id: string;

  @Field()
  name: string;
}
Warning TypeScript interfaces cannot be used to define GraphQL interfaces.

This generates the following part of the GraphQL schema in SDL:


interface Character {
  id: ID!
  name: String!
}

To implement the Character interface, use the implements key:


@ObjectType({
  implements: () => [Character],
})
export class Human implements Character {
  id: string;
  name: string;
}
Hint The @ObjectType() decorator is exported from the @nestjs/graphql package.

The default resolveType() function generated by the library determines the type based on the value returned from the resolver method. This means that you must return class instances, not plain JavaScript object literals.

To provide a custom resolveType() function, pass the resolveType property in the options object of the @InterfaceType() decorator:


@InterfaceType({
  resolveType(book) {
    if (book.colors) {
      return ColoringBook;
    }
    return TextBook;
  },
})
export abstract class Book {
  @Field(() => ID)
  id: string;

  @Field()
  title: string;
}

Interface resolvers#

So far, interfaces have only let you share field definitions with your objects. To also share the field resolver implementations, create a dedicated interface resolver:


import { Args, Info, Parent, ResolveField, Resolver } from '@nestjs/graphql';

@Resolver((type) => Character) // Reminder: Character is an interface
export class CharacterInterfaceResolver {
  @ResolveField(() => [Character])
  friends(
    @Parent() character, // Resolved object that implements Character
    @Info() { parentType }, // Type of the object that implements Character
    @Args('search', { type: () => String }) searchTerm: string,
  ) {
    // Get character's friends
    return [];
  }
}

The friends field resolver is now registered automatically for all object types that implement the Character interface.

Warning This requires setting the inheritResolversFromInterfaces property to true in the GraphQLModule configuration.

Schema first#

To define an interface in the schema first approach, create a GraphQL interface with SDL:


interface Character {
  id: ID!
  name: String!
}

Then, you can use the typings generation feature (as shown in the GraphQL quick start chapter) to generate the corresponding TypeScript definitions:


export interface Character {
  id: string;
  name: string;
}

Interfaces require an extra __resolveType field in the resolver map to determine which type the interface resolves to. Create a CharactersResolver class and define the __resolveType method, which returns the name of the concrete type:


@Resolver('Character')
export class CharactersResolver {
  @ResolveField()
  __resolveType(value) {
    if ('age' in value) {
      return 'Person';
    }
    return null;
  }
}
Hint All decorators are exported from the @nestjs/graphql package.
Edit on GitHub

Support us

Nest is an MIT-licensed open source project. It can grow thanks to the support of these awesome people. If you'd like to join them, please read more here.

Principal Sponsors

SerpApi LogoTrilon LogoMojam Logo

Sponsors / Partners

Become a sponsor