The ability to reply to discussions is limited to PRO members. Want to join in the discussion? Click here to subscribe now.

Add an Interface to a GraphQL Schema

Add an Interface to a GraphQL Schema

5:18
As we start building out more complex GraphQL schemas, certain fields start to repeat across different types. This is a perfect use-case for the Interface Type made available to us through GraphQL’s Type System. In this video, we’ll go over how to create an Interface Type and how to add it to an existing type in a GraphQL Schema.
Watch this lesson now
Avatar
egghead.io

As we start building out more complex GraphQL schemas, certain fields start to repeat across different types. This is a perfect use-case for the Interface Type made available to us through GraphQL’s Type System. In this video, we’ll go over how to create an Interface Type and how to add it to an existing type in a GraphQL Schema.

Avatar
Sébastien

Great series so far, but this specific part was unclear to me. I thought an interface could be meant to factorize code and avoid repeating types, but 'fields' still has 'id', there was no change there. So I assume instead it is to make sure that a field 'id' has the same contract among all the GraphQLObjectType that use that same interface (here NodeInterface). The resolveType function still confused me, why do you need to test for 'title' and return videoType? How is it re-usable if you hard code the type?

In reply to egghead.io
Avatar
Josh Black

Hi Sébastien! First off, wanted to say thanks for watching 😄

I thought an interface could be meant to factorize code and avoid repeating types, but 'fields' still has 'id', there was no change there.

Totally understand the confusion here, and sorry for not explaining it clearly enough!

The goal of a GraphQL Interface is to express what fields are shared across the types that implement that interface. In the example with id here, the goal of the Interface is to specify that all types that implement that Interface have an id field with the GraphQLID type.

Unfortunately, the interface doesn't act as a way to re-use existing code. For example, let's say we have the following types in our GraphQL Schema:

interface Name {
  name: String!
}

type Person implements Name {
  name: String!
  firstName: String!
  lastName: String!
}

type Animal implements Name {
  name: String!
  # Some other fields go here...
}

In this case, Person and Animal both implement the Name interface. Getting the name for an animal should just be a simple lookup in our database. However, for a Person the name field could be a combination of their firstName and lastName field.

As a result, we can't share the resolve methods for this field, and so sharing what we've defined in an Interface won't actually satisfy how we want to resolve the fields on each type that has implemented that interface.

Hope this helps explain the role of an Interface a little bit more. If not, I can definitely elaborate!

In reply to Sébastien
Avatar
utkarsh

Really enjoying the course :)
Based on your reply to Sebastien, the interface exists more as a validation to ensure that a particular type is implementing the interface (example id of type GraphQLID) correctly? Thanks!

In reply to Josh Black
Avatar
Josh Black

Hi utkarsh! Glad to hear you're enjoying it! 😄 And yupp, that's exactly it (from my perspective).

In reply to utkarsh
Avatar
Maxim

Great course Josh, really enjoying it, thanks a lot for putting all of it together. One small thing, not related to GraphQL, is that in this video you introduce a circular dependency (index.js depends on node.js and vice versa). Which means you get tightly coupled modules that goes against the concept of modularity. So the most naive option to work around that issue I guess would be to define that resolveType() function in index.js and pass it on to a function in node.js, say, getNodeInterface() that will set resolveType to the passed function. Defining the interface in index.js is also an option.

Keep those lessons coming! 😁

HEY, QUICK QUESTION!
Joel's Head
Why are we asking?