 Good morning, everyone. Looks like the mic's working. All right, welcome. My name is Robert. I am a software engineer at the Facebook Boston office, where I work on GraphQL. And before that, I was a software engineer at Microsoft and a software architect for as software group. With the recent trends in microservice architectures, cloud native, and rich web apps, there's a lot more challenges when building APIs. In this talk, we're going to talk about how to overcome these challenges with GraphQL, an open source API query language that we created at Facebook. Let's go over the agenda. First, we're going to try to define GraphQL. What is it? What is it not? How do we use it at Facebook? And how does it compare to other technologies in this space? Next, we'll talk about some of those challenges that we face when building APIs. And we'll look at how GraphQL deals with them. Then we're going to transition from theory into practice. At this point, if you're convinced that GraphQL can help you solve your problems, then we'll talk about how you get started, how you get GraphQL into production, some of the advanced use cases and features you can rely on, and specifically how you can deal with authentication and authorization. And finally, we'll wrap it up by talking about what's in store for the future of GraphQL. What's on our roadmap? How can you contribute and participate? And finally, we'll have a resources slide followed by Q&A. So any hyperlinks you see on here, don't bother taking pictures of it or anything. There's going to be on the resources slide for you at the end. Let's start with a demo here. I have a GraphQL server running on my laptop. And I've just plugged in the URL into my browser. And what we see here is GraphQL. Now, GraphQL is the GraphQL IDE. This is just a tool. This is not GraphQL itself. But this tool lets us author GraphQL queries, send them the server for execution, and display the response. In addition, on the right-hand side, you see there's this documentation explorer pane. And using this, we can explore the GraphQL schema that this endpoint supports. So we know what queries to execute. In this case, I've built a very simple example schema to model an online library system. Let's take a look at what it contains. On the right here, we have this query root. And if I click through, it says it has two fields, authors and books. And for authors, it says it's going to return a collection of authors. So if I click through this author entity, it says, oh, it's got these fields, ID, name, image. And these are all primitive fields of type string. But then it has this edge pointing to books. And it returns a collection of books. And books have a bunch of other scalar fields. So knowing that, I can come in here and I can just start authoring a GraphQL query. So if I have a query, I can come in here and I remember that these are my fields that I can use to start accessing my graph of data. So I could say books, and I could see something like ID. So these are the IDs of all the books in my system. But IDs aren't that useful. They're great for programs, but they're not great for human beings. What are the titles of these books? So it looks like we have some Harry Potter books, the Lord of the Rings trilogy. Now, what if I wanted to fetch the author for each of these books? I've got this author ID, and if I execute this, that seems to be pretty consistent, but it's not giving me the data that I actually want. What if I wanted the author's name? Well, I could do something like this, and now I have the author's name populating my query. What if I wanted to get, for a given book, I wanted to get all the other books written by that author? Well, I can come in here and just say books. And now you can see we started with this Hobbit, it was written by Tolkien, and then here are all the other books in the system that Tolkien wrote. But also, I want to show that if I come in here and I type foo, it's telling me, what are you trying to do? Food doesn't appear to be a valid field. And if I come in here and type something like this, it says, hey, what's this? You have, you know, we've declared the opening in the curly brace for the selection, but we've got this extra string outside of it. What does that mean? So let me switch back to slides. What did we just see? Well, we saw a GraphQL document on the left, and we packaged this up into a request, we sent it to the GraphQL server, and we got back JSON as a response. But we also saw that we can't just send arbitrary text. It has to follow some rules. And these rules come from two sources, the GraphQL language specification and the schema. Now, the GraphQL language specification describes the syntax. So it says, opening curly braces must match, or you must have an operation type before the first selection. The second thing, when we typed foo into the selection, and it says, hey, what are you trying to ask for? I don't understand the field foo. Well, that information comes from what we call the schema, and the schema is domain-specific, and it describes the types and fields on those types associated with a particular domain. In our example, this schema that we were looking at was describing an online library system. And you also saw a server that can take one of these requests, execute it, and return the response as JSON. So there's an implementation of the GraphQL specification running that helps you construct the schema, parse incoming requests, and fetch values for the requested fields. In the demo we just saw, we were using the reference implementation that was written in Node.js. It's also useful to describe what GraphQL is not. And anytime anybody sees QL, they probably think database, right? But GraphQL is not a database query language. Although the asterisk here is because there's this interesting new database called DGraph, which happens to use GraphQL as its query language. So I just wanted to point out that it's not the original design of GraphQL. And it's also not a client-side state management solution. So we might be tempted to think, oh, okay, cool, I've got this JSON graph of objects. I can just do it with client-side state management, right? Not quite. You still need some client-side state management for dealing with things like caching, cross-view consistency, and optimistic updates. And it's also not a good solution for binary streams. For example, file transfers, images, streaming video, where you're really streaming chunks of binary encoded data. That's not what GraphQL was built for. And it's also not to be confused with GraphAPI. So if you've ever dealt with Facebook's third-party APIs, you've probably used GraphAPI. GraphQL is something different altogether, and it's currently only used for Facebook's first-party applications. It's not a limitation on the databases that you choose. It's actually just a very thin layer, as we'll see in the stack diagram later. And you can use GraphQL with all sorts of persistence backends, ranging from SQL to NoSQL to caches like Redis to flat files. And that's because the GraphQL fields that we saw in the schema are backed by arbitrary functions that you provide when you define the schema. Now, although the reference implementation is written in JavaScript on Node, that doesn't mean that GraphQL is a JavaScript-only thing either. There are implementations of GraphQL in just about every popular language. For example, Java, Python, Ruby, C sharp, Rust, Go, you name it. And these servers are used in production at a large number of companies. And you may have also heard of GraphQL through other successful open source projects, such as React and Relay. And while React and Relay are really good choices for building frontends that talk to GraphQL, there by no means exclusive. The declarative approach that GraphQL provides is equally useful for jQuery, Angular, View, as well as native UI technologies, such as Objective-C and Java. Lastly, it's not limited to HTTP. We happen to see GraphQL going over HTTP in our demo, but it's not limited to HTTP. It happens to use HTTP very frequently because of HTTP's ubiquity. GraphQL has three operation types. We saw the query where we were essentially performing a read against the system. But there are two other operation types. We have the mutation operation type, which supports writes. And then we have the subscription operation type, which allows the client to specify its interest in observing an event, a domain-specific event. Both queries and mutations take a request and then return a single response in the future. The subscription, by contrast, takes a subscription request and then returns zero or more future responses. And as a result, you can probably see that queries and mutations are stateless and they can operate over any transport that supports the request-response model. However, subscriptions are stateful and that means you need to be careful when trying to maintain durability, availability, and throughput at scale. Another thing is queries and mutations are only semantically representative of reads and writes, just like HTTP verbs. In other words, if you're implementing a GraphQL server or a schema, nothing stops you from having a query perform a server-side state mutation. And nothing stops you from creating mutation that has no side effect. These are just tools to make the operations and intent more clear. So if you had an HTTP get operation, that somehow deleted a record in a row in a database, nothing stops you from doing that. It's just not very communicative and intuitive for the user. And a GraphQL server doesn't even have to support all these operations. For example, if we don't want to find subscriptions, then we just simply leave them out of the schema. Let's talk about the origins of GraphQL and how it's used at Facebook today. The first version of GraphQL was built back in 2012 by three Facebook engineers, Lee Byron, Nick Schrock, and Dan Schaffer. And it was designed to support the growing needs of our mobile applications where the rest architectural style just wasn't cutting it. And in 2015, after years of building, extending, and operating GraphQL, the team decided to open source it. But this wasn't just a port of what we had built internally. This was an opportunity to examine the initial work, to take a look at what worked well and what didn't and make a bunch of tweaks. And as a result, GraphQL was open sourced in two parts, the specification and the reference implementation. Today, GraphQL powers many things, most notably all the Facebook web and mobile apps. Across these, we have over 1.3 billion daily active users. And these users send us over half a trillion GraphQL queries per day. GraphQL is also seeing rapid adoption on other companies. For example, GitHub, Pinterest, Intuit, Coursera, Yelp. And there are a lot of other companies using them for internal use cases that haven't gone public with their announcements. Now there are a lot of architectures, frameworks, and libraries, and patterns that facilitate client server communication. GraphQL is not the only one. But we could be here all day trying to compare GraphQL to everything else. So in the interest of time, I'm gonna focus on comparing it to REST because REST is the architectural style of the web. And hopefully by comparing it to REST, you'll transitively understand how GraphQL compares to any other API technology in this space. If not, come and talk to me afterward. Before we dive into the comparison, I wanna preface this by saying you'll find a lot of literature, a lot of articles online about how GraphQL is here to replace REST or how awful REST is. And I think that kind of narrative might be overreaching. So I wanna frame this comparison in terms of trade-offs. Try to avoid thinking about each row here as a checkbox where the column with the most checkboxes wins. But actually by show of hands, how many people here think they know what a REST API is? Okay, that's quite a few. Keep them up, keep them up, please, please, keep them up. Okay, now how many people with their hands up think they will agree with everyone else with their hands up what a REST API is? Where do they go? So that's great for the first point of comparison. It's likely that if you put 10 people into a room and ask them what is REST, you're gonna get 20 different answers. And I'm here to offer a 21st. So by REST, I mean representational state transfer as defined in Dr. Roy Fielding's dissertation in 2000. That is, a REST API is something that meets all six of the REST architectural constraints. Specifically, there's one that stands out. It's called the Uniform Interface Constraint. And the Uniform Interface Constraint is what contains the hypermedia constraint which states that hypermedia acts as this engine that transfers state between the client and the server. Now, the degree to which these architectural constraints are observed and enforced is highly variable. So that's why all of your hands went down. Because we have this landscape of HTTP JSON APIs that call themselves RESTful or REST-ish. And if we take two Paragon REST APIs, unless they were built with the same framework, it's extremely unlikely that they share critical features like linked resource annotations. So I think it's safe to say that REST has no shared definition, at least not in an concrete sense. GraphQL's not like that. GraphQL is not up for debate. Given a specification and a schema, you know exactly what is and is not a valid query. And you know the shape of the response that you're gonna get. And sometimes this specificity is good. Other times, the flexibility of REST is also good. Next, let's talk about the central organizing model behind REST and GraphQL. In REST, the central concept is the resource. And you can think of resources as virtual files living on a remote server somewhere. They all share common operations against them. In GraphQL, the central concept is a graph. That is nodes with fields and relationships to other nodes. And this has a profound impact on how you add features to each API. In REST, we're gonna end up adding more URIs for more resource types. Whereas in GraphQL, we stick with a single endpoint and we expand the possible variations of the queries against that endpoint. And REST's resource model is also a huge advantage when it comes to federation. By federation, I mean we can link resources between domains. I can make a Facebook post where I share a Wikipedia link. And then in that Wikipedia link, there's a citation of a New York Times article. In GraphQL, linking data across two different schemas is difficult and there's currently no good solution. REST has another constraint called manipulation through resource representation. And that means that a given resource includes hypermedia links that describe how to manipulate it. For example, how you modify, delete, or replace it. In GraphQL, when you're at a node in the graph, there's no standard or built-in way to access all the mutations that could affect that particular type or that particular instance. However, you might argue that GraphQL has something more general, introspection. Introspection is like reflection for your API. And it's the core feature that enables us to build tools like we just saw with GraphQL. It also allows us to generate type-safe client code and some other integrations that we'll see later. By contrast, it's difficult to imagine to introspect REST APIs in a standard way. Maybe something that resembles a sitemap. I don't see a lot of those around anymore. In any case, it's not mentioned in the REST constraints, so any implementations would immediately lack standardization. And as a result of introspection, GraphQL features strongly typed inputs and outputs. REST has a hard time pulling this off, partly again because of the decentralized approach to federation. And modern APIs commonly have to deal with clients that observe changing data. REST's stateless protocol constraint makes this difficult. It makes it difficult specifically to build efficient, push-based APIs that know the state of the history of what was already pushed to that particular client. GraphQL doesn't have this restriction. And via subscriptions, it actually makes real-time data a first-class use case. The trade-off here is that subscriptions are stateful and therefore it adds a great deal of complexity to the underlying infrastructure. That said, subscription support is optional. Building modern APIs is tough. There are a lot of challenges. So we're gonna dive into a few of them in more detail and see how GraphQL deals with them or doesn't deal with them. The first is efficiency. Within a single network request response between a client and server, two common problems occur. The first is over-fetching. And that's when the client made a request for some data, but the response contained additional data that the client didn't ask for. And the second is under-fetching. And that's when the client makes a request, but the response didn't contain enough data. And that forces the client to issue another network request. And under-fetching is especially common with the REST architectural style because the better you get at implementing the hypermedia constraint, the more common under-fetching becomes. And these are huge problems because networks suck. I mean seriously, here's some common latency numbers. So if we try to read one mag of sequential data from a modern SSD, it's gonna take about one millisecond. While if we send a packet from the US to Europe, the round-trip time takes about 150 milliseconds. So the network is exponentially slower than just about everything else that happens in a typical application stack. And that's assuming that we're on a really good network. With mobile devices, the networks are even more unreliable, subject to interference from solar flares or other devices or buildings, vehicles, terrain. In many parts of the world, wireless network quality caps out at sub-2G. And data usage is heavily metered. And to get a better sense of this problem, I have a demo that we can do together. So if anybody has their laptop here, wants to follow along, feel free to open these two URLs in your browser in two different tabs. I'll give you a moment if you wanna follow along. Just raise your hand if you're gonna try this. If nobody's interested, I'll just do the... Okay, cool. Yeah, take a second. Okay, we're all set. That first URL, Swapy.co, takes us to the Star Wars API. It says, all the Star Wars data you ever wanted, planets, spaceships, vehicles, people. And this is great. This is, I'm a huge Star Wars fan, by the way. But this is great. You can see, you know, you've got this URL and it seems like people slash one is the resource representing Luke Skywalker. And you've got a bunch of data here telling you about his birth year, his gender, home world, the relations to films. So I guess this means the films he appeared in, the species, the vehicles. Now, let me point out a couple of things. This films, this films one, this URL here. What is the shape of the data that this thing's supposed to return? It's probably JSON, right? But is it gonna contain something called title? Is that an immediate field in the root of the object or is it nested in there somewhere? What about the director? Does it have that information? I just don't know, just from looking at this, I kind of have to go through this hyperlink to follow through and take a look, right? So let's do that. Let's check out what films slash one is. Oh, so I guess, right. So I mean, there is something, there is a title field, it's called A New Hope. This is episode ID four. It's got opening crawl. And then it's got this bunch of characters, all the characters that appeared in New Hope, I guess. So imagine that we had a requirement that was for the film New Hope, display the names of all the characters that appear in A New Hope, right? I mean, just as humans, we can kind of do this. We can kind of take the role of the machine. What are we gonna have to do? We're gonna have to click every single one of these links and say, oh, okay, I guess people one is Luke and this one's C3PO and this one is R2D2. But every time we click one of these links, this is another network request. If we're in the US and this server's in Europe, well, that's like 150 milliseconds for each request and we're sending these off in parallel. They're gonna have to come back. Some of them are gonna fail. I'm gonna have to retry some of them and then I'm gonna have to join this logic back on the client. So I think that's kind of illustrating. Yeah, and also, look at this, this opening crawl thing. In our requirement, that wasn't even part of it, but this is a huge chunk of text and this isn't even the only piece of superfluous information. So in this Star Wars REST API, given that requirement, we've seen a real-world example of both over-fetching and under-fetching. It both gave us too little and too much data, which is not good if we're trying to build really efficient mobile apps that can operate over flaky networks. Luckily, that second link is that same API, that same data, but rebuilt with GraphQL. And just like the library demo we saw earlier, we have this root query and we can come in here and we can see immediately what is the shape of all the different nodes that we have in this Star Wars schema. So let's try to fulfill that requirement earlier, right? We wanted to get all of the character's names from Unyoo Hope. Well, I can come in here and I'm gonna use store hand notation. If you don't specify the query type and this is the only query in the document, then it automatically infers that it's a query type and you don't need to give it a name. So I can say all films and within all films, it says it's a typed film connection, so let's just get the films out of it. And let's try to guess, yeah, so it has something called ID. Great. So it looks like this is the one that we want. And there are actually a couple ways to slice at this where I only want Unyoo Hope. Probably the easiest one is I can just say first one. Right? Everyone with me? Next, in the film, hopefully there's something called characters, right? There's a character connection. And you know, we can just start typing and we get type hints from GraphQL because of the introspection query. Right? But just as easily we can come in here into this thing and search characters. What has characters? And you get a lot of this documentation for free. So the character connection, I can say, well, for each character, I could get their IDs. This looks pretty promising. And there you go. I have all of the character's names from the film, the first Star Wars film, Unyoo Hope, in a single network request response round trip with zero overfetch and zero underfetch. This is the exact data I asked for and nothing more, nothing less. Now I want to stop here because, you know, it seems like there's a lot of experience in the room dealing with REST APIs. And some of you are probably thinking, well, we can do this with REST APIs. Absolutely can. There are lots of ways to do this, right? We can create a custom endpoint. We can create an endpoint that's like starwars.co slash all character first names from movie with ID and then pass an ID as a query string. How many people have done something like that? Yeah, so you know what I'm talking about. We can do it another way. We could, in order to get this nesting field structure, we could pass it in with query and we can say fields equals whatever as a query parameter. But let's say our requirement changed ever so slightly. Let's say our requirement was that we want the character and we want the home world or something and we want the orbital period for whatever reason. I don't know. I'm a huge Star Wars fan. If I did this, what am I gonna do? Am I gonna go and create another swappy.co slash characters and their home world's orbital periods with ID? This is not a solution. It takes you a little ways forward but you can imagine for certain apps at certain scales this is not a tenable solution for very long. So that's a good opportunity to kind of mention that and a lot of people think about GraphQL as this client-oriented query language and it is but it also makes the server engineer's life a lot easier. You can think of it almost as this engine that can create on-demand rest endpoints where you don't need to go and have a new endpoint and that new endpoint has new authentication and authorization requirements and now you gotta monitor it and you gotta deploy it and you gotta version it. This is the headache, whereas expanding the query in GraphQL adding new capabilities to a GraphQL schema is simple. Okay, so hopefully you guys trying to follow along with the, on your laptops and you can keep exploring these two APIs and let me know if you have any questions afterward. So we saw how GraphQL can help us avoid under-fetching and over-fetching. It lets the client declaratively specify all the data that it needs in a single network round-trip and it reduces the need for complex client-side logic to deal with error handling and retries client-side joins. We also got type safety out of it. Through the schema, GraphQL provides type safety for these requests and that improves predictability because a client never has to send a request to an endpoint and then guess at what it's gonna get back. It has a high level of confidence about the shape of the response and this is really useful for native clients that are strongly typed or gradually typed because it enables compile and build time type checking to help detect mismatches early on in the development feedback loop. And at Facebook this allows us to generate type safe client models that correspond to the GraphQL queries in iOS and Android and that take advantage of full advantage of the type safe languages of Objective-C and Java. GraphQL also enables another very interesting non-technical capability for your APIs and that's fluency for modeling the business domain. How many people here are familiar with domain-driven design? Okay, a few of you. Domain-driven design is a book by Eric Evans in 2004 and it has this really neat set of ideas. The central idea is that people across the business, both technical and non-technical can build this shared vocabulary called the ubiquitous language. And the ubiquitous language is just natural language that describes the business domain in terms of entities, processes, and relationships. And this kind of natural language lends itself to being modeled as a graph. This means you don't have to talk about the business in terms of tables and rows and joins and stored procedures or you don't have to talk about them in terms of resources and URIs and HTTP operations. The entities and operations on those entities can just be spoken and reasoned about in natural language. And I think this is an incredibly subtle but incredibly powerful feature that GraphQL brings. Versioning, the web has spoiled us. If your app only has a web client, then you get to dictate the version that the client is running because the user is essentially redownloading that app every time they hit that URL. However, it's not the case with native apps as I'm sure many of you are very well aware. And if you use Facebook on iOS or Android, you'll probably notice frequent updates. But you have a choice to update that app or not. So you can imagine that we have a large number of different versions running at any given time. How does GraphQL handle this? Well, how would REST handle this? Would we version the API route? We have thousands of those. Would we pass in the version as a query parameter? Would pass it in the header and the MIME type or something? Or the content type? Would we bake it into the access token? None of these are scalable solutions. We've tried. So GraphQL deals with versioning by simply not doing it. And that means GraphQL servers must rely on backward compatibility and forward-only versioning strategies. And to do that, we can use the schema and deprecate certain fields. We can mark certain fields as saying, we wanna remove this as soon as possible. Please stop using it. And then one of the following scenarios occurs. In the ideal case, clients respect this message and they migrate away from using it. And we can detect when that field stops being requested and then we can remove it. If the clients don't migrate, then we have two choices. Well, we can either, if we value backward compatibility and that older version of the client to continue to work, then we can keep the field around and maintain it forever. Or we can just say, that version is too old. It's more than five years old. We're gonna stop supporting it. And we will just break that version. And that's in the, you know, but that's a business decision. We've already seen GraphQL in action and we've seen some pretty cool features like inline documentation, type hints, syntax highlighting, execution. But it's important to understand that all of these features are powered by GraphQL introspection. And introspection opens up this world of possibilities for tooling and integration. For example, my teammate, Hio, has been working on something called GraphQL language service. And this is a package that'll allow you to add some of GraphQL's capabilities to your favorite IDE. Check out this demo of it working inside VS Code. So we can write a query inside VS Code. We get type hints. We get inline documentation. We get type checking on input parameters. And we get click go to navigation, go to definition on fragments and related types. And of course we also get that same validation, the same validation capabilities we saw in GraphQL. It'll tell us when we've declared an invalid field. It'll tell us when we've violated the GraphQL language syntax itself. Authentication and authorization. I think this is such a common problem for APIs that it requires it's a dedicated, we should talk about it in more detail. These two concepts are often confused with one another, so let's quickly refresh. Authentication refers to identifying who the caller or user is. And this can be done, for example, by including an access token in the request header. And the first thing the server will do is check the signature and the validity window of this access token. And then the authentication requirements are usually domain agnostic. They don't vary with domain. And they'll go something like this. If the user can prove who they say they are, let them make the request. Otherwise, don't even bother cracking the request open or executing any more of it. Authorization, on the other hand, refers to whether the authenticated caller has permission to perform a given operation. For example, if we're building a blog, we might have an authorization rule that says only authors and admins can see posts in the draft state. Authorization rules are usually domain-specific, and therefore they belong in the business logic layer. I think a diagram will make it all a lot more clear. So you can see up at the very top, we have our transports, and imagine that the client is floating somewhere above this slide and sending requests to our server. And these requests come over some sort of transport, perhaps HTTP, perhaps some custom protocol. And at some point, the server providing those network transports has to authenticate the incoming request. And that's also a good place to reject in unauthenticated requests if authentication is required for that endpoint, for that API. And you can see that GraphQL, REST, RPC, these kinds of techniques kind of sit in the middle. They sit in the middle of the transport and in front of the business logic. And notice that I put authorization into the business logic layer. This is a little tricky. Why should authorization live in the business logic layer? A lot of newcomers, when they start with GraphQL, they get really excited because they see how easy it is to build the schema out and they start adding business logic into the field resolvers. And they'll add authorization logic there consequently. But if you do that, this is what it looks like, right? What's wrong with this? Well, there's no single source of truth across the different ways we can invoke the business logic anymore. We would need to duplicate the authorization logic across REST and RPC. Probably not a good idea. We might get inconsistent behavior depending on whether the user calls into us through REST or GraphQL. Another way to think about this is how we would test our business logic. If we had a requirement from earlier, like only admins and authors can view draft posts, how would we test that? Ideally, we should be able to write a unit test that isolates the business logic layer. But if we structured it this way, then at best, we have to write an integration test that involves GraphQL as a superfluous dependency just to exercise the authorization logic. Probably a sign that we made a misstep somewhere. So I think this is the diagram that we think makes the most sense for GraphQL and how to think about how GraphQL fits into the stack. Now that we understand some of the problems that GraphQL was designed to solve, but I wanna emphasize that GraphQL is a tool. It's not a silver bullet. It has certain problems that it's good at solving and other problems that it's not so good at solving. And part of our job as engineers is to understand the shape of the problem and finding a good problem solution fit. For example, I wouldn't want people to use GraphQL just because they think it's cool or because it's new. But aside from the specific problems that GraphQL helps you address, there's another dimension to consider, which is when. So you think you have a problem like this, but when should you deploy GraphQL? And this comes up frequently enough that I think it's worth addressing in a fairly general way. For example, if you're building something like a Hello World app on a white background and a web browser, it would be silly to reach for some heavyweight UI framework like React or Angular. And the same is true for APIs. There's no real payoff for trying to future proof everything. But then just how do we think about it? Here we can turn into something called the design stamina hypothesis. This is an idea proposed by Martin Fowler and he asks, what's the point of good design? Because if you start off with no design, nothing gets in the way, that you don't think about how to do some specific thing in some specific way. So you have this very fast initial velocity where you can get a lot of cumulative functionality in a short amount of time. But as you continue with no design, that curve tapers off and it becomes increasingly more and more difficult or takes longer and longer to add the same amount of cumulative functionality. Consequently, if you had started with good design, you are, there's an opportunity cost. Anytime you spend in getting better infrastructure, better documentation, training, whatever, that's time spent not coding or testing or understanding the customer. And if that happens, then initially, at least for a period of time, it will deliver less cumulative functionality in a given span of time compared to no design. Now notice that these two lines cross over and this is called the design payoff line. And what the design payoff line is saying that is that at a certain level of cumulative functionality or past a certain amount of time, good design wins. And this is, I found this to be a very generally useful way to think about when to do X. So GraphQL is no different. Try to think about GraphQL in this kind of framing. Great. So hopefully we have a fairly decent understanding of GraphQL now. We have a decent understanding of the problems and what GraphQL's good at solving, what it doesn't actually try to solve at all. Now some of you might be wondering how do we get it into production? You like these ideas, you wanna try it out. Well, every organization is different and your mileage may vary, but here are some general dos and don'ts when trying to get GraphQL added to your set of tools. In general, try to prefer small incremental changes over large overhauls. Deploy in a forward only way and leave V1 and V2 side by side for a while until all clients have had a chance to migrate. Specifically, don't try to build the entire schema. If your business is in building blog posts, for example, model only a small portion of the schema, it's okay. Model the minimum useful subset of it. Don't try to replace rest in one push or perhaps don't even try to replace rest at all. Don't place business logic in the GraphQL layer. You'll probably pay for it later. Do work with your team. People get really excited about GraphQL after they get it and they're like, oh yeah, this needs to go into production. Going rogue on this is not the best way, most of the stress strategy. Talk to the team, try to help everybody and understand where the wins are, why this is a good solution for the problems you're looking at. And then choose a solution that fits with your stack. So I mentioned that GraphQL servers are available in all sorts of different programming languages. There's no reason why anybody has to use the reference implementation that we've written in JavaScript in Node. Build a simple query first. Perhaps even something that requires no authentication, something like a message of the day that you can show to anybody. Build that first along with a minimum useful subset of the schema and then you can start figuring out how GraphQL queries work from the client, how they work on the server. And that means you can gradually expand out and add features like auth and mutations. And then I mentioned this before but it's worth repeating, but gradually expand the schema. So here's some advanced use cases. I think we're going over time a little bit so I'm gonna hurry this up. But GraphQL is clearly an edge API technology. That means people use it as an API gateway a lot. So if you have microservices, rather than having the client know about the URL of all those different microservices, you use GraphQL in front of those microservices to create a consistent and cohesive API endpoint for the client to interact with. GraphQL supports both third party and third party use cases. Facebook uses as a first party API solution, GitHub uses as a third party API solution. And we've also seen it used for service to service communication. It's really interesting that people are using it for that, but if it works, great. Skip over that. You might wonder, okay, well what prevents clients from sending malformed queries or queries not necessarily malformed, legal but are extremely inefficient or are infinitely nested. There's a technique we use at Facebook called the persisted query. And the persisted query basically hashes all queries ahead of time. And it rejects any queries that are not hashed. And that way we can control the maximum complexity of any given query. What's next? In about two weeks, there's an event called GraphQL Europe where we're gonna be making some important announcements about the progress we've made on subscriptions. Subscriptions is in an RFC state right now, but it's currently being reviewed to go into the reference implementation and the specification. We're also gonna see a rise in support for persisted queries from our partners. And we're also gonna see some really cool experiments like batch, defer, and live queries. So live queries are particularly interesting. Instead of using subscriptions to observe data, we can execute a standard query operation, but we can decorate it with a special directive called live. And that tells us that that query should be a living query. I don't want just one response. I want a new response, container to delta at any time that query would change. And of course we'd love if you were able to contribute back to GraphQL. There are many ways you can, of course, participate in the design discussion of the spec. You can PR features to existing GraphQL servers. You can build a new GraphQL server in your favorite language if one doesn't exist. And you can start working on tooling integrations. Join a local meetup and talk about GraphQL, talk about your journey, or just hang out in our Slack channel and be helpful. So that's it. Here's some resources as I promised. I hope I've equipped everybody here with a clear understanding of what GraphQL is, the problems it was designed to solve, and the associated trade-offs. So if it sounds useful to you and you have some ideas, if it sounds useful to you, hopefully you also have some ideas of how to get it into production. That's it. I'll leave this slide up and we'll do some Q and A. But thank you very much for your time. And I really appreciate you. It's a pleasure, I think.