This lesson is for PRO members.

Unlock this lesson NOW!
Already subscribed? sign in

Add a Relay Node Interface to a GraphQL Schema

7:00 JavaScript lesson by

The GraphQL Relay Specification requires that a GraphQL Schema has some kind of mechanism for re-fetching an object. For typical Relay-compliant servers, this is going to be the Node Interface. In this video, we’ll add in the Node interface to a GraphQL Schema by using the helpers available in the graphql-relay npm package.

Get the Code Now
click to level up

egghead.io comment guidelines

Avatar
egghead.io

The GraphQL Relay Specification requires that a GraphQL Schema has some kind of mechanism for re-fetching an object. For typical Relay-compliant servers, this is going to be the Node Interface. In this video, we’ll add in the Node interface to a GraphQL Schema by using the helpers available in the graphql-relay npm package.

Avatar
Sébastien

Great series, first 11 videos go smoothly. Once at 12 and 13, the assumption about prior knowledge (here Relay) is pretty high and the learning curve is a lot steeper. Probably a good time to read about Relay and come back later...

In reply to egghead.io
Avatar
Josh Black

Glad to hear the first 11 videos went well! But am definitely sorry about the jump when we start talking about Relay-specific concepts for GraphQL.

The goal was to be able to take the server we build out in this course and use it together with React/Relay. Unfortunately, in order to make sure that works we had to tackle the three big concepts for Relay-compliant GraphQL Servers:

  • Node identification
  • Connections
  • Mutations

If you're curious about a place to start to learn more about Relay and GraphQL, a great place to start with these topics is the Relay Docs.

If you're looking for additional resources, let me know! I can definitely provide any help on topics that are underdeveloped during this course.

In reply to Sébastien
Avatar
Alex

Josh, what a great series. I finally feel like I have a solid grasp on GraphQL and most importantly what problems it solves. I'm in the same boat as OP, everything prior to this video I consumed, digested, and understood. In this video I definitely feel lost, I'll check out the Relay docs to try to get a better understanding.

I just wanted to add a comment here in case there are considerations for expounding on some of the concepts in this video.

In reply to Josh Black
Avatar
Josh Black

Hi Alex! Just wanted to say thanks for watching the course, and thanks so much for the feedback. I'm sorry that this video made you feel lost, and I'd love to hear what concepts in particular would be useful to cover prior to this video to make sure the transition to the last couple videos is smoother.

Thanks again for watching! Glad to hear it was helpful 😄

In reply to Alex

Part of the ways that we can make this schema relay compliant is to add a mechanism for refetching any kind of object in our schema. In our case, this will be our video type, and we need to be able to refetch any individual video using something called a "relay node interface."

To start off, let's go and use yarn to add graphql-relay to our project. Once that's done, we'll go into source/node.js, and update how we're currently defining our node interface.

The first thing that we'll need to do is actually change our imports here, instead of importing from GraphQL, we're going to be requiring some things from graphql-relay. These fields specifically are node definitions, and then from global ID.

When we use node definitions, we'll actually be able to get both a node interface, like we have defined below, as well as a node field that will add to our query type, all from using the node definitions function.

What this function takes in are two methods. The first one is going to be given a global ID, and from that ID, we should be able to resolve any kind of ID to an individual object.

The second one takes in an object and tells the node definitions function what kind of type this object is. We'll need to implement both of them for this interface and node field to work as expected.

On this first method, what we can do is use the from global ID method to get the type and the ID from any given global ID. The intent here is to be able to have some kind of function, such as get object by ID, that you can give a type and an ID and it will actually resolve the individual object.

We don't have this method yet, let's go and actually import something called get object by ID. We'll require this from our data directory.

Now, let's go into our source data/index.js file and actually implement this method. We'll do const get object by ID, and this function takes in the type and the ID.

What we can do inside of this function is create a types map, and we can say that the video type maps to get video by ID. Then, our return statement can literally be types of type, which in this case, will point to get video by ID. Then, we'll pass in the ID to that method.

We'll export this function now, we'll do exports.get object by ID, goes get object by ID. We have a proper implementation of this get object by ID method that this first part of node definitions needs.

This second method that's a part of node definitions is a way to tell, given an object, what its type is. This is very similar to resolve type over here, we'll actually go and copy and paste that implementation here. If the object has a title, we'll return that video type, otherwise, we don't know what type we're working with, we'll return null.

Last step is just deleting our old interface here and changing our exports. We'll do exports.node interface is equal to node interface. We'll also export that node field, as well, we can use that inside of our query type.

Let's switch on back to our index.js file, and add in an import for a method called global ID field. We'll require this from graphql-relay. We'll also change the require statement from our node interface definition to destructure and to node interface, as well as node field.

Our next step is to update our video type, and so instead of our ID field having this implementation, all we need to do is say ID, and then in global ID field, and we'll just invoke that method and get rid of our old ID. The interface definition actually stays the same, since that relay node definitions helper also gives us that node interface.

Our last step is to actually update our query type. Now, we'll also add a field called node and this is just going to be the node field that we required up above.

Let's go and check out these updates in GraphiQL. We'll run our server using node index.js, and inside of GraphiQL, we can run a query for all of our videos and we'll get their ID.

When we run our query, we can see that the global ID field is actually generating these base 64 encoded IDs that are combining the type and the ID information for each individual video.

We also have a new field that we can query on called node, which is given to us from the node field, and we pass in an ID.

We can grab one of these IDs here. The idea is that we should be able to query for this node and refetch any given ID. We can use a fragment on video and try and get the title of this.

If we run this query, though, we'll actually run into an area here where we're saying types of type is not a function. Let's go and investigate this inside of our editor. Here, we're just inside of that node.js file and we'll log out the type and the ID.

We'll go and restart our server once again, run the same exact query, and we'll see that what's logged out is Video with a capital V and then the ID is A.

To fix this, we'll just need to do type.to a lowercase, and then when we rerun our server and run the query, we'll see that we get another error that's talking about how our abstract type node has to resolve to some kind of object type.

Let's go and investigate this error. Looking into our second method here, it's trying to determine the type. Let's actually log out what video type is when this function is executed. We'll restart our server, run our query one more time, and we'll see that the video type is actually undefined.

We can fix this issue by just requiring our video type inside of here. We'll require, from the index.js file up above, get rid of this import, and then when we save our file, rerun our server and execute the query. We get our result, and we're good to go.

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