Server-Side GraphQL in Next.js

Interface Types

Scott Moss

Scott Moss

Superfilter AI
Server-Side GraphQL in Next.js

Check out a free preview of the full Server-Side GraphQL in Next.js course

The "Interface Types" Lesson is part of the full, Server-Side GraphQL in Next.js course featured in this preview video. Here's what you'd learn in this lesson:

Scott explains that an interface is like an abstract type that can be implemented by other object types. He demonstrates how to define an interface in the schema and how to implement it in different object types. He also shows how to query for common fields shared by objects that implement the interface, as well as specific fields for each object type.


Transcript from the "Interface Types" Lesson

>> Scott Moss: We talked about scalar types, we're talking about object types. We mentioned the query type. I promise I'll get to it in more detail at the bottom of this, but let's get more into some other things here. So we have this other thing called interface type. If you've ever used any type system in your life where there's TypeScript or type-based language like Java, you kinda already know what interface is.

Interface is like abstract type. It itself isn't an object, but it can be implemented by other object types. So for instance, you might have interface called character, and a character can be implemented by other optic types. So if I'm making a video game and I have interface called character, I might have two object types that are of the type character.

They share these same four fields, but they also have their own different fields, right? So they share this interface because all characters need a ID, a name, friends, and appears in, but this other object type over also has these fields, and this object type has these fields. So that's what a interface is.

So we can play around with that. So if we go back to our schema and we make an interface here.
>> Scott Moss: I can say interface, and I'll call this a, I guess I will do the same thing, character. So we can say character, and I'm just gonna take the name off a person and put it on character because all characters have a name.

They have an outfit, I guess. That's a string, right? And then they have strengthStat, okay? And that is gonna be an integer that's required. So now that I have that, I can go down to my person and I can say this implements character. The only thing is you have to put all the fields on it again.

Was just kinda redundant, but it makes sense if you dive into the tooling. And then I can put any other fields in addition to a character that a person needs. So let's say a person also has backgroundStory.
>> Scott Moss: Something like that, right? So I could do that. And then I could make another type that implements character.

And I'll call this,
>> Scott Moss: An alien. And so having a backgroundStory, they have a homeWorld, something like that.
>> Scott Moss: And then what I could do is instead of, actually I'll just make another query and I'll call it characters, plural. And it's gonna return a list of character, like that.

>> Scott Moss: And I'm gonna say the list is non-null, so it must always return an array. I could also put an exclamation inside the array and say, not only does it have to return an array, the array cannot be empty. So that is something you can do as well.

>> Scott Moss: So I'll do that. And let's see if we didn't break anything.
>> Scott Moss: Okay, nothing broke, that's great [LAUGH] cuz it will break if it's very strict. So now that I have that, what I can do is I'm just gonna get rid of this query. And I'm going to say, give me a character.

And then now you can see here on the left it's like, okay, cool, you want a character? But you have these other things that implement the character. You have a person that implements the character, you also have an alien that implements the character. So I'm gonna say, give me all the common fields, I want those common fields.

So let me run this, right-click. You can see I have the common fields. But notice, how do I know which one of these is an alien or which one is a person? There's no indication of that, they both implement the character. Well, there's a couple things you can do.

One, you can add this field called typename, like this. And what this will do, it will tell you the type of the object that you are resolving to. So in this case, you can see typename shows person or alien here. So that's one way you could figure it out.

But now let's say I actually wanna get this specific fields for the specific implementation. So for the person, that's gonna be backgroundStory. And then for the alien, that's homeWorld. Notice it added these characters here. It added this dot dot dot on dot dot dot on, right? So this is what's called an inline fragment.

And it's basically saying, okay, these are the common fields for characters. So I don't have to specify what object type I want these to come from cuz they all share these. But these are the specific fields. So when the character is a person, I also want the backgroundStory.

When the character is an alien, I want its homeWorld. That's what the dot dot dot on is. But you can think of this as when a person give me this, when an alien give me that. So I'm not gonna run this. You can see, for the aliens I get the homeWorld, for the persons I get backgroundStory.

So you can start to see how you can compose different pieces of data from different places that share similar things but also are quite different, but yet still, from a client side, make one query. And if you notice, we get back the exact same shape in the exact same order that we requested, name, name, outfit, outfit, strengthStat, backgroundStory.

Everything's exactly the same, right? If I got rid of outfit, then it's gonna be gone, it's not gonna be there. Just because it's all a scheme and that'll mean I'm gonna get it back, right? The way you would handle this in rest is, I'm just gonna give you back everything that's public for this resource and send it back.

And then if you wanna optimize for that, you'll build a query builder on the end of that URL. You'll say, okay, all right, well, you wanna do specific fields? Okay, I'll add support for a query string where you can say select or you can say fields. And then maybe you can pass me a JSON object that has the fields, the field name you want, colon, true or false, and I'll return it, right?

That's how it works.
>> Speaker 2: What's the difference between the exclamation mark on the character in the array versus on the array itself?
>> Scott Moss: Yeah, great question. So the exclamation mark follows what you want to be required. So in this case, I have a exclamation mark outside the array, that means characters has to return an array.

The array can be empty, but it has to return an array. The exclamation mark on the inside is saying, the array cannot be empty, it must have a character in it at least. So this is saying, it must return a non-null array that has at least one value in it.

If I got rid of the inside exclamation, this is just saying there will for sure always be an array, there just might not be anything in it. If I got rid of one on the outside, it saying, there might not be an array, and even if there was an array, there might not be anything in the array.

If I just put one on the inside and nothing on the outside, this is saying, there might not be an array, but if there was an array, there would for sure be something in it. So I don't know why you would ever have that, but really just depends on your application.

For me, if I have an array type, I always do that cuz you should always want an array to come back even when it's empty. That way, it doesn't break your app cuz I'm thinking of a UI. You're gonna be mapping over an array inside of React probably.

You don't wanna check to see if their arrays is there or not. It's much easier for the array to be empty. So you had to change your code, then for it to not exist in the first place, where that's gonna create a branch in your code. So for me, I always just make sure the array has exclamation on the outside.

This part, that's gonna be use case. That's gonna be determined on your use case, but for me, I always make sure the arrays is required. And that's just something that I've learned.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now