 Good morning, I'm gonna start talking because I have a lot to talk about so please find a seat come up here Sit down seriously and come up. We can have like a campfire type deal. Just please come sit. Don't stand I'm gonna be talking a lot. I'm gonna get rolling here. We go. We're in the graph QL way talk You're also Let's see if this works. Oh, hey, but here we go. I got to work My phone works you have to reconsider the basics track at Royalscom 2018 That's the last keynote animation. I'll subject everyone to I'm sorry. I don't have a lot of gifts in my talk this year, but I do have these really cute animals So you're gonna have to deal with me Can I take now if I take this mic off will be a problem my audio crew? Yeah, can I have that? Hey, hey, thank you. I appreciate that. Okay. My name is Qrush I'm Nick Caronto You can find me on the internet at Qrush on Twitter I used to have that Instagram account and then I deleted my account out of rage and Russian guys stole it So don't don't delete your Instagram account is the real lesson I have for you today If you want to get get at me there or come up to me. I have the blazer on You might know me from making what is now called ruby gems org or a gem cutter I've talked a lot about that in the past not talking about that today, but happy to if you have gem problems I'll help you out What I do now is I work for a company called chatterbug. We're a language learning company at space in San Francisco and Berlin started by a few of the github co-founders and now we have a dozen people or so and we're trying to teach languages and I want to talk about this just a little this is not a Sales pitch, but I had to talk about it because it it will they paid for me and they also are It's gonna help frame the problems that we're about to talk about Currently we teach to English speakers three languages German and then very soon Spanish and French and we have our cute little Student bear on top and our tutor bear on our tutor owl on the bottom. Hopefully by the end of the year we're gonna have kind of a Marketplace type model where you skip too far Where we you could teach a language just by being a native speaker of English or French or whatever you know and then you could learn another language. That's kind of where we're going The cool thing about our platform is that if you ever use like a language learning app You don't really get to speak it. So what we did is we kind of combined those like kind of memorization Type apps with live lessons So you actually have an in-person 45 minute session with another human being a real human being and you talk in a different language and It is a really fun experience. I've done maybe 30 of them in both Spanish and in German and it is hard I took Spanish in high school and this is like there's a whole no level You get to really really learn and this is all done from a tech side. We are on rails uses web RTC We actually use action cable. We do like a cool little screen sharing and a chat thing. So we're all about it It's a lot of fun One of the things we wanted to do in the past year. So was have a mobile app This is really important if you're on the run You just want to look at some words to figure out to or prepare for your next live lesson we needed a mobile app for that and we were kind of looking at the state of API's because we needed to start one from scratch We had some API's but we really wanted to look at it and we decided to look at graph QL And I'm going to talk about what graph QL is today and a bunch of other Things that we ran into so if you don't know anything about graph QL You're gonna get a great introduction and the next 30 minutes or so There's also a workshop tomorrow. I forget the exact time, but it's in your schedule So if you really want to dig in I would suggest signing up for that But you're gonna get a good intro for both and thank you to the organizers So to moving stuff around so you could attend both I'm gonna show you how you can use it in your app with some examples of how we did and Then I'm gonna talk about some potential pitfalls that we ran into and are still into pitfalls I'm digging ourselves out of that's kind of the plan Okay, so Back to the problem. So the problem is I have a mobile app I need to have it talk to my server our server in as far as rails goes Just to set the context furthers very vanilla We use rails 5.1 we use some webpack and some react webpack is great by the way And react just like any app that's existed for any amount of time It's not all in react and we have some Jason Jason is kind of as we just heard is the kind of the lingua franca. It's a terrible language pun Wow And we use a lot of Jason we have a lot of Jason API is something that I think rails does very well You want to get started with the Jason end point? You want to get some stuff on your page dynamically? It's great I really like Jason. I'm about to really talk about why Jason's not good So I want to make it really clear that I like Jason. It's a great format I think a lot of if you've ever written and how to maintain an API that spits out Jason A lot of the problems aren't really with Jason itself. It's actually with rest This is funny if you're listening to Dave's keynote because we were talking about how rest is a great thing that rails did However, there's a lot of problems with rest if you're writing an API and those problems have kind of stacked up And this is a small smattering of them There's always kind of an end end point explosion You have a lot of HTTP endpoints to maintain and worry about and your users must understand and you must support them Especially if someone is using it Roundtrips get really expensive So if I'm my network is really crappy and I'm trying to do a lot of fetches and requests that makes your app experience worse That means that you think your app is slower because it's grabbing all that data down And it might be actually expensive for your user to with data Discoverability is low and I think this goes into like it's hard to discover about what the API does But I think this speaks more to the developer experience is not as ideal as it possibly could be and certainly backwards compatibility Is not even thought about I've given talks about okay We have to have an API v1 controller or we need to or of course every API has a different way of dealing with versions This one talks with a user agent This one has an HEP endpoint none of that is built in with rails None of that is built in with Jason API is something you have to learn each and every time over and over again So these problems all kind of stacked up and it leads to unhappiness It's something that I was as I was looking at it and this might be a problem that you've had is like okay Am I gonna deal with all this again? And the answer is hopefully not so let's talk about graphql I find myself to be a bit of a Software historian So I want to talk about the history of graphql But I feel that others in the especially JavaScript community have done a better job of it So I'm gonna talk about just what matters to us in this room right now The big point is it started by Facebook in 2012 to implement their newsfeed and it's kind of grown internally at Facebook from there In 2015 they open sourced it There's a fantastic documentation site for graphql and its JavaScript libraries and there's other languages that have implemented it such as Ruby and in 2016 so the graphql Ruby driver has been around for two years ish and This is all the history that matters for right now If you need to go to your boss and be like hey, I heard about this cool API thing What other companies are using it if you don't want to talk about Facebook because well, they're not the best example right now I Don't know why I meant to mention that we have an amazing illustrator at chatterbug his name is Elvis Ferreri and he's an I'm probably mispronouncing his name because he's French and I don't know why he picked a Russian bear, but I really love it Couldn't find an octocat either so my floating pizza-holding Octopus with a the fedora honored who knows what that hat is so get hubs using it for their new API and Shopify Which of course is a Canadian beaver I? Love of the illustrations Shopify uses it as well So I would use if you don't want to use the well the the company that's been Testimap having to deal with Congress and testifying or the scrappy startup you can be hey Here's these other companies that are using it as well Just in general use cases. I think GraphQL really fits in well if you're doing a mobile app if you're starting one from scratch react native is really nice and There's this really great npm package called Apollo that talks really well with GraphQL Same deal with if you're just doing a single page app Also, I think in general to be that person Anywhere a JSON API could be used you could use GraphQL You may not want to though, especially with how great Rails makes JSON APIs do now You could go full full in and do it all from scratch But I just want to and you you can but I would say you probably don't I think the top two are really where it's best What is GraphQL? I wanted to do this really early and of course it's been nine minutes But I keep talking. What is GraphQL? GraphQL is a query language. That means you build things like this This is the query that you will build to ask your Server information so your client on your phone or on your web page will build this thing Submit it to your server and get back information I'm gonna dig in to what this is but basically in GraphQL parlance I'm asking for a query it has a current user field and that's got a bunch of fields underneath it It's got ID login all the junk I might need to show a dashboard Maybe am I a student or not is it updated or not and then underneath I'm gonna have JSON So we're we're in home turf here. This is JSON The real thing that's different is that query language and that's the thing that you're building Of course, there's a lot of semantics and a lot of cool things that are tucked into it And we're gonna talk about a little bit But under the hood you won't need to deal with this if you're using a GraphQL client They're gonna parse all this and give it back to you the way that you need it And I just wanted to show that this is just JSON. This is not some new format. That's invented It is a new way of asking for data, but it's not like a completely brand-new thing under the hood. It's all JSON All right some basics We've talked about a lot of basics But let's go into it like I said, it's still JSON This is great because we're used to JSON with Rails This is the probably the most important thing is that it's strongly typed This means that all the input and the output are You have to have a type for them and if you've dealt with okay Is this thing coming into my controller a Boolean? No, this jerk sent me a number And then you have to parse it and deal with it or dates especially are terrible in this way Any kind of string formats GraphQL handles all of that for you it really enforces types And I think is Rubius we know we like to say everything's an object won't GraphQL everything has a type And I think that really jobs well One of the great things about GraphQL is that it's changed resilient So I think this matters a lot because if you're maintaining an API over time you will get changes to it You have to say okay now I have a new requirement I have to add this new thing in and like it's kind of a pain to talk to your all the people using it and to make your Clients adapt and GraphQL is thought about how this What the story for this is and I think I really appreciate that that from the start it has a way to deal with those changes and You've ever had a lovely discussion with your engineering team about how did how do we do a paging in the API? Do we have like a parameter? Do we do like headers? Like what is what is GitHub to do do we care like stuff like that? You don't need to worry about that either At least for the Ruby side API if you're using Apollo if you're using the Ruby gem Paging is built in that discussion is gone And I think speaking from the Rails point of view of convention or a configuration This is great that your engineering team doesn't have to spend cycles on worrying about how do we get more data? When there's more than we can handle it's done and then if typing is my And the most important thing. I think the introspection built into GraphQL is my favorite thing Everything that you build with GraphQL is inherently Inspectable there's a great little Console that comes with the Ruby gem as well as a separate gem actually But then everything that you get to query and mess around with is Kind of dynamic you get to play with it right in your browser You get to make build those queries and get the responses back You've ever had to build something using curl or a mick or build your own little HCP client Just to test on an API this has it you don't need to write that anymore Okay, so it's a let's keep talking about basics This might look familiar For a request if you ever used I believe any of those W s death star things or something like XMR PC any of these envelope formats This is a pretty common pattern that used to exist pre rails and kind of stills around and we're back to treating requests with GraphQL as Treats HTTP kind of like a dumb tunnel. So this is has its its benefits and its and its drawbacks The big benefit is that it's pretty simple to talk about That query that we wrote is gets posted to your server and then it returns JSON That's how it is for everything with GraphQL Obviously, this is not rest That's something I want to be very clear about it. This is not rest anymore This is treating HTTP just as a way to get data in and out Everything else we have the query language to describe So that's something that is kind of jarring for me for especially I think it's jarring for others as well that may be used to how rails works is that we're not in that land anymore But the nice thing is that we solve a lot of those problems that we talked about by implementing something different So this is something we're not really we're reconsidering the basics So this is a lot to reconsider and I want to be very clear about this that this is we kind of lose They're like really nice HTTP semantics, and I actually think that's a downside the fact that we can't use get Requests the way that they should be used as I think a big drawback, and I hope that changes honestly So that's how GraphQL requests happen you build that query gets posted it comes back All right, let's talk about types. What do types look like? I love this bear too. I actually this is a raccoon Fun story about this We are German mascot a chatterbug, which I have stickers by the way you can come up and grab them But he's a he's a raccoon which is actually not Not native to Germany And I suggested like let's make him a squirrel like it'd be so easy We just add a tail or like a different thing it'll be really easy, and they're like no no no He's a he's a raccoon immigrant to Germany, and we're like okay. I can't argue with that So anyway, that's auto. I don't know why he's so mischief why he's trying to sell you different badges, but Okay, so types types are key to GraphQL This means that all input and output must be a type that me when I ask for data as a type when I get data back as a type The cool thing about this is that there's no more validation So if you've had to write validations that you have to shove the input or output into the certain way GraphQL handles that and I really really like that Every app is gonna have a mix of these three types And these are from the Ruby parlance. So I'm saying When I ask for data, so the equivalent of a get request. I'm getting a query type When I ask for a change the data, so it'd be posts puts deletes that's my mutation type and Arguments are strongly typed as well. So we'll see an example of this when I ask for data to be changed I pass along a type that is strongly typed with those arguments. So this takes the place of Strong parameters, which is really cool So actually all the stuff that's in your input object types are the only things that are allowed Into the mutation so that we don't even need strong parameters here because the query language that we're requesting data with enforces it so that's kind of cool Our app for example, we have this is super simple example But you most likely might have one if you start using GraphQL. We have a user type That's a query type we can ask for we have an update user mutation type Which is a mutation type and that takes as an argument a user input type. So these are just simple examples You'll see we have a few dozen types by now and your app will have a bunch. They're kind of like the the models so to speak I mentioned that GraphQL is inspectable and It comes with a tool called graph IQL Which I really think will change the way you write APIs because it's changed the way I have in everyone on my team has Basically, I know this is hard to read you get free API docs Not only do you get the console where you get to write the queries and then run them and it keeps a history and it has a nice little way to nice it has a nice little way of Sure of like making your code pretty so you can paste it and complain why coat why query is not working But it also comes with documentation So when you're writing your GraphQL types side-by-side with that is the documentation That is shown to your users on your team and you could put this publicly I'm trying to figure that out how we can do that without Letting someone get access to all the other data But at least for your team internally This is a huge huge leg up if you've ever had to deal with okay How do we communicate all these changes inside the team for different quit for different endpoints? We've got it solved. We've got a way to deal with that I can't express enough that like GraphQL is really really nice If you've ever dealt with an API like stripes got a really good one There's a lot of different APIs that give you this kind of playground sandbox and you get it for free Okay, I talked about changes GraphQL deals well with changes This means you won't have to version your API anymore Which is cool You could have a v1 API endpoint for a GraphQL, but chances are you won't need a v2 Instead the the saying you'll hear in a lot of the docs is that you'll extend with graphs So what does that mean? Let's say I've got a new data model. I can on my phone now Okay, I've logged in I show my dashboard, but how do I show my upcoming live lessons? Well, I can start plugging in new fields right underneath. Obviously. This is very similar to JSON I could just start plugging fields in but the cool thing is that GraphQL gives you The ability to be resilient to change in the opposite direction as well So if that was no longer a way I wanted to ask for appointments I could mark that field as deprecated that shows up in graph IQL and then I can say that have one new way of telling my team Okay, here's how don't use this query use this one instead So it kind of goes in both directions instead of just one direction, which Jason APIs only ever go in one direction Okay, so upcoming appointments and the cool thing too is that we can keep extending you you can kind of nest stuff This is also how we reduce round trips is that you can say okay and inside of the same query I can plug in all the data that I need also inside of this inside of the same GraphQL request because we are Handling it at HTTP as a dumb tunnel. I can say plug in multiple queries Your client can start to get smarter with plugging in queries and mutations and batching up all the stuff It needs at the same time. So this gets I didn't cover all of this with code examples But the the rabbit hole is really deep. They really thought about how to how to make it work. Well So to plug away on this example a little more. So I'm asking for upcoming appointments Maybe that would be in JSON API world another endpoint that I would go fetch And then I also want to show when it starts and if it's like a German or a Spanish lesson and all of that I can just keep plugging away For those of you with the security mindset, you might be saying okay Can't you just like keep nesting things infinitely and then like blow up the parser and the answer is yes But don't do that But you can turn that you can basically say only accept nesting up to a certain level And just like before I wanted to show this off is that Under the hood it's Jason And I think this matters a lot because it's not some other weird data format It's just Jason So if you were running this query in the graph IQ QL inspector you open up the web inspector You would see that query go through and this data come back Okay, so I just talked about all the stuff that graph QL has and I'm at 20 minutes. I'm gonna talk Briefly about this There's no data model in graph QL This is kind of a no-brainer for us in the rails community because you use action controller And it doesn't necessarily mean that you have to use active record, but I think for other communities This matters a lot. So this is there's something that is Kind of needs to be said is that graph QL gives you a way for data to come in and then you write the glue that goes From there to your database or wherever your data layer is It does not have authorization does not have authentication So it does not have a way to say hey let this admin do or do not this certain thing this certain mutation And it certainly does not have a way built in to say okay This user only has access to this stuff and you don't so that's something I'm gonna talk about that more And doesn't have caching and I have good news about that because that kind of stinks We're used to caching just working the way it does with rails and it should work with this too Okay, so to wrap it up with just the basics graph QL way you can evolve your server and your client at the same time especially If you're in a place where you're iterating really fast such as we have been with a mobile app very important You get to introspect it all and this matters a ton compared if you've ever had to do a lot of API work in order to get it all visible it's not easy and One of the cool things is that you get to kind of shape your data And I didn't cover this too much But one of the cool features it has is that you get to kind the client gets some leeway with how the data is requested as well So this is something that if you've written a client you've probably had to do It's like oh this endpoint just comes in a different way and the client gets to have actual say about that with graph QL Which is great. So this is that kind of a classic The previous thing was Legos and this is now Play-Doh. I mean you can kind of accomplish the same things But it's kind of cool. All right using it in our app We have a lot of characters. This is our Spanish character Her name is Maria Dolores de Berriga, I don't know why Anyway, it's a llama and this is our Spanish character So if you want the docs for GraphQL that graphql-ruby.org wonderful wonderful site I want to remind you that we're off the golden path here for rails. There's no controllers There's no views which I'm as nervous as Maria about this That means instead we have the GraphQL DSL. So this means we are provided a DSL By the gem and that's how we write our GraphQL types. I'm going to show you how to do that really fast We install the gem really easily. You also will definitely want the graph Iql rails gem. You don't need it but geez get it and Then there's a generator of course the generator will plug a bunch of stuff in the most important of which the thing you're dealing with the day-to-day basis is the tree and If we look at the GraphQL folder it makes it makes a schema and then a folder for mutations and a folder for types So that's just the place where you can plug in all the ways that you change data and ask for data The schema is kind of your root file the root routes It's the place that by default that says hey, here's my just my basic query type That's gonna have the queries that are accessible and here's my mutations as well You can get more complicated than this the schema has a lot of stuff that the GraphQL site On Facebook that Facebook's GraphQL site has but by default you're gonna get something that looks just like this in your app This is also the place where you plug in instrumentation podium mic. All right, I got some stuck. I'm gonna gesticulate wildly back here. How do we do types? We have a name. We have fields and we have a description. So for example for my language I have it's my language type or my user type. I had different fields such as my user I have a login field an email field Update that and then a description obviously for user and language. That's really simple But for a description, maybe I've got a different model that needs more documentation You can you can get it right there each field has stuff as well. You have a name login is very obvious arguments, which is super cool instead of doing Query parameters on your API each field each individual field can take arguments as well So if you ever wanted like a slice of data in a weird way, but you don't want to provide like a query string to it You just want this one individual thing. You can do that now It has a resolver And this is just it's like a resolve function. I'm gonna show off what that is But this is the place where you will actually write the code that connects GraphQL to your app and then a description and this makes perfect sense for Name and login email those kind of fields that make sense, but for something like upcoming appointments You might want to say like oh, this is all the appointments 20 in the next 24 hours, and then that would show up on graph Iql and from there What does it look like? So let's look at a super simple query Here's a query for the German language and its name. I don't know why I'm asking for this just here we go From the Ruby side, it's gonna look like this. We have a field that's called German language I'm asking for a strong type back called language type and then I have a resolve function With three arguments the object coming in any arguments, which both of those are nothing Right now and a context a context is kind of the global object. That's given to all resolve functions So instead of controllers instead of views. This is what you get you get the DSL The deep inside of the result function you can write any of the code that you need such as in our case We're gonna look up with active record and find the language of the code of DE now from there You're saying okay. How do I get a language type and the graph ql gem? Has a bunch of metaprogramming stuff that figures out how to connect the two you don't need to worry about it instead You just write a language type which says okay I'm gonna take a language and I'm gonna say I have a field name on it That is a string and here's my description of it and I might have other fields I could have other fields in here with resolve functions You can have really whatever you would like inside of this graphql type by default It's gonna map properties that are the same name So if I give it an active record object with name and it's I've got a type with the name. It's gonna find it great Let's look at a mutation fast mutations This is an example of the GraphQL language. So I'm going instead of query. I asked for mutation It takes update user and this looks kind of JSON ish So I'm saying my user has a time zone of UTC And it's kind of that's how arguments are done. It's kind of a Perends inside of a field and then it returns a type as well So typically with the JSON API we would see like okay returning true or returning a created response or accept or 200 Okay, and with GraphQL you're returning a type. This is not we're not in normal rest world You can return the type that you just did and then your client can react appropriately such as hey I can say that I updated my type To UTC now or whatever or I keep a log The cool thing this is kind of where I'm getting to the shape of data as well Is that your client may not need every single field from your user type when doing an action such as this? So you only have to get the stuff that you want back That is relevant to this API request, which is super cool in JSON world We'd have to just return the whole thing and then well you do you just kind of discard the rest of it Mutations have a little DSL as well, so we can say okay. Let's have an update user field It returns user type it takes an argument of a user input type, and then here's our friendly resolve function Inside of our resolve function. We look up the global Context for the user and then we call update attributes bang Now that the security minded folks might be saying okay Where am I validating my input and that is happening in the user input type So I can say just exactly what I am allowed to have changes with with the arc with my user input type So if that just has I think just for us It's like time zone and like one or two other things So if there's no possibility of something happening where it's like, okay Could I promote myself to an admin in this way? Could I change my password digest field or some weird stuff because that's simply not in the user input type If it's not in that input type it won't parse It's not a valid query rejected all that stuff is written for you your strong parameters is a thing of the past in GraphQL like I said Authentication is good. I know I'm at 30 minutes. I'm gonna keep going Authentication is not built-in Instead you can force it via the controller and I would highly recommend doing this in your app And you pass a current user So don't do this at the GraphQL level at that resolve function level do this at the controller level when you run the generator It will give you the All the tools you need with rails to do it such as this it looks just like this You'll have an API GraphQL controller You can say hey Let me find the current user from my HTTP token or whatever your OAuth basic auth Setup is for your API and then I can call whatever HTTP rails whatever authentication system you need don't do this inside of GraphQL. It'll be a mess same deal with authorization there's nothing built in but the GraphQL Ruby maintainer has a Pro version of the gem which you can pay him and then you will get access to those features Which I think is a great business model or there's other gems for garden pundit and you could do this yourself if you need to I wanted to talk briefly about testing Integration tests are super hard With GraphQL, but not impossible I would really recommend that you test custom logic. So that means the stuff that's just inside of your resolve functions And then treat the types treat the types that they map to the right thing that they get parsed in the right way Treat that like framework code. It's not the best idea with rails to test a belongs to works or test Hey, my post model has many comments. That's not super worth it But I think in here we want to test the same deal We can trust that the types do what they are built to do and then we can test the stuff inside of resolve functions And especially mutations Mutations actually can be taken out into completely separate classes Which I think is a great little object-oriented design pattern That's inside of the GraphQL Ruby library if you notice our call function for this GraphQL Function has the exact same arguments as a resolve function. So this call Takes input args context same three things that means this class can be can be instantiated outside of the world of GraphQL for example in a simple test case I could say hey, can I make sure I change the info I need I? Fire up just that function not all of the framework around GraphQL and then make sure I test the thing that you need So anything that takes arguments anything that takes a mutation. This is a super good pattern You can integration test as well So if you've written integration tests with other APIs, this is how you could do it here I just wanted to briefly show that it is possible I don't think the code is as important here But you can say hey just testing simple things especially in a great integration with your Authentication system is very important You can also say hey Let me pass in headers. So just this is a standard Rails integration test This is honestly the only integration tests. I have I mostly have unit tests for specific functions Okay Back on track. Let's talk about some potential pitfalls This is Jean. I think she's our French mascot. She's very French One of the things that we kind of ran into early and you will as well is that there's nothing built-in to handle errors in GraphQL And this is bewildering to me. I don't know why It's like this But if you want to have let's say you submit something something went wrong even a 500 requests or for our 400 type deal There's not a built-in way to do that. I don't know why but you will want this gem Which gives you a rescue from block. So if something in your code throws a Active record not valid error or a not found if you pass the wrong ID That will kind of blow up unless if you have this gem. So this is a super good gem to get This is one of the things just like the HTTP semantics that I wish would change soon Like I said, she's very French Something to keep in mind is that resolve functions are not sequential Since we have these functions one of the cool things built into the API is that you kind of get to load them Asynchronously, this is really cool because it lets you do different things with your API But the problem is that M plus ones are real. We are back in the land of dealing with performance problems Luckily Shopify our Canadian friends have built a GraphQL dash batch gem Which allows you to batch up several resolve functions and run them as one thing This also is based on the Facebook data loader NPM package which does the exact same pattern It's that I'm going to take a bunch of things in our case baguettes that might have common IDs You may have dealt with this problem at your work and hey, I've got repeats here. Okay This is super slow to ask for eight separate things. How about I do one giant baguette instead? So this gem does that as a pattern and one of the things that I was finding was that it's It has a lot of great patterns wrapped up in that read me and in various like gist and stuff So I put them in one gem So this is something I'm gonna release today. I didn't I was too busy listening to the last talk all the goodies that I'm about to talk about are gonna be in a gem called cash QL and That'll be released very very soon. I once I get some internet access So yay, this is progressing this gem has four things, which is pretty cool The first thing is it has these loaders Which are the batch loaders provided by Shopify and some other companies wrote them as well That lets you do Solve common performance problems such as foreign keys. Let's say I've got an object that belongs to a language Well, if I have a resolve function that asks that does a single query It's gonna build up to an n plus one So this let's it has a record loader that does just foreign keys It has another one for polymorphic keys if you have a lot of polymorphic keys in your app Which they're everywhere. There's another one for associations as well, which is great so this is a great way if once you're Deep in the graph QL and you're starting to figure out. Okay. What's going on performance wise? Why are these things slow? Batching is the way to go it took me too long to figure that out Caching let's talk about caching briefly too far We're not in HGP rest land sadly So that means stuff like HGP e-tags is out the window and this is I'm not happy about I feel like those semantics are awesome and I feel like probably get should be supported This is something I would love to see change from the graph QL level. So what do we have instead? We have good old rails that cash, which if you're using rails 5.2, which just got released last week There's redis as well. So hopefully you've got redis or memcash hooked up to your app You can cash all sorts of stuff great Well, how do we do with that or what do we do with it? Well? We want to store the results of the of the resolve functions and Let's say you've got a slow resolve function. I need to stick it in a cache somewhere I've got you you can just stick cash QL in front of the resolve function lambda and then you're good And it will cash that expensive operation Based on object that cash key and I think there's an expiration time that you can configure as well So this is great. This is kind of just like our Cash in active action view and that you can say okay now. I've got a cached Function perfect and you'll be able to watch your stuff get faster. So this is the second thing that's in that cash QL gem There's two other things that are related to instrumentation This is something that you'll have to do This is a very common pitfall is that you have to say I've got slow stuff. How do I figure out? What's slow and how to make it faster? Also, I love that we had an illustration of a graph. I don't know why we were teaching graphs, but I love it Apollo engine is kind of the community standard for this This is a separate company that does application metrics And it there is a Ruby gem as well that you can plug in and it gives you a development proxy That will proxy requests through it that I have not run on production yet. So oh no there we go The thing that we use in production is Scout APM, which is a competitor to a new relic I'm sorry if there's new relic folks in the audience and I wrote an implementation for instrumenter for Scout and My gem includes a rails.logger Instrumenter as well. So what are those two look like? Scout if you scout and this is hard to read but in the middle it break it if you use the Instrumenter that's in the cache QL gem. It will start breaking out graph QL resolve functions into their own Block for you to analyze inside of Scout and this is super useful It's kind of take peeling back the covers and figuring out what is going on inside of my request and what which resolve functions are slow You can figure that out now, which is super cool So that's the third thing the fourth thing is that if you don't want to use any of that if you don't want to use Apollo Engine you don't want to use Scout yet. You can't convince your boss to install it which possible We have a rails.logger Instrumenter for you which uses active support notifications You basically just hook it up and then you start getting logs on your graph QL requests So this is great. You can jump back and forth between okay. I'm gonna run this request in graph IQL That might be slow and then pop right to your rails log and look at how slow things are and then hopefully maybe add some caching in Do whatever you need to a batching figure out how to make it faster So this is a super common thing and now we have a way to tackle it So let's sum up is this the new way for JSON APIs in rails and There's this law with headlines where if there's a question at the end of the the headline the answer is probably no So I'm gonna let the reader decide I think this is gonna be really hard for you for graph QL If your app logic is super coupled I want to talk about this more but I kind of cut it for time I think that if you don't have clear defined layers between how you present HTML and JSON as they are and Your apps logic if you don't have some middle presenter data serve whatever you want to call it If you don't have that middle layer you're gonna have a really hard time with graph QL If it's if it's an existing rails project So you really need to consider how your apps are protected and if it can handle adding a whole slew of new semantics to it I think for fresh apps though This is a great solution and especially for new APIs if you're trying to look for a new API That's gonna really be around for a while. I think that this is a safe bet now We have larger companies that are using it It's shown that changes are very easy impossible and it gives a great developer experience and especially for fresh apps the integration with Apollo and if you're using react native or even if you're not if you're just doing this And in browser app. It's really really really nice. That's all I've got. Thank you