Server-Side GraphQL in Node.js Interfaces
Transcript from the "Interfaces" Lesson
>> Scott Moss: We also have interfaces. Interfaces, if you ever use a type language, Java, TypeScript, pick one, it's the same thing. Abstract Types that can't be used as field values but instead used as foundations for explicit types. Great for when you have types that share common fields but differ slightly.
[00:00:19] So what does all that mean? Basically that means if you have two or more types that share common fields, but they have like maybe one or two or three fields that are slightly different, then you can use an interface to share those fields. But not for the sake of brevity inside of your code because you still have to provide all the fields regardless if it's a interface.
[00:00:45] But for the sake of your clients, only asking for that interface versus having to ask for individual types or versus having to make a query for every single time, you can make one query for that interface and that interface covers all the types that belong to it. So it saves you on queries basically.
[00:01:05] So an example of that would be, so let's say we have a shoe here, we'll convert shoe to an interface actually. So we'll say interface Shoe, like this, I'll get this stuff, and use the interface keyword just like I did there, paste in your fields, cool. And then from there you can make types that implement the interface, if I say type Sneaker implements Shoe.
[00:01:37] And like I said, this is not for the sake of brevity because I still have to put these fields in here, you still have to put them there. You cannot put those fields there, you still have to put them there. This is not for out of like write in these fields again, so I'm gonna make an interface.
[00:01:50] Now, this is so you don't have to make a whole other query for a shoe, and another query for sneaker, and another query for whatever thing is gonna implement it. You can just make one query for everything that's a shoe, right? All right, so if I have a sneaker, but then let's say a sneaker has a sport field on it, which is a string, something like that.
[00:02:09] And then you have another type of, and this might be a, I don't know, a boot, right? And a boot is a shoe and what do boots have? [LAUGH] Grip, it has grip, I don't know. I don't really wear boots. Cool, so all right, so you can see the sneakers and the boot both share brand and size, brand and size from the interface.
[00:02:39] So a couple things know here the interface describes the common field. Anything that implements an interface has to put all the common fields in their definition of they don't GraphQL will break. It's not an option, you have to put them there. And then you can add whatever you want, the order doesn't matter, you can put sport up but above this, it doesn't matter it's just conventionally you probably put the shared fields first because it's the interface so you put it first.
[00:03:04] And then put whatever you want, so you can never query for a shoe cuz the shoes is an abstract type. Eventually, a shoe is gonna resolve to either a sneaker or it's gonna resolve to a boot. That's it, it can never be a shoe. But from the client side, you can ask for a shoe to get the common fields.
[00:03:29] But then if you want something specific about it, you have to tell GraphQL hey, but for a boot I want this, but for a sneaker I want this. I wanna show what that looks like that sounded really complicated was actually a lot easier. So we shouldn't have to change anything.
[00:03:43] We have shoe type here, a shoe type here. All these returns shoes. So basically what this means now is because shoes and abstract type. We're saying shoes kinda return an array of either boots or sneakers, because the shoes are either now and same thing here. So let's do that.
[00:04:04] And boom, we already get this little, not so much of an error, but it's more of a, hey, by the way, so maybe I said they all have to resolve down. The shoe has to resolve to either sneaker or boot. This warning is telling me, hey, shoe is missing something called __resolveType resolver.
[00:04:21] This is basically saying, Apollo is saying, hey, you didn't teach us what to do when we get a shoe. How do we resolve it? How do we know if the shoe is a sneaker? How do we know if the shoe is a boot? That's what it's saying. So you've got to write a resolver for that.
[00:04:37] So the way you would do that is you just do a __resolveType underneath the type for the interface, which in this case is a shoe. So for a shoe, I would need it. __resolveType, which is also a resolver. And as its first argument it's going to take the shoe.
[00:04:56] So I'm just gonna say shoe, the shoe could be a boot, it could be a sneaker, we don't know yet, it's some object I got resolved. And depending on this object I need to determine if this is a show, I'm sorry, if this is a sneaker or a boot.
[00:05:08] So I gotta go look up here like what could I look at that would tell me? I guess if there's a hasGrip thing on it, or something like that, or this is where you, I mean, I'll make that for that thing, and that's required. So cool, if there's a sport owner, it must be a sneaker.
[00:05:25] If there's not a sport owner, it's a boot. Let's just do that, that's a quick boolean check. So what you can do is you can come down here and you can say, okay, cool, if Shoe., what did I put in there?
>> Speaker 2: Sport.
>> Scott Moss: Sport, there we go.
[00:05:42] Shoe.sport, then you can just put the string, the exact name of the type, as you put it up here. So in this case Sneaker with a capital S. So I'll say I'm gonna return a Sneaker, else just return a Boot. And that's how you tell GraphQL based on the actual value, what type to resolve to, otherwise, it doesn't know.
[00:06:06] So if I start the server up again, I don't get that warning, it goes away, everything's good. And if I go back to playground.
>> Scott Moss: I guess I should add some shoes, so you can actually see what's happening. So we have a query. Here we go, here we go, we got brand Nike size.
[00:06:29] Let's put some sport in here. Sport would be basketball.
>> Scott Moss: Timberland, size 14 and then hasGrip, I don't know, sure I know where Timberland is, [LAUGH] I'm not sure. What else, buddy? So start that again, refresh this, and we'll run a query to get some shoes. So shoes and we can say, let's get all the common fields first on the shoe, we have a brand and we have a size.
[00:07:06] So let's get those first, brand and see if everything works and size. It cannot read property brand of undefined, we're up with that.
>> Scott Moss: Where is that brand? Let me get rid of this filter sorry, that was killing us that was another example
>> Scott Moss: Expected value of type, sheet type, but receive, man, I forgot the other types here.
[00:07:31] Sheet type Nike, and I guess I'll add Timberland up there.
>> Scott Moss: Timberland, that command button is so sticky.
>> Scott Moss: There we go and add this email.
>> Scott Moss: There we go, and make sure we don't have any, yeah, okay, cool, that's not required, perfect
>> Scott Moss: There we go, so cool, so now we got a Nike, we got Timberland and we got the common fields, brand and size.
[00:08:09] But let's say I wanna get the sport. So I just typed in sport here, it's not auto completing. So I'm not sure what I'm supposed to do. Well, this is where use this special syntax. You use got ..., use the key word on, and then on the sport or a sneaker.
[00:08:28] I wanna get the sport, and the now I'll get the sport. If it's on a sneaker and then I can say ..., on boot, I wanna get the hasGrip, and I'll get hasGrip. And that's how interfaces work.