Introduction to GraphQL Interfaces
This course has been updated! We now recommend you take the Server-Side GraphQL in Node.js course.
Transcript from the "Interfaces" Lesson
>> Scott Moss: We'll go over to our next lesson which is gonna be Interfaces, Unions, and Fragments. This one is really cool, I really like this one. Yeah, so interfaces, basically, they are inheritable types for your schema. So far, we've made types, we made a product type. There were some other types in there.
[00:00:18] But what if you have types that are very similar, they have very similar fields but some are slightly different? That's an interface. If you ever use typescript or any type check language, they have a constant interfaces. This is the exact same thing but for GraphQL. So we can create interfaces for our similar types.
[00:00:37] So some types are very similar with the exception of a few fields. You can use the interface as a base type and have other types implement that interface just like a language type system. So what am I actually talking about? Let's head over to our schema here, let me get rid of this stuff.
[00:00:53] Basically, what I'm saying is you have the ability to do something like this. You could say, instead of using the word type, which we have been using, and the word input, which we have been using, you can use the word interface. And then you can give it a name.
[00:01:06] So I can call this interface a animal, and I can give it fields. I can say animal has a species, which is like a string. And then like a location, which is a string, right? And they're both required, or not null. So I have interface. Now, interface is exactly like a type.
[00:01:29] It can be used in the same place as types can be used. It's literally used as type with the extra ability of the fact that it can be implemented in other types. So now that I have an animal and I want to make a tiger type, I can say, type Tiger is going to implement
>> Scott Moss: The animal interface, like this. And then, I have to give it the exact same fields with the exact same validations that the interface did. I wish they would do this for us, but you have to put them here again, you have to duplicate them. I know, it's like, why won't you just let, if I'm implementing the animal, then of course I want those.
[00:02:09] But no, you still have to put them again, it's very explicit. And then now, you can add all the other stuff, like how many stripes do you have? And then that's the difference, is that it had stripes, and the animal didn't. So unlike type systems, where it saves you time to do this, and that's why you would do an interface, this doesn't save you time because you still have to copy all the fields over.
[00:02:33] So why would you do this? Well, this is basically great when you have a request where you want, let me think of a good example. So for in this case with a animal, if we have a request where we wanna get all the animals for the zoo, and we wanna do it in one query, like just give me all the animals, this is where we would make an interface.
[00:02:57] Cuz I don't wanna make a query for a tiger and a giraffe and a lion. I just want give me all the animals, but they all have slightly different properties on them. So this is why you would make this. But the only problem is if you're asking for all animals and it's sending you back animals, but then in that query you ask for stripes, but it a lion doesn't have stripes, it doesn't have the property stripes, then GraphicQL will break.
[00:03:25] So they have to create another way for you to get around that, and that's were fragments come in. So you didn't have to use the fragments in your request query to conditionally ask for the type of the specific fields. So in this case, what I'm talking about, let's just go to, I'll do a live example here.
[00:03:42] Let's go back to server. It's been working out pretty good for us. I'll get rid of this, get rid of this. So in this case, let's do that type animal again, or interface animal.
>> Scott Moss: Interface animal, species, as a string. And then I'll make it type Tiger that implements
>> Scott Moss: An animal. And then it has to have the species there exactly the same. I'll actually make that like that.
>> Scott Moss: So we got that. And then it just has stripes, stripeCount or whatever. That's gonna be a Int. Cool, so we got that. And then I'm gonna say type Lion implements animal.
>> Scott Moss: And it too has to have a species exactly the same. And then I will say mainColor.
>> Scott Moss: Cool, so if I do that, I have some resolvers here. Let's make a query.
>> Scott Moss: Type query, and I will say animals. And so, I'll get back in array of animals, like that.
[00:05:15] There we go. Get rid of that mutation, and then we'll just go ahead and make the query here.
>> Scott Moss: For animals.
>> Scott Moss: There we go, and we're just gonna return an array of animals. So if I return an array of animals here which have just an object with a species on it, so I'll do that, species, tiger.
[00:05:41] And then, we'll make another one for species lion, okay? So we'll start there.
>> Scott Moss: So let's start the server.
>> Scott Moss: Got it, comma. There we go. I forgot that comma.
>> Scott Moss: What we got here? Did I fat finger something? Yeah, animal. There we go. See, it's very strict.
>> Scott Moss: Okay, so now that that's running, and you can see we get this error here. It's not a error, it's more like a warning. And this is what we're gonna talk about, how to fix this later, but don't worry about that right now. So if I head back over to our thing here, let's look at my schema.
[00:06:39] I got animals here. So what I'll do is I'll say, cool. Give me animals and then give me species. So I'll run that, and then boom, I get an error here. Abstract type animal must resolve to an object type at a run time for field query dot animals with value species tiger.
[00:06:55] Receive undefined. Basically, what that's saying is because if we look at our query here for animals, it's returning an animal interface. That's what GraphicQL just said, an error. So that's an abstract type. So it is a type, but it's an abstract, you can't really query on it. This needs to resolve to a full type eventually.
[00:07:16] We need to know what type of animal you're asking for. So in order to do that, you have to add a resolve
>> Scott Moss: Type. And that's what was in that product thing before. So underscore underscore resolve Type on the type that you need to resolve. So in this case, we'd say on the animal type or animal interface, we need to underscore underscore resolve the type.
[00:07:40] That's gonna receive the animal as the first argument. And then given that, you need to return the string of the name of the type that's being asked for. So is it a tiger or is it a lion? So given an animal, which is an animal with a species on it, how do you know what type is it?
[00:07:58] Well, if you look at the data, I'm just putting the type here, so Tiger and Lion. So all I gotta do is just return the species name. So I'll just say return animal dot species, and that's gonna tell me what type it is. It's either gonna be a Tiger or a Lion.
[00:08:13] And Tiger with a capital T and Lion with a capital L matches the exact same names as Tiger with a capital T in the type and Lion with a capital L in the types up here. So what you have to return in the resolved type is the name of the GraphicQL type that this interface is supposed to be resolving to.
[00:08:31] And that's how it knows which one to resolve to, cuz you have to create this resolve type. You're literally resolving the type.
>> Scott Moss: So I'll put something like gorilla here, and then there's no gorilla here, it's gonna be like what's that, that's not a real type, okay? So now that we have that, if we go back and we try to do this again, you can see I get back species Tiger, species Lion.
[00:08:57] So that solved one problem. But I wanna get the stripes of the tiger. But you see as I type in stripes it's not showing up. It's like that's not even real. But I know tigers have stripes according to my schema, stripe count. So how do I get that?
[00:09:15] That's where fragments come in. So we can do these what's called inline fragment in your query where it's dot dot dot, and you use on.
>> Scott Moss: And then you put the name of the type. In this case on a lion. So when this is a lion, give me the main color.
>> Scott Moss: On a tiger, give me the stripe count. I know main is not spelled that way, but whatever.
>> Scott Moss: Yeah. [LAUGH] So if we run that it's not notable because I didn't return anything obviously in my resolver, so it's freaking out. So I gotta add this stuff here, right?
[00:09:59] Like stripeCount: 2, and then mainColor: 'yellow'. Save that, let that rebuild.
>> Scott Moss: And if we go back, run that, and then boom, there we go. You can see, it comes back as just those objects with a species and then the different fields that they have. So as someone querying your API, it's their job to do this.
[00:10:26] It's not your job on a server to do this. You don't have to worry about this. You just need to worry about resolving the type. That's it.
>> Scott Moss: And that's how interfaces work. So they're really cool. Allow you to do stuff like this.