"What is GraphQL used for?” “How do I find the fields I need?” “How do I test queries against a local graph?” All of these are common and valid questions that developers who are learning GraphQL have when they are first getting started with a unified graph. The secret to overcoming these challenges? You guessed it, Apollo Studio! In this session, we’ll dive into the best tools in Apollo Studio to help new (and experienced) developers feel confident when querying and collaborating on a unified graph
The Secret to Graph Onboarding
AI Generated Video Summary
Today's Talk focused on making GraphQL graphs more usable and approachable. It covered topics such as onboarding developers, enforcing graph usage, handling errors and authentication, creating a custom developer portal, enhancing the log-in button and query IDE experience, enforcing rules, and building and customizing public graphs.
1. Introduction to Making Your Graph More Usable
Hey, everyone! Today, I want to share tips for setting up your graph to be more usable to other people. GraphQL's introspection and auto-generated tools make it self-documenting, but as your graph grows, you'll need to scale development and onboard new users. Thinking about graph usability from the start makes onboarding easier.
Hey, everyone! My name is Danielle and I'm an engineering director at Apollo where I've been working on helping people use graphs for more than five years now. And today, I want to share some tips with you for how to set your graph up so other people can use it successfully.
This talk will be a little different than your standard GraphQL deep dive because instead of talking about some of the elements that go into building a graph, I would like to talk about how people use graphs. And in particular, I would like to talk about how to make your graph more usable to other people.
You might wonder, why is it important to take explicit steps towards making your graph more usable? Well, GraphQL has introspection built into its specification, so it's self-documenting, right? And the GraphQL ecosystem has a lot of wonderful tools that are auto-generated from GraphQL introspection to make things like schema diagrams and fast documentation sites. But the reality is, like any other piece of code that you author or any other product that has a bit of success, eventually it will start growing and growing. And you're going to need to scale the velocity of your graphs development beyond a single person or a single team of people. And the more you think about how you want to use your graph early on, the easier it will be to onboard new folks into your graph down the road.
2. Onboarding Developers and Enforcing Graph Usage
Today, we'll discuss how to onboard developers into large-scale graphs and create a developer portal-like experience for easy integration. We'll also explore tooling to enforce graph usage and establish naming conventions. Additionally, we'll cover schema and query linting tools for federated graphs and the benefits of capturing metadata using GraphQL directives.
So with our time today, I want to talk first about how people who are running graphs at a pretty large scale are onboarding developers into their graphs both to consume and to contribute to. And then with the majority of our time, I want to write some code together and show you how you can set your graph up with a developer portal like experience for other people to plug into with very little effort. So let's dive in.
I feel like the GraphQL community is inundated with technical content relating to how to scale a graph. But I haven't seen a lot of content around the human side of scaling a graph. So I asked some of our customers and some folks from our community, what do you do to onboard new people to your graph? And I got a lot of answers back with overlap. So it was exciting to see a lot of the patterns and what people were doing.
A lot of folks are using internal hashtag GraphQL Slack channels to make themselves available for questions and to create processes around things like schema design. A lot of folks host regular onboarding sessions to help new teams get started. Folks also host monthly lunch and learn sessions and brown bag talks on advanced GraphQL topics or to talk about new things that are happening in the ecosystem. And a lot of folks have set up a graph section in their internal wikis. Some folks have even created full graph websites. And these sites tell people how to get started with a graph, how to authenticate with every company's unique needs, what types of conventions this graph is following, et cetera.
Some of my favorite answers that I got back though were actually around the tooling that people have set up to enforce that their graph is being used according to the rules of the company. One example is that there are a lot of ways that people set up observability for their APIs. And with GraphQL, once you put something into a graph, it becomes discoverable through introspection. So it's very possible that you might add a field to your schema for your own use, but someone else in some other department might also start using it. So if you require that every request being made to your graph has headers to identify which client was making those requests, then you can set up observability to be alerted whenever a new client starts using your field, which becomes really useful information as you evolve a graph. And what I have on this slide here is just an example of what that client-level observability looks like in Apollo Studio.
Another pattern that I really liked was the idea that you could establish some naming conventions for your operations. So first and foremost, one thing that you can do is you can enforce that every operation to your server has a name, but then in addition to that, you can set up naming conventions so that your operations are all being named in a standardized way. And this becomes really useful down the road because inevitably one day, you'll end up having some issue with some section of your graph, and if all of your operations follow a standard naming convention, it will be very easy to figure out which parts of your products are being affected by this graph issue. So even though operation names aren't unique identifiers, in practice they're actually very, very helpful as a tool for product resiliency.
And then on the developer tooling side of things, there was a pattern of people setting up schema and query linting tools that I really liked. So one example of this is in a federated graph where you have lots of subgraphs that are all independently owned and controlled by different teams, it can often be really useful to enforce that every subgraph schema has contact information in the schema itself. And you can use GraphQL directives to define contact information. And then you can use schema linting and GraphQL schema tools to make sure that those directives are present. And one of the cool things about using the schema and directives and linting for capturing all of that metadata is that all of the tools further down in the GraphQL ecosystem can make use of that metadata as well. So here in the screenshot I have a picture of the documentation page like schema documentation for graph in studio that is showing contact information about the subgraph that a particular field belongs to. And there's so many more conventions that you could set up along these same lines.
3. Handling Errors, Authentication, and Onboarding
Handling error throwing and authentication in GraphQL is crucial. Consider patterns for mutation arguments and schema nomenclature. Onboarding users without GraphQL experience requires providing information without overwhelming them.
How do you want your graph to handle error throwing is a really big topic in GraphQL. How do you want your graph to handle authentication? Is there a pattern that you want to follow for the types of arguments that mutations are going to take in the schema? Is there a particular nomenclature that you want to make sure people abide by when adding new things to the schema? And amidst all of this onboarding stuff and teaching people how to use the graph and setting up conventions for them, you also need to keep in mind that a lot of folks are going to be coming to your graph without much GraphQL experience at all. So you need to have a way to give them this information that they need to succeed without also completely overwhelming them or making the barrier of entry to your graph too high.
4. Creating a Custom Developer Portal
Across all the feedback I received from different teams, creating a developer portal was a consistent practice. Building a full developer portal may seem daunting, but new features in the Apollo ecosystem make it easier to share your graph. In this part, we'll write code together to set up a customized developer portal. I'll demonstrate how accessible it is by using a demo graph I created. The graph allows querying financial transaction information and uses the Plaid financial transactions API as a lightweight wrapper. To make login easier for developers, we'll create a custom web page and change the default landing page of Apollo Server.
And across all of this feedback that I got from these teams about how they onboard developers into their graph, the thing that was consistent for pretty much every team is that they had created some sort of developer portal. And these portals took all sorts of different shapes, websites, wikis, even Google docs. But every team had some, every team had needed to create some sort of hub for all of this content.
And it might seem like building a full developer portal is kind of a big task and therefore one you should take on only when you're ready to start scaling your graph outside of the context of maybe the team that started the graph. But there are some new things in the Apollo ecosystem that make sharing your graph much easier than it used to be. And I wanted to show you all just how easy this could be.
So with the majority of our remaining time, I wanted to write some code together and go through the process of setting up a fully customized developer portal for the graph just to show you how accessible that now is. So I have a little demo here for us to start from. And you should be able to get into this code sandbox by scanning that QR code. And this is actually a graph that I created about a year and a half ago, when COVID first hit, and I transitioned to working from home. Because in my work from home routine, I started to try to make some routines and I made this habit of going on a walk and getting a bagel every morning before work to get myself into the right headspace.
And a couple months in, I started to wonder, what is this bagel walk habit costing my budget? And being the GraphQL developer that I am, I figured the best way to answer that question is obviously to make a graph to query that data. So, here I have a graph that can query financial transaction information. This is a very, very lightweight graph. It's an Apollo server with no configuration at the moment, it's just a very simple Apollo server 3. And in my schema, my schema is very small, I just have one field on the root query type, which is transactions that we can query. And in my resolvers over here.
The way this graph works under the hood is we're making use of the Plaid financial transactions API. So, Plaid is a company that provides a financial transactions API as a service, and they have a REST API. And this GraphQL API is really just a very lightweight wrapper around their REST API. And we're using the Plaid node client with its Plaid API bindings to just translate our transactions resolver into a call to their API. And then down here in the mutations, I have two little mutations for getting a link token and getting an access token. And these mutations are how we facilitate authentication with this graph. So here I can come in here and I can query this server and we'll open up the Apollo sandbox and I can ask for transactions and maybe their amount and their name here. But if I run this request, I am going to get an error saying you're not authenticated because there is nothing we can do meaningfully with this graph without authenticating because it's all about financial transactions.
And so if we want to invite developers to participate in contributing to this graph, we want to give them an experience where they can come and make whatever query they want at will, but we want to make login way easier for them because we don't want them to have to come here, get a link token, go to some other website, exchange that for an auth token, come back and put it into headers, that's just a lot of work. It would be much nicer if they could have a website that they would visit that feels almost entirely like this, but also has a login button that they can just press and authenticate with right in place. So in order to do that, we're going to need to create a custom web page. We can't just use the sandbox immediately out of the box, and I'm thinking the best place for our web page is actually just to put it at the same URL as our server because then it will be pretty easy to find. So what we're going to want to do is change the default landing page of Apollo Server and put our custom page there.
5. Enhancing Log-in Button and Query IDE Experience
We can enhance the log-in button experience by combining our website and log-in button with a query IDE experience using Apollo server's public graphs feature. By making a graph public in Apollo studio and embedding it in other websites, we can provide a seamless authentication process through our website. To achieve this, we define a handle request function in Explorer's advanced config and add an authentication header using the token from local storage.
And we can do that by plugging into Apollo Server's plugin architecture. So here, Apollo Server defines a bunch of different plugins. Well, there's a whole ecosystem of plugins, but Apollo Server has a plugin API that lets you define your own plugins. And we can come back to our server, add this plugin that puts the HTML and the string in the landing page instead of the default landing page, and you can see now our server is serving that HTML.
And what we want is we want that log-in button experience, so I've pre-prepared a little bit of HTML for us, just so we don't have to write it on the spot. And in my HTML file that we've got here, I've got some helper functions at the top of our file. The only real structure to the DOM of this file is the button that we have for log-in and then a little span to show log-in context. And then down here, I have a click handler for how to facilitate authentication. So when this button is clicked, we get a link token from that mutation in our API. We open up the plaid log-in handler. And if you have a successful log-in with this log-in handler, which, please don't share my banking password, everyone. This is very, very confidential information. If we have a successful log-in with this log-in handler, then on success with that data that we get back from our mutation, we will put that auth token into local storage. So now our little website here has a Plaid token in its local storage.
And what we want to do is combine this website and this log-in button with a query IDE experience. And the way we're going to do that is we're actually going to use a new feature of Apollo server called public graphs. So you can make a server, sorry, a new feature of Apollo studio called public graphs. So you can make a new graph in studio based on a schema from anywhere. In our case we're going to make it based on a schema from introspecting our code sandbox. And if we come in here and make this graph public, then in our Explorer page, there's a setting that becomes available to us which is a setting to embed this Explorer in other websites. And so we have some options here. We want to embed a dark Explorer because we're putting it in code sandbox. Probably want to hide our docs panel because code sandbox is quite small. And then we're going to hide headers and environment variables because we want to handle off through our website so that users don't have to think about how to handle off in headers. So we're going to copy this code now, go back to our code sandbox and in our HTML file right below our buttons, we'll paste that. We will restart our sandbox, refresh our page and now we have an embedded Explorer.
But this embedded Explorer is still just an iframe that is making requests to our server from an iframe in another website. So we haven't fully solved our problem yet because what we really want to do is have our parent website make requests on behalf of the Explorer and not have Explorer make a request from the iframe. So we're going to go into Explorer's advanced config and we're going to define this handle request function inside of the Explorer config. And our handle request function here, we pretty much want the request to be sent as it otherwise would have by the Explorer, but we want to add this one header, which is the token that we're going to take out of our local storage, this authentication header.
6. Enforcing Rules and Making the Graph Approachable
By enforcing required headers and named operations, we ensure that all clients using our graph follow our rules. This allows us to identify who is using our API and how. Additionally, we explore making our graph approachable by providing a welcoming homepage and explaining the concept of public graphs.
So now if I save this, restart my sandbox, refresh my HTML page, and make this request, we should now have authenticated requests. And if we change our page's default landing query to be a little bit more interesting, like we could query instead of account owner, which is just the default field that we got, amount and name, then when we refresh this and land on that default query now and run it, we get our transactions back.
And so now any developer that comes to our little dev portal in the future will be able to log into their bank account and immediately get their transactions with pretty much a login click and a run query click. So now that our graph is super easy to query, its popularity is totally going to take off. I just know it, because everybody's going to want to know how much their bagels are costing them. And before that happens, I think we should put into place some protections so that people follow the rules of using our graph from day one.
And one of the rules that we had from our slides was that we want every request that comes to our graph to have our required headers. So in this case, let's say we want every request to have a required Apollo GraphQL client name header, because then we can plug that into our other observability. So the way we're going to accomplish that is we're going to extend the logic in this context function. So if a request does not have our Apollo GraphQL client name header, then we are going to throw a new error, all requests must be from an identified client. Now, if I run this query, we should get that error back, which we are, because our little web page here isn't identifying itself as a client yet. But over here, just like we extended our request using this handle request function with an authorization header, we can also pretty easily add in an Apollo GraphQL client name header, and just say this is our portal embedded explorer. Now if I refresh my page here and run this query, we should be good to go again. And if we were to look into our observability tools, now the requests coming from our portal embedded explorer will be identified as such.
So now that we're enforcing required headers are indeed present on our requests, another rule that we had from the slides was that all operations should also have a name attached. This one is a little bit more involved because unlike headers, which are just a property that you can pull off the request directly, operation names are embedded in the body of the operation and the body of the operation when it goes over the network and first hits our server is entirely in a stringified format. And so in order to know whether or not the operation is actually named, we have to have our server parse that operation into an abstract syntax tree and then ask at that point, does this operation have a name? So unfortunately we can't just continue to extend the logic that we have in context here, but fortunately we can make use of Apollo Server 3's plugin architecture. So down here if we come back to the Apollo server docs, and look at how the plugin request lifecycle works, there's an entire set of states here that every request goes through the Apollo server, and at any point we could kind of plug into the states and add some augmented logic. And so the first stage of the request lifecycle where the request operation has been fully parsed is the stage right after validation did start, so this would be did resolve operation. So we're going to come in here and hook into, we're going to come in here, add another plugin, and then hook into did resolve operation and its context. And all of this is inside the request did start lifecycle. So here we're going to say if there's no context.operation name, then throw a new error all operations must be named. And now if I run our operation again we should still be just fine because this operation is named, but if I delete that name and run this operation we should get an error. So we are good to go. So with just one small plugin in Apollo Server and some logic in our context function, we are now automatically enforcing that all clients who are using our graph are following our rules. And as this graph takes off and more people discover that they can use our API and learn all about their bagel transactions, we will now know exactly who is using our API and how, which is pretty amazing. And the last thing that I wanted to cover in our demo is how to make this graph truly approachable. It's one thing to give folks that are going to be developing against our graph a link to this sandbox that we made and say, have at it, figure it out, good luck. But it's another thing entirely to give someone a link to a homepage that welcomes them and tells them where to start. And I showed you all how to make a public graph in studio earlier because that's how we embedded the explorer, but I didn't really tell you what public graphs were all about.
7. Building and Customizing Public Graphs
We built public graphs in studio to make it easy for you to share your graph with users. Each graph has a customizable home page with metadata. We created a GraphQL wrapper around the Plaid REST API and added a login button to our developer portal. We can also customize the graph's appearance.
We built public graphs in studio to make it arbitrarily easy, basically turnkey for you to share your graph with your users. And every graph in studio has a home page where you can fully customize its metadata. So here I preprepared a little readme for us, so we don't have to type it out on the spot, but we can customize this readme and explain all about how this is a little GraphQL wrapper around the Plaid REST API. Because we have our developer portal with this login button that we made, we can add that as an external link. And we could even give this graph a avatar if we wanted to make it like real sharp and fancy.