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.