Add a Relay Node Interface to a GraphQL Schema

Josh Black
InstructorJosh Black

Share this video with your friends

Send Tweet
Published 5 years ago
Updated 3 years ago

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.

[00:01] 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."

[00:20] 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.

[00:34] 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.

[00:52] 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.

[01:05] 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.

[01:19] 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.

[01:34] 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.

[01:57] 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.

[02:09] 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.

[02:22] 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.

[02:42] 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.

[02:59] 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.

[03:22] 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.

[03:39] 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.

[04:05] 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.

[04:28] 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.

[04:40] 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.

[04:52] 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.

[05:06] 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.

[05:14] 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.

[05:28] 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.

[05:45] 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.

[05:56] To fix this, we'll just need to do 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.

[06:15] 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.

[06:37] 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.

~ 5 years ago

The reason for the error at the end is that you created a circular import. I already felt this could lead to problems when you did that in lesson 12...

Josh Black
Josh Blackinstructor
~ 5 years ago

Hi Chris! Glad to see you spotted the error 😄.

In this series, the hope was to try and emulate an issue that I've found to be common when people are starting out with GraphQL. In this case, the error would be that circular import like you described previously.

Awesome to see that you caught it, but I also wanted to walk through solving the problems for others who might end up in a similar situation to what was crafted in the video.

~ 4 years ago

Late to the party, but why is videoType out of scope the first time?

I thought the difficulty was OK. The real issue is the teacher commenting on what he types (no need to do that IMO since we can see that on the screen or look up on github) as opposed to taking a step back to explain why he's doing what he's doing and what all of these concepts mean which would be 10 times more productive as far as learning goes.

~ 4 years ago

I thought that the graphql course was short, and apart from not showing anything that you can not read in the first steps of the documentation until the 11th video, I now realize that the last three videos are useless for non-React developers.