 Great. Hey, everyone. My slides are available at this link, bit.ly slash graphqlcsvconf. In this talk, I really want to talk about two open source technologies that I think are each on their own really interesting, but when they're used together become sort of this superpower combination of technologies. And that is GraphQL and the Neo4j Graph Database. And so my name is Will. I work at Neo4j on the developer relations team on a team called Neo4j Labs, which works on building extensions and integrations with Neo4j and other tooling. That's my Twitter handle there. And my personal website, I write a newsletter and an occasional blog post if you're interested in digging in to more there. So these two technologies that I want to talk about, one is Neo4j, which is a graph database. So similar to other database management systems you might be familiar with, but instead of working with a table or document data model, we're working with graphs. So nodes, these are the entities in the data model and relationships connect them. We call this the property graph data model because we can store arbitrary key value pair properties on nodes and relationships. Those are the attributes in our data. With Neo4j, we use a query language called cipher, which you can think of as kind of like SQL but for graphs, which we'll take a look at some examples in a minute. And then there are lots of different use cases for graph databases in Neo4j from the transactional building a web or mobile application to things like graph analytics, graph algorithms, data visualization and these sorts of things. But fundamentally, graph databases are optimized in a different way from other databases like relational databases or document databases, graph databases are optimized for traversing the graph. So going from one node traversing to all other nodes that I'm connected to very quickly and efficiently. The other technology we're gonna talk about is GraphQL, which is an API query language that allows us to describe the type of data that's available in the API and then presents this data as a graph to the client who can then sort of arbitrarily describe a traversal through the data graph and what fields to come back. So it's important to point out that GraphQL is data layer agnostic. So while it's presenting a graph data model to the client modeling application data as a graph on the back ends, we can fetch data from really any system and we can even wrap other APIs and other databases. So these seem like two somewhat complementary technologies that they're both sort of working with graphs but in a different way. When we combine these together and we talk about building GraphQL APIs that are backed by a graph database, we have all these benefits that start to emerge. So type safety is a really important one. So I can use the GraphQL schema to define the database schema and I have sort of one unified graph data layer to think about and really have sort of graphs all the way down through the stack as I'm working with data. We were really interested early on. So GraphQL was used internally at Facebook for a while and then open sourced in 2015. And we're really interested to see if we could build some GraphQL near for J integrations to make it easier to build GraphQL APIs using a graph database and sort of some of the things we learned from that is what I'll talk about next. But really quickly, I think it would be interesting to take a look at a near for J example. So this is near for J browser which is like a query workbench for near for J and I have some data loaded. So I'm going to run query here to show our data model. So we have some data about businesses that are in categories. We have users that have written reviews of these businesses. And here's a Cypher example. So here I'm saying find a user node where the name is will. So Cypher is all about pattern matching. So we draw these sort of ASCII art representations of a graph pattern. The nodes or the parentheses are sort of defining a node and then we're saying match and return to find where this pattern exists in the graph. And so we get back this user node with the name will and I can sort of traverse through the graph to see that, oh yeah, this user wrote a review of a business in these categories, your other reviews and so on. So I can explore that data visually or I can express more complex graph patterns in Cypher. So you can see how I can string together these patterns to again, using this sort of ASCII art notation, I'm saying find a user node with an outgoing wrote relationship to a review node and then what business is that review connected to and return that piece of the graph. So here I have a sub graph based on this pattern that I've defined that I'm looking for. And this is really powerful when you start looking at questions that can be answered through a traversal through the graph. So here, this is a business recommendation query where I'm saying for this user named will find all the businesses that he reviewed, what category are they in and then find other businesses in the same categories that he hasn't already reviewed, those may be good recommendations for him. So adding some personalization by traversing the graph. So that's a quick look at Cypher just to give you an idea of what that looks like and how we work with that in Neo4j. Here's just kind of a snippet using the JavaScript driver for Neo4j. So if I'm building an application and I want to expose some of this data, I'm kind of hard coding a Cypher query here and then I have some boilerplate code for sending that off to the database and then working with the results. But exposing this data directly to an application or if I want to share some of this data, I don't want to just sort of expose my database. I want to build some sort of API layer that sits between the client, whether that's someone looking at analyzing the data or if I'm building an application. I'm building an API layer between the client and the database and this is where GraphQL comes in. So we said that GraphQL is this API query language that allows us to define the shape of the data, the schema of the data in the API and then allows the client to arbitrarily express traversals to the data graph and what data the client wants to come back at query time. So let's take a look at querying with GraphQL now. So this is a tool called GraphQL Playgrounds and this is a example GraphQL API that is out there with data on movies and actors and reviews of movies. So one thing that is really neat about GraphQL and a lot of the tooling that's built around it that's powered by this feature called introspection. So I can ask a GraphQL API to tell me what data is available in the API and explore the entry points and sort of see what fields are available. So in GraphQL, entry points for the API are their queries which are to be read operations or mutations which are typically write operations and so I can see just by this introspection feature all of the entry points, the types and how that data is connected. And then I can write queries here. So here I'm searching for movies where the title contains river runs through it and then I want the title plot and all of the actors in that movie. But I can then also express more complex queries. So also for all of these actors tell me all of the movies that they've acted in as well. And so I'm traversing the graph. If I don't want the plot field to come back, maybe that's computationally expensive to compute on the backend. I don't need it in my application or analyzing the data. I can remove that and I don't have to send that data back to the client. So that's a quick look at GraphQL. Let's take a look at a example application using GraphQL. So this is an example from a podcast application that I've been building on a live stream called grandcast.fm. That just links to the GitHub repo for this. If you want to see the code, you can find that there. And there's basically three views to this podcast application search. I want to search for podcasts by title or some keywords, something like that. A feed that is personalized for the signed-in user. So for all of the podcasts that they subscribe to, these are the most recent episodes. They can add those to a playlist, play them, whatever. And then the episode view, which is showing me details for a particular podcast and I can listen to it, add it to a playlist and so on. And each one of these views, the data comes from a GraphQL query. So we can co-locate the data fetching logic with our view and our application. So it's sort of component-based data fetching logic, which is quite nice. So each one of these views has a GraphQL query associated with it, each one of these hitting a different end points, different entry points, rather, for podcast search. I'm passing a search term for the episode feed. I have different ways to order that. And then for the episode view, I have an ID of a particular episode that I'm looking at by ID. And the data that comes back to our application in JSON and the shape of that JSON exactly matches the GraphQL query. So the fields that I have requested show up in that JSON response and I can then use that data to populate the view in my application. Now, as far as where that data comes from in this application, well, for the search endpoint, that is actually just wrapping a REST API called the podcast index. So we're actually just searching another API and just passing that data through. But for the feed view, we're looking up the current user in the database, looking at all of the podcasts they subscribe to and then finding the most recent episodes. This is the equivalent Cypher query for how we're traversing through that graph. It's somewhat similar for episode. We're looking up an episode by ID and then just traversing to the podcast node and then returning the results. This is how we might deploy that application, just pointing out here that the GraphQL layer, here we're deploying it to AWS as a Lambda function, but just pointing out that this is something that sits between the database and our client to help us load data in the application or to get data to someone analyzing the data. So based on what we've seen so far, GraphQL is really an API query language and very much not a database query language. So we have limited ability to express things that we might would want in a database query language like projections, aggregations in a graph query language, like variable length paths, this kind of thing. And we saw that while GraphQL does expose our data as a graph, we can use any other data layer to fetch data for a GraphQL API, even other APIs. So some of the advantages of GraphQL, well, we can send less data over the wire because the client is specifying exactly the fields that they're interested in. Underfetching, this means that the client can say in one request all of the data that it wants to populate the view or that it has specific need for, so we don't have to make multiple round trips to the API. And then we also saw this benefit of component-based data interactions where in our application with the podcast example, we're able to take the GraphQL queries and componentize those with the view logic in this case. There are some challenges associated with GraphQL, a lot of the well understood practices from the rest world don't really apply here. So things like HTTP status codes don't really apply. Air handling is a bit different. Caching can be problematic because our queries can be different with each request. And then there's this in plus one query problem, which because you saw that these GraphQL queries are often very nested, we can often be going back to the data source multiple times. We want to try to avoid that. These are all things that tooling and best practices have emerged to address a lot of these, but good to be aware of these challenges when you're looking at implementing GraphQL. So how do we typically build GraphQL services? Well, there's basically three steps. One is we start with what are called GraphQL type definitions. So here's an example where we are defining the types and the fields and how these types are connected. It's basically building out the graph. Then we write what are called resolver functions. And these are functions that define how we actually fetch the data from the database, from the data layer, whatever it may be. And we call these for each field in the GraphQL API. So in this example on the right, we're using sort of like an ORM type model to go back to the data layer and fetch data for each one of these fields in our GraphQL API. This is an example for like a conference website. So you can see because of these nested resolvers where this N plus one query problem comes from. And then we serve our type definitions plus resolvers and that gives us a executable schema that we can then serve as an API endpoint. But there are some common problems that come up with this. One is we're now sort of duplicating our schema in the API and the database. We have to think of this mapping translation layer in our resolvers going from graph to maybe a different model in the back end. We end up writing a lot of boilerplate code in these resolvers. And we have this N plus one query problem that we want to avoid of not going back to the database multiple times. And so these were sort of the input when we were looking at building the Neo4j GraphQL integrations. Can we build tooling that makes it easier to build these APIs? And I'm going to skip to a code example here showing how to use this library. Actually, we have right here. So basically what this library is is a JavaScript library that allows you to just write GraphQL type definitions and then that generates a GraphQL schema with all of the sort of filtering logic to entry points for the types. And then at query time, that is generating Cypher for you automatically to fetch data from the API. So basically the only code I'm writing here are my GraphQL type definitions which maps to the business reviews data we saw previously and connecting to the database. I don't have to write these resolver functions that specify how to actually fetch that data from the database, which is a huge advantage. But if you're interested in how the sort of database integrations work with GraphQL, there's an object called the ResolveInfo object that's passed to all these resolvers that has lots of information about the GraphQL schema and we essentially iterate through that to build up the database query. I'll leave the slides here that have some resources to learn more. There's a hackathon that's currently going on for building GraphQL APIs as well as an online training. I've also been working on a book talking about using these technologies together that's available in early release. This is a pre-download for the first few chapters and then I mentioned that I've been doing a lot on the live streams as well. But anyway, here's my Twitter handle and my personal website if you're interested in digging into more.