 Good morning everyone. My name is Jeremy Ward. Let me get started here. I've been building things for the internet as a hobby since about 2005. In 2008, my hobby became my career, transitioned from a career in athletic training and strength conditioning to a front-end developer, a small part due to a hobby app that I had called My Fair Ex at the time. It has served me well. It will actually serve as the live demo for this presentation, actually a later iteration of it called Fit or Me. About the same time in 2008, I started dabbling in Ruby on Rails over time, over maybe about five years, eventually transitioned to the dark side or the server side of the software development world and I've been doing that ever since. I'm currently a software engineer three on the FishMe team at CoFence. FishMe was recently acquired by CoFence, so now the simulator product, which sends out simulated phishing emails on the corporate level, is now known as FishMe. I'm here today to talk to you about GraphQL. We've recently made the decision to start using GraphQL for some of our funded projects and microservices and would like to share a little bit about that. In this talk, we'll compare our existing API standard, REST, which has served us very, very well, to GraphQL. I'll introduce you to some of the basics of GraphQL and we'll show you how GraphQL looks and how it feels in a Rails application. We'll discuss how to start using GraphQL in your applications and toward the end, we'll talk about what we're doing on the FishMe team and how we plan on using GraphQL moving forward. So REST, our current standard, it's served us very well like a dark night on the wall. Anyone remember the dark days of chaotic wild APIs and soap? So for the better part of two decades, REST has done us very, very well. In essence, REST can be distilled into four virtues. So Uniform Interface, it's stateless, it has a clear separation between the client and the server, and it's cashable. So as Uniform Interface, what this basically means is that we always use HTTP verbs, get, put, post, delete. You know them all well. We don't always use them correctly, but they're there. We always use your rise as our resources and we always get an HTTP response and status or HTTP response status and a body back as a response. Stateless, each request is self-descriptive and it has enough context for the server to actually perform whatever it's supposed to do. Pretty self-explanatory. Client server separation. There's clear boundaries, as it says. So basically there's a contract. One entity has to serve the function or it has to be the entity that's doing the calling. The other being the client, has to function as the entity making the requests and it's cashable. Unless noted otherwise, a client can cash any representation. This is possible thanks to the statelessness of the REST request. Every representation is very self-descriptive. But along with REST, and though it has served us very well, there's some pain points that we see more growing points than pain points. REST is rigid, as we already talked about. There's five resources that we'll generally use, using the different HTTP verbs. So we're going to use get request for index, post request for create, another get request for show, patch update for updating and delete. This is great, but it kind of ties us to a structure and there's a lot of boilerplate with this. Which brings us to why REST is rigid. Lots of boilerplate. While not exceedingly difficult, specifying all the URLs, all the routes, it becomes, then you have all the controllers. It becomes tedious and time-intensive, just monotonous boilerplate work. All while we're making the assumptions that the data the client interface actually needs, and they might not even use it. And you know what happens when we start making assumptions. So what we end up with is if we have to make a change in the design to our API, at best it's a simple internal code update. If it's a public-facing API, how many people in here work on public-facing APIs? A good chunk of us. If we had to make a public-facing change, it's probably going to require a new version bump of our API. That gets expensive pretty fast. In many cases, our server-side code is the most rigid part of our system and it's considerably more difficult to change. This leads to a situation where we tend to implement our clients around the needs of our servers. And if you think about it, who should we put first in any of our projects? The end-user, the client. So putting the server first, putting the server's needs above the client, that's really bass-accords. Ideally the server should exist to serve the client. It's in the name, right? So it needs to be responsive to the changing requirements of the client. We all have product owners. Anybody get a new request last week? Yeah, it happens all the time. So requests come down. We need to be able to respond to those requests very quickly. Rest is wasteful. Wasteful's probably a little bit of a harsh term. But sometimes it gives us too little and we have to ask for more. That's under-fetching. Sometimes it gives us too much and it's over-fetching and we're left with a pile of data that we really didn't ask for and need or we really don't need to use. Both are less than desirable, especially from a mobile device that may have limited network connection. So classic case of under-fetching. We have two rest requests. This is a simple blog post. We have the posts and we have the comments. For whatever reason, the request comes down and we need to display all the posts and all the comments. Don't ask me why. It just came down from the product owner. And so now we have to make another HTTP request to get a post's comments for how we're displaying that on the page. So we're making, essentially, N plus one HTTP request on the client side. Not exactly the best-case scenario. A real-life example of this can be highlighted with putting a toddler to bed. Anyone ever have to do that? I have a three-year-old son at home. He just turned three. And the bedtime process is exactly that. It's a process. So I'll put him to bed and, you know, start to walk out and close the door. Daddy, daddy! I'm thirsty. So I go out. He tells me that he wants milk. He gets milk. Trying to leave again. Daddy, daddy, I need my green blankie. Go out, get my green blankie. You see where this is going? Daddy, daddy, I need my teddy bear. And on it goes. Lots of requests. So the next night, how do we solve that? That's a question. So how do we solve this problem for our product owners? And how do I, as a parent, solve it for my son? We over-fetch. Simple way to do it, get into the post and give him back everything. Here it all list. So the next night, I put my son to bed. And I'm thinking that I have him beat. So I bring in the milk. I bring in the blankets. I bring in the teddy bear. I bring in a flask of Toulouse-Merdu. Clearly, there's a authorization problem with my parenting endpoint here. But fear not, if he tries to access Toulouse-Merdu, I'm sure that he will get an access denied. So over-fetching. So that's a problem. So how do we, what do we have left to do? This is obviously a problem. Well, a friend of mine offered a parenting advice. Clearly, he doesn't have kids. Gives me a book. Not exactly helpful, but you know all solutions are on the table. So, well, funny, it's slightly less helpful for our blog. So we might do something like this, where we come up with a custom endpoint. Anyone have any custom endpoints in their application that you know, it's kind of a specialized endpoint for a more generic concept. Yeah, this is how we kind of solve these. We come up with a custom endpoint. So now the clients that need the posts and the comments, they can hit this endpoint. This is this is interesting for our REST application, because now we're kind of breaking our REST contracts. And as Nietzsche said, that will not with monsters, unless you become a monster yourself. So our defender of the wild and chaotic APIs on the wall has now stared into the abyss and the abyss has stared back and now he's becoming what, what it's been protecting us against. So this is basically our APIs are starting to become harder to maintain and we find ourselves loathed to work on it, which is undesirable all around. REST is laborious to document. I probably can just leave it at that slide. We've all struggled with documentation with REST APIs. It's often manual, it's probably going to require a markdown file. Maybe, maybe some JSON files, in the case of Swagger. It's hard to ensure it's up to date. You make an API change. Maybe you update the document, maybe you don't. Anyone come up with a you know, ever run across a case where you try to use an endpoint and it doesn't work as expected. It's especially challenging for fast changing internal APIs. On the FishMe team we've run into this with a microservice where we had an internal, the internal API for the microservice was changing very rapidly and the UI would be continuously broken because we have to readjust things and those things don't necessarily translate to the documentation. But to give a good example of a REST API I would refer you to Stripes API. Anyone had the pleasure of working with Stripe API? Probably one of the best documented and up to date examples that I can come up with. I'm certain that there's others. So GraphQL. A new hope. GraphQL was developed by Facebook in response to these types of problems or issues with REST APIs. They wanted to improve the performance of their new native apps by fetching the exact data each of you needed. Now this happened I believe back in 2012 and they ended up releasing the public version of GraphQL in 2015. So they worked on it for quite a while and put a lot of good thought into it. So the Facebook engineers, they also wanted to design an API where versioning and documentation were much easier. With GraphQL there is no versioning. Which we'll talk about in the live section. In short they wanted to empower the client. Which is something that we should all try to do is empowering our clients. And GraphQL does exactly that. So GraphQL defined a query language for your API. Well, that's not exactly helpful. But, don't look at me, I didn't come up with it. This is straight from the GraphQL.org website. So what does it mean exactly? Well, they offer a follow up paragraph to that terse definition. GraphQL is a query language for APIs in a runtime for filling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API. Gives clients the power to ask for exactly what they need and nothing more. Makes it easier to evolve APIs over time and enables powerful developer tools. There's a lot of stuff happening there. It sounds very exciting. I still have no idea what GraphQL is. So with that maybe we can get a better sense of what GraphQL is by comparing it with our pain points of rest. So where Graph or where rest was rigid, GraphQL is very flexible. In GraphQL, the client is in charge as we've already said. The client specifies what data it needs and the server only responds to what is necessary. So, here's an example here's an example to retrieve posts, their ID and their title in GraphQL. So this query will actually return this response. Data posts, ID, title. Pretty simple. So the query type of posts and the shape that you give it is the exact response that you give back. Which is very empowering if you're thinking of developing an Angular app or Vue components. You know exactly what you're getting back you know exactly what to expect. One thing to notice here is that all GraphQL requests go with one HTTP method and that's post. And this is because you can create long complex queries and if you try to put that in a get request you're going to run out of URL max length very quickly. So in Rails it's going to be a post request and it will be parsed appropriately on the backend. GraphQL is frugal so this goes along with what we just talked about. You get back exactly what you put into it. So if you want posts and ID and comments and author and body you're going to get that back as well. So you get it back in exactly that shape. If you don't want the comments leave out the comments. If you want the comments but only the author leave out GraphQL is easy to document. Don't worry about the fuzziness of this slide this is a screenshot of GraphQL. It is the query viewer, UI viewer for GraphQL and we'll explore this here in just a second but exceptionally easy to document. Basically GraphQL provides machine readable metadata that describes your API. That's a really fancy way of saying GraphQL is self-documenting and is browsable. It makes discovering APIs nearly trivial. Front-end developers would have access to this and everyone on the team has access to the same documentation. Now is where the rubber hits the road I guess. Because I lose my speaker notes we go old school and use no cards. That's pretty tiny isn't it? Let's try to bump up my resolution. Is that a little bit better for people? I think that we can actually be able to make use of it. So for GraphQL let's see if we have access to everything that we need here. In a Rails project we start by adding the GraphQL pretty simple, pretty straightforward. We're going to bundle install and Rails generate GraphQL install and that gives us the graphical interface and everything that we need. Basically it adds this route to our demo file. This is our graphical route. It's the documentation viewer. It auto-generates it behind the development environment for security purposes. You can further lock that down. Then we have our post graphical endpoint. This is going to post to the GraphQL controller and the execute action. I can't, yes. How's that? Let me get rid of I can also lighten the screen or try to change the color scheme. Live demos they say. Let me get some here. This is the GraphQL or the graphical UI served from localhost 3000. We just have the fitterme application running locally and with the graphical endpoint. You can read here as a little blurb about what it is, but this is our documentation on our query type. If we click this docs arrow over here and then get back all the way here. We see that we have a GraphQL schema provides a route type for each kind of operation. So with us, anytime that we're looking at fetching data, it's going to be a query type. Anytime that we're looking at updating or creating, updating or deleting data, it's going to be a mutation type. I didn't think that I'd have enough time to talk about mutation type, so I just wanted to touch on that, but there won't be any examples of mutations. I can click on query and these are my these are my initial query types. So when I say query type, let's go back to the code, what is so we end up with a fitterme schema. So this is our schema file, this is our entry point into GraphQL. So we have our query and our mutation types. Inside, so this is in a directory called GraphQL where we have directories for mutations and types. So we're only going to be talking about types right now, so keep in mind that the types just goes into the types directory and then they're auto-loaded. So as we're talking about query types, so under the query type this is our, remember our entry point into any type, anything that we want to fetch from GraphQL. So we if we want to see the circuits, so the circuit in fitterme is a circuit training work out. We can easily do that. So we can look at that through our through the interface that we have circuits. So over here and get rid of all of this mess, whoops of course I closed so we get rid of all of that and we can type in query gives us a little auto-complete here and now what do we have to play with? So we have circuits, okay let's type in circuits what's, so we know a collection of available circuits, okay let's maybe pull the name of a circuit and maybe we want to know the duration. Now we can run that query and there's the circuits. If we want to decide that we want the image URL but we know that that's there and now we can run that and and now we get an image URL and we can take this and see that it actually is an image URL that actually works if I had internet. That's the joys of live coding demonstrations. So at any rate, so with this we can explore and play with the shapes of the data that we want. The nice thing the really awesome thing about defining these types is it's really easy to add new things and especially to get away from the cumbersome rest responses. So as we take a look at what an actual user looks like from the database. There's a lot going on there. If you look at the user model or a person model or a member model whatever your current user model is and your Rails applications, it's probably pretty bloated so don't judge me too much. But knowing that it's bloated that's why we want to you can customize you can use custom serializers to get a sparse return and then if we look at the circuits, so the circuit that's even more so. So we have the name the duration in seconds some difficulty and then it has this hash of exactly what the workout entails and how to do it. And that's a lot of data coming back if we only need maybe a picture and a workout name. So if we're wanting to implement that here I want to grab a user with an ID of one mainly because I know that's me I'll take the I can have a full name so I'll do a full name and an email address I don't have workouts defined yet and if I try to run that I'll get an error and it'll tell me exactly why. So what we can do I already have a user circuit type and because I was a chicken I didn't want to actually live code I just commented things out and so we'll go ahead and uncomment this workers field and I'll walk through what the code is doing here it's a I'm giving it a custom name because I don't actually have an attribute in the model called workouts so it's going to be workouts it's going to be of types user circuit type and that is defined right here so this is a a GraphQL type and so the description is going to be completed workouts by user so this is for the documentation that's where we get this pretty stuff over here so the duration is all supplied by the description that you supply and you also know while I'm here we have deprecated fields this is how easy it is to deprecate something so I used to have an OG image URL and that is defined in the circuit type so this OG image URL it's the promotional image for the workout it's using the same property up here but we don't want to use OG image URL anymore we only want to use image URL so we put a deprecation reason in and now any clients that are using that or more importantly any future clients that are exploring the API can see that OG image URL is deprecated and will likely be removed at some point in the future so not to use that and it tells them what alternative to use to be in compliance so again living documentation is a wonderful thing so going back to adding the workouts to the user type I'm using a draper decorator here so you know this code is really not all that important now all that we're doing here is pulling the user circuits using an includes to get rid of an n plus one constraint or concern there's a couple different graphical gems there's one in particular by Shopify that I would highly recommend that does batch request that also mitigate n plus one concerns so we'll go ahead and save that and then I don't think that that is using and then we'll need to undo the image URL there and now refreshing that we should be able to use workouts and the workouts we know that it's a user circuit so we can come over here and go to user circuits to see what attributes or properties we have available to us and we have a name so we'll go name and we want maybe the image URL and we'll throw a duration in as well and it'll be that and so what that does it takes this view and instead of rendering the server side now we can use a view component or a react component or your JavaScript flavor of the day and build this component with GraphQL and only getting back the data that the view actually needs to render and nothing else and I believe that is everything that I wanted to show from a live demo standpoint so now let's see if we can enter back into the slide show here and it picks right back up nice so live coding complete I think by now we can all agree that GraphQL is interesting but we may not know maybe interesting it's at least intriguing but before we dive in head first let's take a step back and spit ball some questions where do we start do we have to rewrite everything what about production do we need a graph database because it's in the name and too long didn't read the answer to most of those questions we'll talk about where we can start the other questions the answer is no let's ask a fundamental question is GraphQL really all that different than what we're already doing it's usually presented in a way that it's a totally different way of thinking you have to think in graphs and reimagine your application and it's using some of these buzzwordy things that I think actually are more harmful to GraphQL than anything else in practice GraphQL is just the standardization of things that we're already doing it's similar to REST it's another specification it could be used alongside REST it could be used as a thin layer on top of REST so you don't need to rewrite any of your existing REST APIs you can integrate GraphQL into your Rails application and use that as a thin layer on top of your existing internal APIs or third party APIs so GraphQL adoption and integration so we've already explored how GraphQL can quickly be integrated into a legacy Rails application but let's set that implementation, the technical implementation aside for a second and let's talk about the soft, the people, organization hurdles that you'd have to overcome so where do we start how do we get buy-in from our teams from our organization, from our managers well what we're doing at FishMe is we're starting with one component for us it's a bigger component but you start with one component you implement GraphQL into your Rails application you use it to talk to your existing REST APIs so that you're not rewriting a whole bunch of code and you take that one component and you deliver it all the way to the next production there's no need for a graph database you're already running queries if your queries are already inefficient you've already got another problem so GraphQL isn't going to necessarily highlight or create more problems on top of bad queries and I guess going back to that with integration incremental adoption is the key you think about any technology that's really taking fire and taking hold be it React especially with React and now more recently View but if you can't incrementally adopt it just drop it in create something without a lot of overhead it's probably not going to take off so GraphQL can be adopted in the same way in your applications so GraphQL first workflow so as you're developing this one component design your schema first so the schema is those GraphQL types that post type that query type and use that schema as a contract between your front end and your server because now with that GraphQL schema you can hand it off to both teams if they're separated and create different you can develop the back end and the client view side in parallel there's great mocking libraries so that the front end can load in a GraphQL schema and get live responses back without the need for an actual working back end server and then you can come together and marry those two at the end of the project great talk that talks exactly about this and goes into far more depth than I will is navigating your transition to GraphQL by Saschko and Danielle from the Apollo team would highly recommend that so final thoughts what abilities do you have so as we're thinking about client and user joy what abilities do you have to improve client experience and developer experience think about those and then how will you respond with that ability how will you respond with your responsibility response and ability and bring your responsibility be kind do great things and continuing building great things and thank you very much