Leveraging Interfaces in GraphQL Schema Design - Ryan Kanner - Apollo GraphQL @ NerdWallet

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
all right sweet so we've had some awesome talks already super glad to be here today maybe wrapping things up with my talk leveraging interfaces and graphical schema design a little bit about myself my name is Ryan canner I actually live in Denver Colorado at San Francisco but I am super pumped to be here today not only because it was eight degrees this morning when I woke up to get in my car too but I'm really excited to give this talk as well I am an engineer here at nerd wallet on the content platform team where I work with WordPress and Rock ul and lots of other fun stuff I'm also a co-organizer of the graph QL and WordPress meetups in Denver so if you're ever in town come on by on the side I also helped maintained a peak graph QL which is an open source project bringing graph QL to WordPress in my free time I like to hang out the crazy dog Blake that's way too much energy and I'm here baseball fan Cranky's something else about me I love pizza now I love pizza probably to like an unhealthy amount like it's my favorite food groups type of obsession you know thin crust Sicilian deep-dish you name it if it has cheese sauce and dough on there now as you could probably tell since I'm standing up here in a room of my peers talking about my favorite pizzas I've hit kind of like the pinnacle of software engineering I think at least for my own career I've hit all my goals at this point so that's kind of that's kind of giving me this feeling deep down inside that I'm missing something I'm not using you know my skills to to their full potential that's why I got thinking of what what I really want to do with all my skills and that's why I decided I wanted to be the best damn pizza man in this land now when I start thinking about this dream of mine I think you know I could start small you know couple local pizza shop self-direct and produce a very low-budget commercial airing on public access get one of those logos that like is a magnet sticker under your car definitely dump way too much money into the white pages for advertisement and then once I've gotten to that point think about how can I grow this dream of mine how can i really be the greatest pizza man there is and that's when I started thinking I need to combine what I know with what I love and that's how I plan on getting to the pinnacle of my dream which it which is pizza QL now the best way to scale my business to really get into you know those that Papa John's type of dough my plan is to create a website to open up access to my wonderful pizza to people outside of my local community so I'd start out small comfort with the specials board you know throw up a couple things that you know I really like I love buffalo chicken pizza it's one of my favorites throw that up there so other people can enjoy this as well so then I start thinking well how do I build this how do I start modeling this data what I have now is it's pretty simple it's pretty easy right I have a pizza Pizza has some attributes you know all Pizza has sauce all Pizza has cheese and toppings and then I can write my query and return an array of pizza types boom I'm done easy to do right you can see how all of these fields map I now have a graphical model representing what my UI should look like but now things get a little more complicated because I've discovered that I make the best garlic knots that anyone has ever had so naturally I decided this needs to be on my homepage I need to start pushing these garlic knots people need to know about these garlic knots but hold on this creates a problem for me see there's the garlic knots are not pizza right there's no toppings that there it's a different thing so my model that I had for pizza before it's just not going to work so I need to come up with with a different type entirely to model this data so I come up with two different types I have my pizza type to model all of my data about my wonderful delicious pizzas and then I come up with a side type to model all of my sides now to query all of this data at once the way I plan on doing this is with a graph QL interface that's how I'm going to tie this all together so what our interface is anyway john travolta doesn't know that's for sure an interface is an abstract type that includes a certain set of fields that a type must include to implement that interface right interfaces are not a new concept in software engineering they've been around and very old programming languages and they also show up in graph QL as well the way I like to think about it within graph QL is you know your schema becomes the contract with you between your server and your client saying this is the shape of the data that I'm going to deliver to you mr. client and interfaces within your schema have that same sort of contract but between your types let's say any type that implement this interface also need to have these fields which creates another level of predictability within your graph so as for how this actually works within the graph QL language you have this keyword implements so on any type that you have you can implement a type like so and then it's expected that any fields and the way they're defined on your interface then need to come over to the type itself so if a certain field is supposed to return a string then any type implementing that that that interface needs to have that field returning the type of string now there's still there's still room for you know some self expression for these types because they still want to be their own thing so a pizza can still have toppings and a side can still have quantity so when querying interfaces this is where the power of interfaces really comes to comes to show in the graph QL spec at least I think so so something special about interfaces is that within the spec any any any time you query an interface or a union you have this type name field that you can query as well a lot of tooling within the community relies on this to build cool things like Apollo so this type name will return the name of the type that's actually being queried so because our query returns an interface it can return any type that implements that interface as well so in their specials query we're returning our food item interface and at the top level of that query we can query for any of the top-level fields that are within that interface itself and these fields will be plucked out of the response for any type that implements this interface then we can use these really cool things called inline fragments so fragments are this idea of a tiny piece of your query that is just like in this little box and inline fragments can be used within the larger scope of the query itself so in this instance we have an inline fragment on the pizza type so pizza is one of the types that implement food item so whenever the query response gets a pizza type back it will grab the toppings field out of out of the response from the schema and then the same thing will be done for side as well the way I think about this it's kind of like a switch statement within your query so as the query is executing and I'll say what type is this if it matches one of your in line fragments it will grab the fields for that type now we can look at an example of this here this tool is called graph tool faker if you're interested unless you like mock-up graph you all schema really quickly it's pretty cool so this is the schema we were just looking at so as you can see the response of that we have a couple days okay do you all sides all sides snake guys there we go so we have a mixture of different types so we can return sides and we can also return pizza so we'll grab all of the fields that we need from the interface itself and then we can grab you know toppings if it's a pizza that's returned or we can return quantity if it's a side now if you've used graph QL before and written queries you might used unions it might be thinking unions do this right well yes they do it allows unions allow you to combine two types together so that when you return a union you can query for fields on either one of the types within a union so let's take a look at what that looks like so you'll see the big difference here is that there's no intersection between the types so the way I think about unions is it's just like a kind of like a parent umbrella for your types so there's no intersection it's just showing like what the possible return times for it can be so we can run this and the response is essentially the same it's the same shape we're getting back but again we have to write out every field we want on every single type now in a small example like this it's not such a big deal but when your graph starts growing and you have hundreds of fields on types and have a lot of instances where you have many types of overlapping this can become an issue very very quickly now another important distinction between interfaces and unions is that there's more predictability within unions because a union says you can only return this type this type and this type whatever types you have listed within the union but with an interface it can return any type that implements that interface so as your graph grows that can become problematic because if you don't control both sides of your integration so say your back-end team introduces a new type that implements a certain interface that you're using on your and you're not expecting that data to come through that puts you in a situation where you need to be coding a little more defensively in the client rather than when using unions so it's something to think about and is very dependent on your particular implementation now this is the the difference of unions and interfaces visualize that like this is for me what kind of made me like really understand the difference where interfaces have this overlap between types where our common fields between them can be queried on the interface itself whereas unions are just separate standalone types that are just held together by this umbrella now let's look at something a little more complex because when you start growing your graph and your implementations things start getting more complicated very quickly so the world knows about my world famous garlic knots at this point they know they're amazing the thing that's really started I can't just start to catch on is my pizza QL t-shirt that I've been pumping on Twitter so I decided this needs to go on the special boards I need to move this t-shirt the problem is t-shirts are not garlic nuts and they are not pizza unfortunately so we end up in this place where we now have three bespoke types that we're trying to return on the specials board I think to myself oh my god how am I going to do this I figured out two types I got over that barrier I related everything together but now I have these three bespoke types that are like kind of similar and also kind of not so I end up in this place where I start looking at what what overlaps between these three things so when I start looking at it I see everything has an ID everything has a name an image and a price okay that's some common fields I can work with that then they also see well everything that I sell that's like a food thing has sauce and cheese so the way I'm going to handle this is by using multiple interfaces so in graphic you know schema design you can actually implement multiple interfaces on to a type itself the way that works is by separating them with an ampersand so in this case we have the pizza and side type and both of them implement the food item and product interface so what this means is that each of them inherit the fields from both of those interfaces so in this instance they get sauce and cheese from food item and then they will get ID name price image from products and then we also have the third type apparel that also gets those fields as well and all of these types can continue on being their own types and having their own fields obviously in this example they have one but that's mostly so code can fit on the screen rather than any other good reason now what we could do with our query is really really freaking cool and in my opinion I get jazzed about it is that we can we can query interfaces inside of interfaces so we're making exhibit proud here so so where we're gonna start on this our specials query has changed so now it's going to return the product type or the excuse me the product interface which again is the interface that is shared across all three of our types so on there we can query for the common fields ID name and price then we can also query for fields on the food item interface so we can query once for things like sauce and cheese for our two types that implement this interface because graph QL is a strongly typed language and it always knows the type that's being returned it can then figure out that okay I know that the pizza type is being returned here this type implements the food item interface so I look for this inline fragment and then I query for those fields then we have our inline fragments to get the you know individual fields off of the individual types that are unique to them and we have all of our data and one beautiful magnificent amazing query now what this kind of looks and feels like too much let's see so now we can let's see if we can get everything nope roll the dice it's just like randomly returns types so it's like kind of a crapshoot trying to get off this one did it okay so in this response we get we get an object back that's the apparel type you get one back that's a side and one that's a pizza so within the single query we can query things across our graph all at once and we can have all of these all of these fields that we need to query in a nice like tightly coupled package which is really nice when you get into component development so when we start looking at the component mappings for this of you know when we start building the front-end how are we going to parse this all out in a way that makes sense we can start right we have a product card pretty standard thing our high-level kind of component and in that component we're going to have a fragment so this is the other kind of fragment and I was talking about earlier inline fragments are used in line with your query standalone fragments can become reusable chunks of a query so we have a fragment on our product interface and there we can query all the fields we need within the product interface next within a lower level type we can query for all the fields we need on the on the the food item interface so that becomes this food fields fragment that will then get hoisted up to the main query and same thing goes for apparel fields we can have a payroll details component that has this query trunk very very tightly coupled so the important thing the thing that that interfaces really empowers here is it lets you forget about like distinct types within your type system and lets you think more about like what like what data do I need to hydrate this component like these these particular product cards like I could start selling mattresses tomorrow and like still want them to show up this way and a mattress is still gonna have a sale price an ID a picture and all these things so by querying my interfaces I can start scaling that super easily and then when I tightly coupled my fragments with my components they're really caring about the raw data that they're getting not so much about like the properties on this very specific thing but a component will be like well I need a URL and alt and image width to render an image I don't care what type it's coming from as long as it implements this interface I know that it will have these fields because of the strongly type system that graph QL has now a little fun thing we've talked a lot about you know how to make this easy to do in graph QL I like to kind of put this into perspective especially when I've been working with graphical for quite a quite a long time when I start thinking about well like how would I do this with rest and like you're back to this or you're like well I gotta hit all these three different end points go return a whole bunch of data that I don't really need and they're gonna be in like totally different shapes and when you start looking at this versus the power of something like this it very quickly starts to feel like you're in the dark ages again okay so some takeaways interfaces help bring your types together and they make your graph more flexible the thing to remember is that while you implement all of this you can still use everything like the exact same way you were so every step of this process I walked through where I was like okay we're gonna query for only pizza types or a tournament ray of them implementing interfaces doing all of this stuff I showed you you can still do step one so if there's another piece of your application where you only need pizzas then you can only request pizzas and get your pizzas back also makes your components more reusable again when you start thinking about the data you need to hydrate them and stop worrying if what this thing actually is you can then start turning out things way quicker because your components will be more reusable using multiple interfaces is like one of my favorite cool little like craft QL schema design trick I highly recommend you start messing around with it I think they unlock really really powerful query combinations I think to remember is the trade-off of using interfaces understanding that you may need to code a little more defensively in your client so I encourage you to think about your implementation long and hard think about if that's the right decision for your product and finally pizza QL for life thank you so much if anyone has any questions feel free to ask otherwise I'll be hanging around come talk to me yeah yes can you give more detail on coding defensively on the client when you're using interfaces sorry when using interfaces you mentioned coding defensively on the client can you know into perfect yes I think so coding defensively on the client I think is very important especially when you start doing things like this because as you introduce more things into your schema you'll you know start introducing new types and they will implement the same interface that's being used in the query somewhere in your client so within your schema you could have a query that returns a particular interface and a client could be like okay great I need these three types that are all bound by this one interface that's what I want for this very specific component I want these three things cool so that right there queried they're getting those things back and then all of a sudden if you don't control both sides of your integration some we could say okay I'm going to introduce this new type that also should implement this interface then they do that and then all of a sudden the client is getting this new type that they didn't expect so it will start showing up in their query in a place where they're not expecting it so that's a big difference between interfaces and unions where unions is you will get these types and nothing else it's very specific whereas interfaces are a lot more open where they say anything that implements this can be returned yep how would typescript play into that as a follow up I have no idea because I'm mostly right in the u.s. oh my god gotta like pull out my notebook question there so yeah piece of ql is number one come on good catch yeah I'm not I mean it's like my hometown like spot that like no one's ever heard of that's like to super small and like everyone's mean to you like that's my spot you know like yeah for Telly's yeah I mean like you could google it you probably I don't think they have they're probably still in the white pages at this point they they have not risen to the level of a success that pizza QL it's gotten to because they haven't harness the power of graph QL so anyone else I have a question I was wondering about and I think I kind of garnered this a bit from your clarification but I wanted to also circle back is there a cost to retro actively introducing interfaces into types that already exist No so that's the other cool thing right like you can get to this point start growing your graph just you know get things up there start spinning out types and then you can get to a point where it's like okay okay okay let's take a step back see what we have look at like what is overlapping like what are the similarities here what makes sense to start codifying this into a single interface that you can unlock stuff like this so I think if you are at that point where you're like more greenfield and you're like let's let's get this going get up and running like go for it don't you know stop and like try and make all these big decisions and like plan out ten you know miles ahead when you're like on step two so introducing them after the fact I think is actually it's probably a very good way to go about it because you have a better idea of like where where is your graph at and like where are those intersections between your types what are those triangular things on your shirt there there are these pretty awesome things they're slices of pizza which I had this already and like I actually like this did not inspire the talk at all it was like I was in the middle of writing this I'm just like I think I have something for this and I did which was pretty cool yeah cool yeah what he said that awesome thanks guys you
Info
Channel: NerdWallet Engineering
Views: 605
Rating: undefined out of 5
Keywords: apollo graphql, graphql, react, javascript
Id: 4du-oX1M0AI
Channel Id: undefined
Length: 26min 32sec (1592 seconds)
Published: Wed Mar 04 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.