Full Stack GraphQL In The Cloud With Neo4j Aura, Next.js, & Vercel

Bookmark

In this workshop we will build and deploy a full stack GraphQL application using Next.js, Neo4j, and Vercel. Using a knowledge graph of news articles we will first build a GraphQL API using Next.js API routes and the Neo4j GraphQL Library. Next, we focus on the front-end, exploring how to use GraphQL for data fetching with a Next.js application. Lastly, we explore how to add personalization and content recommendation in our GraphQL API to serve relevant articles to our users, then deploy our application to the cloud using Vercel and Neo4j Aura.

Table of contents:
- Next.js overview and getting started with Next.js
- API Routes with Next.js & building a GraphQL API
- Using the Neo4j GraphQL Library
- Working with Apollo Client and GraphQL data fetching in Next.js
- Deploying with Vercel and Neo4j Aura



Transcription


So my name is Will, I work for a company called Neo4j, which is a graph database. We will go into a lot more detail about Neo4j in a little bit here, best way to get in touch with me probably on the Twitter, it's my Twitter handle, www.lionwj.com or my personal site, I publish a blog and a newsletter as well. I also co-host the graphstuff.fm podcast, so if you like the podcast format and if you are interested in graph technology, you might want to check out that podcast, you try to have some fun with it and learn things about graph technology. So here's kind of the rough outline for today. So the goal of today is to build a full stack application, including building the graphql server, working with the database, building a next.js react application that queries our graphql api, and then we're going to deploy that to the cloud with Versel. So we'll be using Neo4j AuraDB. So we said that Neo4j is a graph database, Neo4j Aura and AuraDB is like a hosted Neo4j in the cloud. So it allows us to spin up Neo4j instances in the cloud that are private to us. We're going to use the free tier of Neo4j Aura, so we don't need to have a credit card or incur any fees or anything like that. We will be using GitHub, so we should have a GitHub account, and then we'll be using Versel to deploy our application. Versel also has a free tier, so we just need to create a Versel account. So we're going to start off talking about Neo4j and getting started with Neo4j AuraDB. So we're going to work with some data about news articles. So we're going to build a full stack news article application using graphql and next.js. We're not going to focus so much on front end design. We're mostly going to focus on how the pieces fit together. So don't be a little disappointed when you see there's not a whole lot of design or sophistication in our front end application, but we will cover how to handle data fetching with graphql in a react app, and specifically with next.js. Cool, so that's kind of the order we're going to go in, starting with Neo4j. So we're going to start off with Neo4j Aura. We'll import some data on news articles. We'll see how to use the query language called Cypher to work with the data, including things like can we recommend similar articles, this sort of thing, recommendation, personalization queries. Then we're going to see how to build graphql APIs backed by Neo4j. So we're going to build a graphql api using the Neo4j graphql library, which is a node.js library. We will see how to actually run our graphql server in next.js. So for next.js, we're going to use next.js both for the backend, the api routes functionality, and then also for the front end react application. Then we will deploy our application to Vercell. So both the front-end react app and our graphql api will be deployed as serverless functions. Cool, so let's get started. I do want this to be as interactive and as hands-on as we can. So as we go through this, if you have questions and comments, drop it in the chat, and I'll definitely address those as we move along. You'll also see this hands-on exercise icon. So definitely want this to be hands-on. So there will be, oh, I think we have five or six sort of hands-on exercise segments where we're going to work through some exercises together as we build up our application. We're not going to start from scratch. We'll have some starting code to help us along. But yeah, try to make this as hands-on as possible. So definitely ask questions in the chat. Let us know how things are going. And when you see this hands-on exercise icon in the slides, that means we're going to spend a few minutes working on something together. Great. So to get started, let's talk a bit about Neo4j and Neo4j AuraDB. I guess we should also talk about the time here. So this is scheduled, I think, as a three-hour workshop. We haven't done this one before. This is kind of new. So we will play it by ear. I think three hours will probably be good. But we certainly won't go over. Not sure if we'll finish early. So a question from Mohammed in the chat. Is this training session continuous to the previous one? Yeah, good question. So was that last week? Yeah, last week I did a workshop focused on building graphql APIs with the Neo4j graphql library. So if you took that session, there'll be some similar concepts that we'll transfer. In that workshop, we spent sort of three hours going deep on the features of just using the Neo4j graphql library to build a graphql api, and we just kind of left it at that. We didn't really see how does that fit into the context of deploying our application, a front-end application. How do we use cloud services with that? So today, the focus is really on how these different pieces fit together for building a full stack application. So we're going to use a different data set. In that one last week, we built a graphql api for an online bookstore. Today, we're focusing on a different data set with real-world data of news articles in a graph. So if you took the workshop last week, most of this will be new. There'll be, again, a little bit of overlap in the concepts, but I think it should be worthwhile. Hopefully, that answers your question. Cool. So let's talk about Neo4j Aura. So first of all, what is Neo4j? Well, we said that's a graph database. You may be familiar with relational databases or document databases, where in a relational database, the data model that we're working with is tables. In a document database, we have collections of documents, like JSON documents. In a graph database, we have graphs that we work with. So in a graph, nodes, these are the entities, relationships, connect them, and we can store arbitrary key value pair properties on nodes or relationships. Those are the attributes. In Neo4j, we use a query language called Cypher to work with the data, both for creating and querying the data. So if you're familiar with SQL or you've heard of SQL, you can think of Cypher as kind of like SQL, but designed for graphs. So in this example on the upper right here, that is a Cypher query that is searching for addresses in New York and then looking for people connected to offshore companies in New York. This query comes from the Panama Papers or Pandora Papers data sets that is an investigative journalist data set looking at offshore corporations. The group that did that investigation used Neo4j to make sense of very nested, structured data of offshore corporations and people connected to them. So I think that's a good example that kind of ties things to a real world use case. But there are lots of interesting things we can do with graphs and with graph databases. We're going to focus on more of the building an application, kind of like operational transactional use cases. But there are lots of interesting things as well that we can do with graph analytics, like graph algorithms, graph data science, or data visualization as a graph. But we'll be using the graphql integration for helping to build that api layer today. So really, I think of Neo4j as kind of the core piece of this graph platform where you the database gives us the ability to model, store, query our data as a graph. And then there's lots of tooling and different integrations depending on what we're working on. So on kind of the right side of the spectrum is more of the analytics, data science things where I'm interested in things like graph data science, graph algorithms, graph visualization. And then what we're focusing on today is more on the left side where we're more focused on today is more on the left side where we're more interested in operational transactional use cases. I want to build an api layer for my news application or I want to build the api layer for an e-commerce site, things like this. So, okay, great. Here's our first hands-on exercise of the day. We are all going to sign in to Neo4j Aura and create a new AuraDB instance that is private to ourselves. So let me drop the link to the Neo4j Aura in the chat. There's the link. Drop the link in Discord. So what we're going to do is go to that link and sign in for Neo4j Aura and create a new AuraDB free instance. When you do that, you'll be presented with a random password. Be sure to copy that password, save it somewhere. We will use that pretty much immediately. This is kind of what the flow looks like. I'll go through this in a minute. Basically, once you sign in, you'll see this screen where you are prompted to create a database, either free or professional. We want the free tier for the workshop today. You'll give it a name. You can choose a region. I just usually select whatever region comes up first. There's a few different. You can also select whatever is closest to you. And then you have two options to start with an existing data set about movies or to start with a blank database. We want to start with a blank database. This is where you'll see the password. This is randomly generated. You can change this later. You'll see this, save it somewhere, because we'll use that in the next step when we go to start using Neo4j browser for writing queries. You'll see in the Aura console, we're starting your database. It'll take a couple minutes to spin up. Then when you see this green running, then you'll see also this URI, this connection string for your Neo4j Aura instance. We'll want to copy that. We'll use this later on for our graphql api to connect to our Neo4j Aura instance. I'm going to go do that now. You can see that there's different tiers for AuraDB. We want the free tier. It's limited in the size of the data, but it's perfectly fine for hobby projects or workshops like this. And you have a link to the free tier. You can also use the link to the free tier. You can also use the link to the free tier. If you're working with hobby projects or workshops like this, you have a real world application that you're ready to deploy. That's where the professional tier comes in. Or if you're a huge company, enterprise can have lots of custom things. Okay. I'm going to sign in to Neo4j Aura. Oh, it looks like I was already signed in. When you sign in, you can sign in either with GitHub or create an account via email if you haven't done that already. I'm going to click create a database for IDB free. Let's call this graphql Galaxy Workshop. And I'm just going to leave the region as Singapore. Sure, why not? Well, no, I will select one near me. Let's go with Iowa. Load or create your own data. I don't want the movies data set. I want to create my own data. I'm going to select this one. And we don't need to update that. Thank you. Create database. Here's my password. I'm going to copy that. Save it somewhere where I won't lose it. Yes, I have saved that. And here we'll see, okay, now we're setting up my database. It'll take a few minutes to do that. Cool. So when you get to the screen, you should be good for now. So let's pause. I'll go back to this slide. And let's pause for just a couple of minutes to give everyone a chance to create a Neo4j or a DB instance. If you did the workshop from last week, you can use the same database. That's fine. Or you can destroy that one and create a new one. Doesn't really matter. But yeah, let's pause just a couple of minutes and then we'll move on. If you get stuck with anything or have any issues, just give a shout in the chat. Thanks for watching. Okay. Okay, did everyone get their or a DB instance spun up or at least get to the gray screen that says it is in the process of starting up? Basically, you want to see something like this. Cool. Let's move on. But if you did, if you had an error or if anything isn't working, definitely, definitely let us know in the chat and we'll get it figured out. But let's talk a little bit about graphs and the data sets that we're going to work with today while we're waiting for our Neo4j or instance to spin up. So we said earlier that the data model that we work with in Neo4j is a graph. So nodes, these are the entities, relationships, connect nodes. In Neo4j, we use a specific data model called a property graph or also sometimes called the labeled property graph. So in the property graph, we have labels, first of all, that define like the type or grouping of a node. So in this case, we have the label node on all of our nodes, which is not very helpful. And then our relationships have a type and direction. And then we can store arbitrary key value pair properties. That's where the property in property graph comes from. You may have heard the term knowledge graph in the context of property graphs. I think knowledge graphs are really interesting because they help us put things in context is kind of how I like to think about it. So we're talking about things. So these are the nodes or entities. And we know what kind of things they are. So in this example, we have some data from New York Times articles. So we have article nodes. We have the title in the URL stored as properties on those nodes. And then the articles are connected to topic nodes. So here's an article about the infrastructure bill in the U.S. It has the topic United States politics and government that's connected with this has topic relationship. This article has multiple topics, also about the U.S. economy. We can see other articles connected to the same topic. So this is the idea of a knowledge graph where we we're working with things and we know the type of the things. You got an article, a topic, a person, and we know the context of the thing. So what other things our article is connected to? That's that's basically what a knowledge graph is. When Google announced their knowledge graph api in 2012, I think it was. They published this blog post called Things Not Strings, just talking about the idea of a knowledge graph, which I think is a really good summary of what we're talking about when we talk about knowledge graphs. So those may be some terms that you've heard in the context of graphs and graph databases. We're going to be working with graphql shortly here. I think it's worth mentioning that in graphql, we are also working with a graph. We have we have types and objects and fields that connect other types and objects in the graphql type system. So this is where the graph and graphql comes in. I think these data models, the property graph and the data model that we use in graphql, as you'll see in a little bit, are very, very similar. And when we're building full stack applications, it can really help to be working with graphs sort of throughout the stack from the front end to the back end. I use this this news article example because that is the type of data we're going to be working with today. So I pulled down from the New York Times api this morning, It's either 25, I think, or so or maybe 50 or so of the most viewed articles for the last the last week or something like that. So we're going to work with that data set. And this is the graph model that we're going to work with. So we'll have article nodes. Those are going to be connected to topics or organization or person that the article is about or mentions. We also have geo regions or what geographic areas is this article about. And then we also have things like the author, the photo. This diagram has comments in here. I don't think we'll work with user comments today, but you can see how we would model comments on an article and comment threads, that sort of thing. The code for this is online on GitHub linked there. We're going to be working with a separate repo, but this GitHub repo has some code for loading this data set from the New York Times api to grab it directly from the New York Times api. You'll need an api key, but I don't need to worry about that today because I just grabbed a slice for today. data that we'll work with. But this repo has some interesting things like working with this data in cloudflare workers or a couple of different ways of building graphql APIs. Okay, so that's the data we're going to look at today. What we're going to do now is switch to Neo4j browser. So Neo4j browser is like a query workbench for working with Neo4j. So it allows us to write these Cypher queries, visualize the results, and work with data. So it's kind of the main development environment testing and development that we use when we are working with Neo4j. So we access Neo4j browser from within the Neo4j Aura console. So you should see this open with button. You click that and you have two options. Neo4j browser, which is the query workbench for Neo4j that we're going to use or Neo4j Bloom, which is more of a visual exploration tool. When we do that, we'll be prompted for our password. So that's the random password that was generated. So we want to grab that from wherever we saved it. And then we're going to run this command colon play news graph in Neo4j browser once we're signed in. And we should see something that looks like this kind of down at the bottom. This will bring in what's called a browser guide that has kind of like a carousel of text and embedded Cypher queries that we can click on to kind of go through our next piece of the workshop. So I'm going to go ahead and switch to Neo4j Aura. And run this command to bring up the browser guide and then we'll pause for a few minutes to give everyone a chance. It looks like my Aura instance is still spinning up. So we will have to wait a couple of moments for that. I think this is taking longer because I changed the region. I think what it does is it gives you a region by default. Maybe that has more allocation available to it. So if your instance is spun up, let us know in the chat actually how many folks have a green mark here that says running. If you have that, go ahead and open up Neo4j browser. If not, we'll just wait a few minutes. Antoine says, yeah, his is still in progress. Okay. Paul says the same. Okay, so we'll we will just wait a few minutes. That is fine. Gabriel says still waiting. Okay. Yeah, that's cool. We'll give it a few more minutes to spin up. That is fine. In the meantime, if anyone has any questions, feel free to let us know. Let us know in the chat if you have any questions and we can dive into those. I do have a Neo4j instance with this data loaded. Maybe we'll take a look at that. Cool. So this is Neo4j browser. I'm just going to demonstrate what this looks like here. And then when our Aura instance is ready, we'll switch back to Aura. So this is the Neo4j browser. You basically have a Cypher editor here. So we write Cypher queries here and then we get a frame. So one of these panes for each query that we write. So here I wrote a query that says match in parentheses. So with Cypher, what we do is create graph patterns using this sort of ASCII art-like notation. So the match command is saying go find some data that exists in the graph based on this pattern. And we're going to define some graph pattern. So the most basic graph pattern we can define is think of it as a bare node pattern, I guess, where we draw this sort of ASCII art representation of a node, which is like open and closed parentheses. And then this in inside that parentheses, that becomes a variable that is bound to that piece of the graph patterns, in this case node, that we can then refer to later. So the first thing we do is we match on every node in the database. That's the simplest pattern we can. And these nodes then that match get bound to the variable in. And then we can refer to that later on in our query. And we want to return an aggregation that is a count of the number of nodes in the database. So this data set that I'm looking at has 16,000 nodes. We can create more specific patterns. Here we're adding the label. So this colon article after the in, this is saying find nodes that have the label article. So we said labels are kind of like a way to group nodes in graphql terms. Think of this as a type. So when we start working with graphql, we'll see how we can map graphql types to node labels. So if we run this again, we have 4,500 article nodes. Let's look at the data model that we have. So DB schema visualization. And let's clear out the styles here. There we go. It's a bit more legible. So this is sort of the meta model that we're working with. So we have article nodes that are connected to topics, person, geo, organization, and photo. So this is exactly matching the slides here. This diagram that we looked at earlier. So this is kind of the end result of what we're going to be working with. But using this information, let's see how we can create a bit more complex patterns. So first of all, we have 4,000 articles. I can't just return all of the articles. Let's return in about limit 10. So here are some article nodes. We can click on these to view the properties. So here we're viewing the key value pair properties that we're storing on our nodes. I can double click on these to traverse out the graph. I can see this is about a lunar eclipse. And I can see the topics, eclipses, moon, earth, space, and astronomy, and then a photo. If I want to see what are other space and astronomy nodes, I can double click again. And we do another traverse out. So I can traverse the graph visually this way. But Neo4j browser is really built for writing Cypher queries and working with the results. So rather than exploring visually, if you want to explore visually, that's where we would use Neo4j Bloom. Let's add a more complex pattern to this. So let's say for these 10 articles, let's also see the topics connected to the articles. And we'll return and set them just in. Let's return star, which will return any variables that we match on. So now we've defined a little bit of a traversal in our graph. So we're searching for not just articles, but now we're drawing this sort of ASCII art representation of a relationship. So this kind of looks like an arrow that we've drawn here. And these brackets indicate the relationship where I can specify the relationship type. So I want to follow the has topic relationship coming out of our article nodes to these other topic nodes. And then I'm going to return 10 of those paths. Let's return, let's say, 25 so we can get a little bit more visual representation. So here's a bunch of articles about exercise. We can change this also to order by in the published. So now we should get the most recent when we get the oldest in by published in descending order. By default, we get ascending order. So we want the most recent articles and their topics. And what's nice about Cypher is if the answer to our question is a more complex traversal through the graph, we just add a more complex graph pattern. So now if I want to say, OK, for all of these topics for today's articles, what are other articles that have those same topics? We just add that piece to our pattern. So now we're starting with most recent articles ordered by published date in descending order first out to the topics of those articles. And then find other articles that are connected to those same topics. And let's make this let's do get a few more pads here. So 300. There we go. And ends up with lots of things about coronavirus and vaccine and so on. Because there are lots of articles about those two topics in our data set. OK, so that's a little look at Cypher. Let's switch back to Neo4j Aura. Still looks like we're still loading here in Aura. Okie doke. Let's keep looking at Cypher then. By the way, if you want to follow along, this database is public. There's the URL for it. I'll drop that in the chat. And there's a read-only user, which is NewsGraph. And the password is just NewsGraph. So you can open that up if you want to follow along. We have talked about Cypher writing graph patterns. We also have some more complex patterns that we can work with, such as the variable length path operator. Let me bring up the Cypher ref card. This is a helpful reference. So this is the Cypher ref card, which has lots of different information about Cypher, different commands and examples. So there's lots of functionality here for working with Cypher. One thing I want to take a look at is variable length paths. We have an example here. Yeah, here we go. Variable length path. So this variable length path operator is really, really powerful for working with graph data. Basically, what this means is it allows us to specify a variable number of relationships to follow when we, maybe we are interested in a node that's connected to another node, but we don't know if that's one hop away or five or 10 or 20. So what we can do is just include this asterisk in the pattern here. And that means find, in this case, n and m. So find a connection between n and m by following any number of paths. And we typically want to specify an upper and a lower bound. We don't typically just want to keep traversing the graph. At Nausium, typically we have some upper boundary that we're interested in. So we can set that as well. So this is really powerful. When we combine this with another super powerful function in Cypher, which is the shortest path function. So oftentimes I'm interested in the path from one node to another, following a variable number of relationships. But I'm not interested in like the longest path often or just like one of many. Often I want the shortest path. So the shortest path path function, we'll take a pattern with a variable length operator in it and we'll do what's called a binary breadth first search. So find the two endpoints and then kind of iterate through the graph to find the shortest path connecting these two nodes. And this is useful for all kinds of different use cases, things like logistics and routing. Also things like in social networks or even in knowledge graphs where I'm interested in two topics and maybe I want to recommend in our case like articles that are sort of intermediate topics to our data set. So let's take a look at an example of using variable length path operator. So I'm going to say match. Now here I'm going to use a slightly different syntax where instead of where the variable is defined sort of inline in the pattern, I'm defining it out here. And this is because what I'm going to work with is a path rather than just a piece of a pattern. But I'm interested in the shortest path. Let me close some of these frames to get out of our way here. So I'm interested in shortest path. Shift enter will get you a new line if you want multiple lines in here. The shortest path from how about the shortest path from cheese. I was looking at this one earlier. Cheese to TikTok. So here I'm defining a node pattern. So looking for topic node and then these curly braces. That's how we indicate properties. So this says match on the node that has the label topic where the value cheese for the key name. And then I think we have TikTok in here as we did this earlier. I think it's TikTok. And then it's parent company fight dance, something like that. And then return. So this is going to traverse the graph to find the shortest path from cheese to TikTok. And it ends up being kind of a short path. So here's an article about cream cheese shortage in New York. That also has the topic quarantine. There's another article here about social media influencers, which, of course, is connected to TikTok. I can double click on these to sort of expand out any other sort of intermediate nodes that are connected. Okay, cool. So that hopefully gives you some idea of the power of cipher that we can use with Neo4j. Let's check in in our Aura instance. If it's not done yet, we might just go ahead and move on. I'm assuming everyone else is still says waiting to spin up. Aura must be having a slow day today. All right, well, let's go ahead and move on since we don't want to spend all of our time just waiting for our Aura instance to be ready. That's fine. We can just use this news.graph.zone database. That is fine. So that kind of covers the first module about Neo4j. Any questions that folks have, definitely let us know in the chat. You can also in Zoom, you can raise your hand if you want to speak to ask a question. Go ahead and do that. If you have a question about Neo4j, just click the raise hand and then it'll send me alerts and we can get your question that way if you don't want to put it in the chat. But chat is fine as well. Cool. So let's move on. We will come back to our Aura instance once they'll finally spin up. Usually it just takes a minute or two. I'm not sure what's going on today. Let's talk about building graphql APIs. So we have our data in Neo4j, this data set of news articles. We saw how to query that with Cypher in Neo4j Aura. Oftentimes, you know, when we're building an application though, we don't want to just expose our database publicly to our client applications. We want to have this api layer that sits between the client and the database where we can control things like authorization, custom logic, these sorts of things, controlling what pieces of our data we're actually exposing, how we want to represent that data to the client. And this is the common architecture. graphql makes a lot of sense for working with graph data like data in Neo4j because, as we said earlier, the property graph data model and the data model we work with in graphql are very similar. So let's talk about how we would build graphql APIs with Neo4j. So we're at the point now we have our data in the database. We know we want to build this application. We want to build this api layer as the next step. So how do we do this? Let's talk a little bit about graphql. I know I think most folks said they had some familiarity with graphql, but let's talk just a little bit about graphql at a higher general level before we move on. So we're all sort of on the same page. So graphql is a query language for APIs. We have a strict type system with graphql. So we define the data available in the api, including what entities and attributes exist in the data and how those types are connected. So that's the graph piece of graphql, or that we can have fields that reference other types in our schema. So our type definitions, these are an important concept in graphql. They define the data available in our api, right? So we have types and we have fields of the type. We typically use the schema definition language to create our type definitions. We can create these programmatically using whatever graphql implementation we're working with, but I think SDL, the schema definition language, is really a great language agnostic way to do this. That means our type definitions can transfer between graphql implementations. It's not dependent on whatever language we're writing our api in. So a graphql operation is either a query mutation or a subscription that specifies an entry point. So the entry points are either a field on the query type, the mutation type, or the subscription type. And then we have optional arguments that we can pass as well. So here, we're looking for movies where the title is a river runs through it. And then we specify a selection set. So the selection set can think of as a traversal through the data graph. So the selection set is this nested structure that can also take arguments for the nested fields. And we're also specifying the selection set, the data to be returned. So the selection set defines the shape of the data that comes back. So here's the response to this graphql query. We're searching for the movie a river runs through it, and the title, the actors connected to the movie, the directors, and then for directors also the movies that other movies that those directors also directed. So who directed a river runs through it? What other movies did they direct? The selection set defines not only the traversal through the graph to fetch that data, but then also the shape of the data to be returned that exactly matches our selection set. So those concepts are, how do we write graphql queries or graphql operations? What about implementing a graphql api in the back end? What does that look like? Well, typically that involves creating our graphql type definitions that we talked about, and then implementing what are called resolver functions. So resolver functions, these are functions that define the actual logic for going out to the data layer to fetch data from a database or query another api, whatever it may be. graphql is data layer agnostic, so we can really build a graphql api on top of really any data source. In this example, this comes from a graphql api for conference data. So we have conference sessions, sessions are in a room, sessions have a theme, and then we have recommended sessions that are other sessions that you may be interested in, like if you enjoyed this session. And each one of these resolver functions, so this is called a resolver map, because this is a javascript object of functions, so you can see we have query.session as a resolver function, session.room as a function. And in each of these functions, what we're doing is going out to kind of a fictitious database using this kind of ORM syntax to first of all search for sessions by some search terms. So imagine we're on the conference website and we're searching for, show me all the graphql sessions. So we're going to the database once to find all sessions that have like graphql in the title or whatever. And then if we ask for room, well now we're calling this resolver function to now go back to the database. And for all the sessions that match graphql, now tell me the room that those sessions are in, that comes back, and then do the same thing for theme and do the same thing for recommended so you can see because of the nested way that these resolver functions are called, we can often end up making multiple round trip requests to the data layer, to the database for each of our selections essentially in our nested selection set. So this is what's called the N plus one query problem, where we end up making multiple round trip requests to the data layer, and this has performance problems because each of those round trip requests to the data layer incurs some some overhead to be much more efficient So we just make one request to the data layer and all of our data comes back. So the N plus one query problem. This is something that if you've built graphql APIs before that you will run into, there are a few different ways to address this one is called the data loader pattern, where we can cache and batch data so that, first of all, we figure out, okay, what are all of the queries that we're going to send to the database and then we kind of send them all at once. Or we can use database integrations that generates a single database query from the root resolver based on our graphql request. And that's what we're going to do today with the Neo4j graphql library, which will do two things related to resolvers. The first one is, first of all, it will auto generate all of our resolver functions for us so we don't have to write any of this kind of boilerplate data fetching logic, but also, and equally as importantly, I guess it will generate a single database query from the root solver. So that takes care of the N plus one query problem, it sends a single database query to the database, the database can then figure out how to optimize that request. Okay, so that's graphql resolvers. In general, I think this idea of over fetching and under fetching is important where we're sending exactly the data that the client has asked for nothing more, nothing less, and the client is able to construct a query that says, give me all the data that I need to render this view. So the client does not have to make multiple requests to the api layer, it's a single api request to fetch all the data that the client needs. I think that's really one of the key benefits when working with graphql. Of course there's lots of challenges that come up when working with graphql, we talked about the N plus one query problem, but also I think in general, one of the main sort of categories of challenges is that a lot of the well understood practices from REST don't apply in graphql. So things like HTTP status codes, error handling, caching, those things are all handled a bit differently. There's tooling and best practices to address all of these, but these are some things to be aware of. We are going to use graphql Playground today to query our graphql api. Playground has been deprecated, so you will probably see less and less of it going forward. Instead you'll see things like GraphiQL or apollo Studio has a, is it called Explorer, I think is the function in apollo or the feature in apollo Server, apollo Studio rather. But it's all similar tooling, basically tooling that enables us to query a graphql api from within the browser, taking advantage of a feature of graphql called introspection. So we can introspect a graphql api that says, hey, tell me the types, the data available in this api, that's introspection. Once we have that, we can then build tooling that gives us say like documentation of the api, what are all the entry points, what are all the types of the api, or tooling like autocomplete. As I'm writing my query, I can get autocomplete because I know what fields are available, the types of those fields, and so on. So we're going to use graphql Playground today. So to get familiar with graphql Playground and also with the api that we're going to be building, let's take a look at an example. So let's go ahead and open this URL in a browser, and I'll drop a link to this in the chat. So news-graph.barcel.app slash api slash graphql. So that will open graphql Playground. And what we want to do is spend a couple of minutes just familiarizing ourselves with the structure of this api and also with graphql Playground if we haven't used it before. There's a couple of queries here. I'll copy paste these in Discord. Maybe that's easiest. So if you're in Discord in our channel, here's the first query, and here's the second one. Otherwise, if you have the slides up, you can just kind of copy and paste these, but just give these a run in graphql Playground. Take a look at the Docs tab to see what data is available. Play around with the control space autocompletes to see, for example, in articles. Can you also include topics? Can you also include things like the geo region and so on? So let's spend a few minutes working with this. This graphql api is querying that same database in Neo4j that we looked at earlier. So if we look in the Docs tab, we can see we have articles. We also have count and aggregates. We can also do aggregations. We can look for articles, authors, topics, and so on. So here we're looking for, let me make this a little bigger, for topics where the name is movie. So topic movies, and then what are all of the articles connected to the topic movies. And we can see things that we can do, for example, just show me 10 articles. We can also grab the URL, the published date. Maybe we want to know organizations that are mentioned or other topics for each one of these. So let's just spend a few minutes querying this api, give us some ideas of what kind of data we are working with. So again, I dropped a link to that in the chat and some of the example queries. I'll bring that back on the screen. But let's pause for just a couple of minutes to give folks a chance to write some graphql queries. And this is the exact api and data that we're going to build the graphql api for in the next step. So in the next step, we'll see how do we create the code for this api. So I'll pause for just a couple of minutes and again, ask any questions or issues that you have in the chat. Just let us know. Okay, did everyone have a chance to write some graphql queries? Anyone uncover anything interesting or an interesting graphql query or this api? If you did, feel free to let us know in the chat. Cool. So that gets familiar with graphql playgrounds and writing graphql queries and the api that we're going to build. So let's see how we can implement this api using the Neo4j graphql library. So we talked about kind of the basic approach of building a graphql api where we define our type definitions and we define our resolver functions for how to fetch data. And I mentioned this idea of this N plus one query problem and writing a lot of boilerplate resolvers and some tooling that addresses some of those issues are database integrations that make it easier to build graphql APIs backed by certain databases. So we are working with Neo4j. So we'll be using the Neo4j graphql library. So this is a node.js javascript library that we can use with really any javascript graphql implementation. We will be looking at some examples. So let's talk about some goals of the Neo4j graphql library. Well, the first one is this idea of graphql first development where we want to take our graphql type definitions. So we start there, we define the types, how the fields available on the types, how that data is connected. And then that drives the data model in the database. So we don't need to maintain multiple schemas for the api, for the database. Instead, our graphql type definitions define everything. So before we move on, I see a good question in the chat from our previous exercise. So let's switch back to Playground. So AC is asking, can we catch errors during query creation time instead of only knowing after running them? Field topics must have a selection of subfields. Yeah, this is a good one. So for example, so you might get this error. Let's say, let's just look at some articles. Here we've got 10 articles. Bring in title and URL. And if we look in the docs for articles, we can see that, okay, yep, we've got topics connected to the article. So let's grab topics. So we can add topics here. But if we run this, we get an error, and I think this is the error that the AC posted in Discord, that we'd have a selection of subfields. Did you mean topics? graphql validation failed. graphql validation failed. And yeah, so what this this error is saying is that topics, this is a object array field. So this is like a reference to topic nodes in the graph. And I can't just return these topic objects. I need to, in my selection set, define which fields I specifically want to return. That's sort of the way that the graphql selection set works, is that I have to define my selection set the scalars that I want to return for any object field. So AC's question was, how do I know that there's an error here before I actually send the query to the server? And one thing in graphql Playground will give us this, if you can see it here, but there's a small red line here on line five, that's indicating there's some syntax error. If I highlight over that line in graphql Playground, I can see this is telling me the client-side error, so I can see this before I send it. And this is this idea of introspection, where graphql Playground knows this is an object field, so it's giving me the error here and telling me that, well, I need to add a scalar selection in graphql Playground. AC says he doesn't have the red indicator. Okay, that's not good. That's one way, I guess, is just in graphql Playground and other tooling as well. If we're in VS Code and we are writing code, which we'll jump to working with code in a minute here, and we're writing code, if we have the graphql extension installed and it's pointed at our api, it can introspect the api and know that, oh, this is an object field, it needs to have a sub-selection. So AC, you posted that screenshot. What if you remove the name selection under topics? So you just leave, it just says title URL and topics. Do you have the red squiggle then, if you remove name? Okay, cool. Yeah, so we see it there. Yeah, so this, we fixed our syntax error and the squiggles appear. Yeah, so that's the client-side sort of query validation process happening there. Cool. Yeah, so that's a super helpful feature is being able to introspect the api and use that, use those types in tooling, both things like graphql Playground and then also other developer tooling. Cool. So we're talking about the Neo4j graphql library and talking about building this api layer that sits between the client and the database. What we are talking about now are the goals of the Neo4j graphql library. So we said this idea of graphql first development, where we define our types, our graphql type definitions, and that drives the data model in the database. Once we define our types and hand those off to the Neo4j graphql library, the Neo4j graphql library will generate graphql api operations. So specifically, it will generate the query and mutation types with entry points for by default, every field, every type in the schema. And add things like ordering, pagination, filtering, aggregations, these sorts of things. So we don't have to define all of those. Those are just generated based on the types. Then at query time, the Neo4j graphql library is going to take a graphql request and translate that to a single Cypher query. So we saw some examples of Cypher earlier where we were drawing traversal, drawing like ASCII art representations of traversals through the graph. You can think of that as kind of mapping to like a nested selection set. A nested selection set is also defining a traversal through the graph. So by generating a single database query, this means that we're getting rid of that n plus one query problem where we might make multiple round trips to the database. And instead, we send a single Cypher query. The database figures out how to optimize that and go from there. So, so far, the features we've talked about have been kind of like CRUD functionality. So we get create, read, update, and delete operations for every type we define basically without writing any additional code. But what about if we have custom logic? So let's say, for example, we want to generate personalized recommendations. Well, to do that, we can use what I think is my favorite and probably the most powerful feature of the Neo4j graphql library, and that is the Cypher graphql schema directive. So graphql schema directives, these are like annotations in our type definitions that indicate that there is some custom logic that should happen on the server. So schema directives are graphql's built-in extension mechanism. The Cypher graphql schema directive allows us to basically attach a Cypher statement to a field in graphql to define some custom logic. So in this case, this example, we have a recommended field where we are returning recommended businesses. So for example, we may do that by traversing user reviews. So this comes from a data set where we have user reviews of businesses. So we can say, for the currently resolved business, that's where this keyword comes in. For the currently resolved business, find all the users who wrote a review of this business, and then what other businesses are those users reviewing? That might be a good recommendation. So if you like this business, what are other businesses that you like? That's an example of what's called a collaborative filtering graph traversal. We can basically use this Cypher schema directive feature to attach custom logic defined using any functionality that we can define in Cypher. So super powerful. We don't have to write our own resolvers in that Cypher query that we attach to our schema. We don't have to write our own resolvers in that Cypher query that we attach to our schema that gets attached to the generated, the single generated database query. So we're still just sending one query to the database. So let's take a look at kind of a quick start example. You don't need to follow along, we're going to clone a repo in a moment. But just to give you an idea of what building a graphql api with the Neo4j graphql library looks like. So here we're installing some dependencies, the Neo4j graphql library, the graphql javascript reference implementation, the Neo4j driver, this allows us to create a connection to our database, and then apollo server, which is a really great graphql server for node.js. There are others that we could use with Neo4j graphql library, but apollo server is nice because we just kind of hand off executable schema object. So here's sort of the minimum viable snippet. Let's go through this in a couple of chunks at a time. So first we're pulling in our dependencies, so the Neo4j graphql library, the Neo4j javascript driver, and apollo server. And then we are defining our graphql type definitions. So here we have pretty simple type definitions, movies and genres are our two types. And then on these relationship fields, we see that movie has genres. So genres and movies are connected, we've added this relationship schema directive. So earlier we were saying that the property graph model that we use with Neo4j is very similar to the data model that we work with in graphql. So the Neo4j graphql library is mapping types to node labels and fields to properties. So that's a pretty much one to one mapping. However, in a property graph data model, every relationship has a type and a direction. And in graphql, our relationships don't have direction. So we need to encode that information to be able to drive the property graph model in Neo4j from our graphql type definition. So that's why we use the relationship schema directive to define the direction for the relationship in the database. So in this case, we're saying that the genres field on movies in the database that follows the in genre relationship with the out directions are going from movie to genre. So the next thing we're doing is creating a connection to our database using our connection string for the database, in this case username and password. And then we take the type definitions that we wrote earlier, and this Neo4j driver instance, we pass that to the constructor of the Neo4j graphql class this comes from our Neo4j graphql library. And then that gives us a executable graphql schema that we pass to apollo server that can then handle the networking aspect of our graphql api. So note that we didn't write any graphql resolver functions, we didn't write any like boilerplate code that specifies how to fetch data from the database, all of that was handled for us by the Neo4j graphql library. So that was all in a single file if you run that we would see graphql playground running locally. So now we can query our api. So this is an example from a books api that's pretty similar to the articles api that we were just looking at in graphql playground because the generated api is both generated using the Neo4j graphql library so the filters, the query entry points, and so on. So I'm going to go through this a little bit quickly, but I do want to touch on some of these concepts. And then we will start writing some code. So by default, every type has a create read update and delete operation generated as a field on the query and mutation type that maps to node labels in the database. And of course we can construct arbitrarily complex graphql queries and those are translated to cipher queries and sent to the database for us. Okay, we've seen some examples of this already for sorting and pagination we have this options argument in our query fields that allow us to do sorting limiting offset for pagination. We can also do cursor based pagination using relay style connection types. So you'll notice that for our relationship fields you'll also see the name of the field connection, and those map to relay style connection types that support cursor based pagination. For filtering, we saw an example of this, where we were filtering for a movie by title. The inputs generated here depend on the type of the field so for numeric fields are greater than less than equals that sort of thing for string fields we have the string comparison operations like starts with ends with contains those sorts of things. We can do nested filtering and sorting as well so that where arguments can be applied at the root and also nested in the selection set but just note that the filtering is applied at the level in the selection set where we use it. So here this in this example we're searching for books with a price of less than $20. And then for all of those books, reviews that were created after January 1 2021. We're not saying only show me books that are less than $20 in price and have reviews that were created after this date. So we may not see any reviews and for filtering, because the filter is applied at the level in the selection set where we, where we use that argument. We can work with geo data I don't think we have point geo data that we work with today but we can use filters. If we have points latitude and longitude data. So here's an example so I said, just a minute ago that the filters are applied at the level in the selection set where I use them in the argument so for example, if we want to filter through a relationship so here in the book example we were looking at we had orders, address nodes that are connected to orders and address have a latitude and longitude point type on them. We want to filter for orders, where the location is within a certain distance of a point. That's being applied based on a value on the address node we want to filter order, order nodes based on that. Well to do that we just use a nested structure in the where argument. So, we're saying where the ship to, which that's the relationship field to the address, where the distance is less than one kilometer from this point, so now in this case because we're, we applied to filter at the root by specifying the argument here. Now we're filtering orders based on your relationship to address nodes. Cool, so that's the new to graphql library you can see a big part of a big part of driving the configuration for the api is all about the graphql type definitions that we write so we drew our graphql or our graph data model. Already we saw that we have data on articles topics geo region and so on. So what we're going to do is define graphql type definitions that define that data model. Zoom in a little bit here this is a little easier to read. So, what we've done here, we're defining type topic topic has fields like title URL. Relationship fields to the author, the topic person organizations can see we're using this relationship schema directive to encode the direction of the relationship, and the type of the relationship. We're also using the exclude directive here this is going to be a read only api we don't want to support, create updates or deletes right now. So we use the exclude directive to basically say hey don't don't generate mutations for this type. So, these graph diagrams were all created using this tool arrows dot app. I will drop a link to in the chat as well. arrows dot app. This is nice because it allows us to create these graph diagrams so I can sort of drag out nodes of video might have. I don't know maybe this has a rating. This to be a node label, not a caption there we go node label video has, let's call it a rating or something like that. Contrived example. This allows us to create these diagrams, which we can then save the images, we can also export, say like the JSON that defines this and check that into version control that's quite nice, but we can also generate the graphical type definitions based on the diagram we created so we go through this graph modeling process we go through this iterative process where we figure out what are the entities that we're interested in, how are they connected, those become relationships. We look at a traversal through the graph to sort of think of can we answer the questions that we have. If we can, then our model is complete, and we can just generate our graphical type definitions that define that graph model, these are the type definitions that work with the Neo4j graphql library so that can be a good way to go through this data modeling and come out with type definitions that match the api you want to work with. Okay, so we talked about the Neo4j graphql library we talked about how to write graphql type definitions based on the data model that we want to work with today articles topics and so on. Let's actually take a look at some code and get this running with Neo4j. next.js. So next.js is a, I think of it as kind of like a full stack react framework. react is a javascript framework for building user interfaces often front end client applications. next.js is built on top of react and adds a lot of other features, so things like server side rendering file based routing where you can just create files that map to new routes in our application. next.js also has support for something called api routes. Here we can see sort of all of the functionality of next.js. But api routes so that means we can define api endpoints in our next.js app so you can define both back end and front end code in next.js so that's why we're going to use next.js to actually run our graphql server our graphql api endpoints. Cool, so let's, let's take a look at some code and working with GitHub and next.js so there's a starter starter GitHub repo. Let me copy the link here. So this links to a repo that has some starter code for us in a next.js application. So we want to do is open that link in GitHub. This is a template repo, which means that what we want to do is instead of cloning this repo, we want to click on use this template, which will create a new repo under your GitHub user. And then what you want to do is clone that repo that was created from a template of this one. And the reason for that is because we're going to use Vercel to deploy this directly from GitHub. So it's easier than if you pull down everything from this repo and then go through the steps of creating your own repo and so on. You can just do that with one click, use this template. So what we're going to do now, we're going to pause for a few minutes and go ahead and open this repo in GitHub, click on use this template that will create a new GitHub repository. And then when you created the new one, what you want to do is clone that GitHub repo and then follow these steps here to get the next.js app running. There's a step in here to update the environment variables, but I think there may be an issue with provisioning our Aura instances. So we'll just use that default database, which is already filled out in the .env. So let me go through this so you can see what this looks like. And then we'll pause for a few minutes to give everyone a chance to go through this as well. So I'm going to go to dev.newfj.com slash full stack dash graph dash repo. That link is pasted in the chat. So this is a starter project next.js app for the workshop today. I'm going to click use this template. Give it a name. Let's call this graphql Galaxy full stack graphql workshop. And click create repository from template. You can call it whatever you like, of course. So that's using that template repository to create a new repository under my username. Cool. And what I want to do is now clone this repo. I'm going to go under the code tab here, copy the link to it. You can do either SSH or HTTPS if you don't have an SSH key configured. And then in the terminal, zoom in, do git clone, paste that link, and I have a password for my SSH key. Cool. And then I'm going to CD into the directory that was created when I cloned that repository. And let's open this in a code editor. So I use VS code. So I'm going to open this in code editor and bring that over. And so if I look at this, here's the readme. There's a data directory, an image directory, which we don't need to worry about, and then the next.js directory. So all of the code are interested in this next.js directory. Zoom in a little bit here. And so in next.js, we have a few things. We'll do a walkthrough of the code in a minute here, but just for the initial setup, we said to update .env.local to fill in your Neo4j Aura connection string. But I think there's some issue with Aura, so we'll just use this default one. This should still work for everyone, just the read-only database user. So just leave .env.local. You can just leave that as is. And then I want to open up a terminal. And in CD next.js, we're going to do npm install or yarn. If you use yarn, that's fine too. This is going to install our dependencies. And then I'm going to do npm run dev, and this is going to start this next.js application and run it locally, in my case on port 3000. So if I now go to localhost 3000, I should see this, which is the welcome to next.js. This is the basic app that you get when you create a new next.js application. Cool. Let's pause there to give everyone a chance to go through those steps. If you get stuck with anything, if you have any questions, ask in the chat. What we want to do is open the template repo in GitHub, click use this template to create a new GitHub repo under your GitHub username, clone that repo, and then open that up in a code editor and in the terminal, do an npm install and npm run dev. And if you see something that looks like this, then you're good. So hopefully that was enough time for everyone to create a new repo, clone it, and run your next.js app. next.js app, AC posted a screenshot, looks like he's got his setup. That's great. Was anyone else able to get that going? If not, let us know. Oh, I got some more information about the Aura issue. Did our Aura instances ever spin up? No, it doesn't look like it. So apparently, there's a aws DNS outage, which is preventing aws from processing these create database requests. Yeah, that is why we can't provision new instances. So aws is resolving that. Got tickets and all of those database create requests will be completed once the issue is resolved. So glad to know it's not just us. Okay, cool. So we've got this repo up and running. Let's take a look at the code and see what's going on. Thanks, Robert. Keeps prompting me to update one password. Don't, don't need to worry about that now. Cool. So here's our basic Welcome to next.js page. Let's jump into VS Code. Is this, is this theme okay? Maybe I can change this to something a bit more readable. This one, I think I've had good luck before with on videos. Anyway, let me know if that's not that's not legible. So let's take a look at what's going on here. So first of all, in the next.js directory, this is where we have our next.js app. And first off, we can look at package JSON to see what dependencies we're pulling in. We're pulling in react and react DOM and next.js and we're pulling in Neo4j Driver, Micro, which is a web server, and graphql, the reference implementation. And then we're pulling in apollo Server. We're pulling in this Micro flavor of apollo Server. Micro is a web server that works well with next.js, which is why we're using that and we'll see where we're using that in a minute. And then we're also pulling in the Neo4j graphql library and apollo Client. apollo Client is a tool for querying graphql APIs. So you can you can see here we have a couple of like front end and back end things mixed. We have basically the dependencies we need for our react app and like apollo Client for data fetching into our react app. But then we've also installed the dependencies we need for building our graphql api as well. So all of that is in one next.js app, which I think is pretty neat, is handy for sort of having one code base to work with. next.js, by default, when we go to localhost 3000, next.js uses a file based router. So in the pages directory, we have a few different pages. We have index.js and index.js. This is what we see when we go to localhost 3000. So here's where we have the welcome to next.js and basically everything that's rendering this screen. So if we if we edit that, we can we could instead say welcome to full stack graphql and we have hot reloading. So that updates right away, which is super cool. So that's kind of the basic for the front end. If we create a new page, we'll get a new route. We can see there's one here for articles. So if we go to localhost 3000 slash articles, we can see we have a honored list of articles. So we have these links. We can click on one. This is data coming from our graphql api reading data from Neo4j and just showing us a list. So I warned you earlier that we were not going to focus too much on the front end. We'll improve this a little bit, but just kind of want to touch on the data fetching basics first. So this data is coming from our graphql api, which is coming from Neo4j. But where is the graphql api running? So that's the next thing we want to look at. So we talked about next.js having this file based router where we create a new file and that maps to a route. So we have index, we have articles slash articles, but we also can have api routes. So let's take a look at the docs for this. This is a really cool feature. So api routes. This allows us to define api endpoints in our next.js application. And so the convention here is anything inside the api directory inside the pages directory gets mapped to a api route at that endpoint. And when we go to deploy this, we're going to use Vercel to deploy this in a minute. Each of these endpoints gets deployed as a serverless function. So I think we have slash api slash hello. Yeah, so if we go to slash api slash hello, we get back John Doe. If we look in our code in pages api hello JS, this is the function that is called. We can change this to return so returning a JSON object. Let's change this to return full stack graphql and save it again. So that hot reloading, we get that updated. So we also have an api route graphql. So api slash graphql. We should see graphql playground. And I have an old query variable. Don't need that. But here, this is just should look familiar to us. This is very similar to the graphql api that we were running in one of the exercises. We were writing queries and search for articles and so on. And that's exactly what we have locally. So let's take a look at what's going on in this code. This is going to be the kind of the starting point for our graphql api. So we're pulling in some dependencies. We're pulling in apollo server from this specific micro version. Again, micro is a web server that works well with next JS, which is why we're using that. Then with the latest versions of apollo server, apollo Studio is the default. You kind of get when you open a graphql endpoint, you get like a redirect to the hosted apollo Studio. I'm using apollo. I'm using a graphql playground here. I like being able to just open the endpoint and you have apollo or graphql playgrounds right there to work with. But really, it's the same functionality. Actually, apollo Studio, I guess, now has more functionality than playground. Anyway, that's why we're pulling in this graphql playground landing page plugin. We're pulling in the Neo4j driver and Neo4j graphql library. Then we define our graphql type definitions. So we saw these earlier. Basically, we are creating types that map to the graph model that we created in Neo4j. So we have articles, authors, topics, persons, organizations, geos, and photos. All of these types have an exclude schema directive, which allows us when we generate the api to exclude, create, update, delete. So no mutations are going to be generated. In fact, we can verify that if we go to the graphql playground, look in the docs tab, no mutations show up. The read-only api, we only have query operations. We're also using the relationship schema directive to encode the direction of the relationship. So this matches exactly this model. If we do call db.schema.visualization in Neo4j. And let's do style reset so we can read it. This matches this graph model that we have in the database. We create a Neo4j driver instance. We're reading the connection string and username and password from environment variables. And that's set in this .env.local. Typically, you wouldn't check in the .env file into version control and to GitHub. But for the purpose of having a skeleton that works out of the box, we've done that. So by default, we're pointed at this news.graph.zone Neo4j instance, which is that same Neo4j database that we were querying earlier using this news graph read-only api. So next.js works with these .env files. So we're setting those here. Later on when we go to deploy this with Vercell, we'll have to set these environment variables in Vercell to kind of override this .env file because we shouldn't really have that checked into GitHub. We are also setting a couple of other environment variables. debug, we'll talk about that one in a minute. And we'll also talk about this next public graphql URI. So we'll come back to those. Oops, that's not what I wanted. I want pages, graphql. Okay. So that's where our environment variables are coming from. We then pass the type definitions and Neo4j driver instance to Neo4j graphql constructor. And we get back a graphql executable schema that we pass to apollo server. We're also enabling playground and making sure enabling introspection. By default, in development mode, these are enabled. I think in production, by default, playground introspection, I think are disabled for security reasons. So we're explicitly enabling those. And then we define the start server function. We just have to start our apollo server instance before we can reference it in the handler. Remember, this gets deployed as a serverless function. So this looks a little bit different than the syntax. We were just running this as a regular node app with apollo server. But basically, we're defining the path which slash api slash graphql that apollo server is going to serve our endpoint. Cool. So that's the basic code for our graphql endpoint. So that's running locally as part of our next.js app, which is running here. So you saw one of the environment variables that we set was debug. And it had a value of Neo4j graphql colon star, I think. Yeah, so this one. So what's going on here? Well, this is enabling debug mode in the Neo4j graphql library, which we can see in the docs. So let's go to the docs for the Neo4j graphql library, which I linked to these in the slides. But this is a good reference document to have available specifically in the troubleshooting section where we talk about debug logging by setting this environment variable. So if we set debug equals Neo4j slash graphql colon star, that will log basically all debug info that is generated from the library, which is what we want. So what is this? Well, let's run a simple graphql query here. Let's just return title of the first 10 articles. When we do that, if we go back to our code and look in the console, we can see quite a few things here that were logged. Basically, it's saying, we have an incoming graphql request. Here's the graphql request. There are no graphql variables. We have not enabled auth, so there's no JSON web token to talk about. And then that graphql query is translated into this Cypher query. So you can see here the Cypher query that is generated and run against the database to resolve the data that we requested in graphql. And you can see here what's going on is we're matching on article nodes and then we're doing kind of a projection where we're returning just the title of the article and then doing our order and limit here. Now if we add more fields, so let's also return the URL and let's also return topics. If we run that query. Now we can see our generated Cypher query is a bit more complicated. This looks a little bit different from the queries we were writing earlier. But because these are generated programmatically using a map projection and pattern comprehension features of Cypher, which typically you find it easier maybe to write like one long match pattern, rather than to project out patterns that you want to return, but that's valid and in Cypher as well. That functionality is actually inspired by graphql and Cypher. Anyway, so here we can see we're returning title URL, and then for the topics in the object that we're returning. Here's where we're doing the traversal, where we're traversing from the currently resolved article node to find topic nodes that we're connected to and returning the name of those topics. So, really the Cypher queries that we're generating are projecting out basically a single object to be returned that matches the data that our graphql api is expecting to return. Cool. So, that's the back end, that's our api endpoint as an api route in next.js. We saw we have this very simple. If we go to localhost 3000 slash articles. We have this very simple list of articles that we're returning, which link to some of our data from the New York Times. So let's take a look now at the front end for this articles component, how that works. So now I'm going to go to pages, articles.js. And this is pretty simple component we're pulling in the use query react hook from apollo client so apollo client has the functionality for querying graphql APIs. And it has integrations for lots of different front end framework so we're using next.js which is built on top of react so we're using your react flavor of the apollo client integration which I think is kind of like the, the default integration that you get. The use query hook, this allows us to basically define graphql queries, and then we have this hook available in our react components that we can use to work with data fetching this is kind of the simplest way we can do that is by defining a graphql query. So here we are, we wrapped this in the GQL template tag this GQL template tag comes from apollo clients import as well. This is what this is doing is parsing our graphql query. And we're searching for what is the 25 most recent articles, and then grabbing title URL and published. So here's our react component. We don't have any props. Our data comes from a call to the use query hook, and we're passing the article query that we defined here. So this is going to go out to our graphql api to fetch data, based on this query. And then this data object will contain our result data. There's also loading state and an error object as well that we can pull in here to check if we are currently loading or if there's an error, but we're not handling those cases here. So we are just returning an unordered list. We are mapping over articles, so this query. We can just copy this run this in graphql playground. So, this is the data object that we that we are working with in our react component so we have data articles, and that's an array of these article objects where we have title URL and date published. So we can hover that articles array and return a list item that is basically just the title of the article linked to the URL of the article, so pretty simple and that is what renders this list so these are the 25 most recent articles from our graphql api that come from Neo4j. Another thing I want to mention while we're talking about the front end data fetching aspect, and that is how we configure next.js to work with apollo clients to fetch graphql data and that is in this underscore app.js file. So this underscore app.js file this is kind of like, if we need to inject things into our applications react component hierarchy, this is where we come to do it and that's exactly what we've done here so we're pulling in apollo provider apollo client in memory cache and HTTP link from apollo clients. The first thing I want to mention create apollo clients is first creating a new instance of HTTP link, passing in a URI. So what is, what is HTTP link well apollo client for the networking layer has this concept of composable links. So we call this as maybe like a middleware kind of thing, where I can sort of have multiple links, or my request goes through multiple sort of middleware processing. So in this case this is just creating a connection to our graphql URI, which we specify as an environment variable that comes from our dot env dot local. So our next public graphql URI is slash api slash graph, which is where our api route is running. Next public is, this isn't a real environment variable because we're, this is client code right so this is code in the browser where there isn't really that same concept so next JS, let's bring up the docs for this next JS environment variables. Link, drop this link in the chat here. So this talks about, we can set values and dot env dot local, and those are set as environment variables and available for data fetching and the api route so that's what we did to set our connection credentials for Neo4j, but then for using environment variables to the browser, anything that we prefix with next underscore public underscore, and that basically gets rewritten in the code that sent to the browser. So, allows us to kind of use the same idea as environment variables here, and it's fine we can expose us doesn't really matter if the client knows where we're running our graphql api, that's perfectly fine. There we go. So we create a new HP link that just basically is telling apollo clients, what graphql endpoints to send requests to. And then, when we create our apollo client instance we also need to create a instance of the cache so other than having really great front end framework integrations, another thing that apollo clients does for us is maintain a cache, so that if we send requests requesting the same data the same objects, instead of fetching that data again from the server we can cache it in our client application and that's data is just read out of the cache. We can of course have different types and control over the cache implementation. The simplest one is this in memory cache. It could be like reading from a Redis cluster or something like that. Down here, we are wrapping the sort of top level app component for our next JS app with the apollo provider so this is the provider syntax in react allows us to inject things into the component hierarchy using what's called the context api. So here we're injecting our apollo client instance. So now that apollo client instance is available to any component in our, in our application, which is why if you look at our articles component. That instance of apollo client is available for our use query hook here so it knows exactly what graphical endpoint we're talking about we don't have to like configure our graphical endpoint in each component where we have data fetching code, which is quite nice. Okay, so that I think is a pretty good sort of whirlwind. Look at the code here. What we want to do next is deploy this so that instead of running locally on our machines that it lives in the cloud and to do that. Go back to our slides. We're going to use for sell for sell for sell. I think of as like a cloud deployment platform for developers so big focus of herself is focusing on the developer experience, I don't want to see that I want to see the landing page or so. Come here we go. So I think for sell does a really nice job of focusing on the developer experience, and basically giving us the ability to deploy applications with things like GitHub integrations we get these really cool preview URLs so we basically anytime. So, anytime we connect a deployment to a GitHub repository. Anytime there's a pull request, for example, or changes to that GitHub repository, we get a preview URL that we can see a full running version of that application actually hosted live to sort of share with with our teammates, and so on so for sell has a CDN that it publishes static content to it works with serverless functions for api endpoints, they just announced a new sort of edge handler functionality, which looks super neat so I like for sell So we're deploying these kinds of full stack applications and that's exactly what we are going to do. I think that's the only slide we have on for sell. No, it's not. We have a few slides here so what we want to do now is take our GitHub repository that we created from What we're going to do is deploy that to for sell to deploy our full stack application, the simple front end as well as our graphql api endpoint. We're going to connect our repo to for sell deploy that so we can have that running. And then we're going to make some improvements to our application both on the front end and the back end. And then we will see those update in for sell, so we'll take advantage of that deployment preview functionality. So if you have a for sell account already, we're going to sign in and add a new GitHub project. If you don't have a for sell account and you can just sign in with GitHub, there's a free tier, which is perfectly fine you don't need to put in a credit card so Just like if you aura, we have a free tier to work with don't need to think about how much this is going to cost us, which is quite nice for for development as well. So what we're going to do is sign into for sell and click on new project. And we may if you sign in with GitHub, your GitHub account is linked automatically I think if you sign in with another method, you may need to link your GitHub. So when you sign into for sell, I just use the GitHub authorization. So we'll click new project. And then we have the option of selecting what GitHub repository we want to import. It's usually sorted by which ones were updated most recently, which is quite nice. Also have some templates that we can clone, which is also cool just to get started directly. And then we'll see the screen to configure our project. There's a couple things that we do need to configure here. For sell does a pretty good job of detecting what framework we're using, but because we have our next JS app in a In a directory rather than at the top level, we just need to point it to that directory and I'll go through this in a minute. So don't worry about paying too much attention. So we do need to say what root directory we want, which in our case, it's called next JS. And then we do need to set some environment variables and these We will actually I guess we have our dot E and B file checked into GitHub. Just to make it easy. So We probably don't need to do this step, but in the real world, we wouldn't have our dot E and B file checked into GitHub. So this is where we would specify those environment variables. And then we can watch the project build. And then when it's done, we will have a URL. We get a couple of URLs. One is URL for the project. So that's like the production version of the project and we get a SSL certificate. So yes, and all that, which is which is very nice. But then each deployment. So remember we have this idea of preview deployment. So we make a change from say like a pull request on GitHub. We don't necessarily want that to immediately be the production version. So the production domain may point to a different deployment, but we get a URL specific for this deployment as well that we can share with our team or whoever. If it's a client we want to send something to before we push something to production, we get a separate URL that's specific to that deployment, which is pretty cool. So we're going to do that, deploy it, and then and then we're going to talk about adding custom logic to our api. But let's go ahead and I'll go ahead and go through these steps and then we'll pause for a few minutes if everyone a chance to do that. So I'm going to go to Bercel.com. I'm already signed in. But I think I signed in with GitHub. So I'm going to do new project. And here are all of my GitHub repositories. I want this one I called graphql Galaxy full stack workshop or something like that. Let me zoom in a bit. So the project name of this project name is not good. Let's change. Let's just change this to full stack graphql. And then this is going to be next.js. If I had the next.js app in the root, I wouldn't need to do that. It can detect it's the next.js app. But we have it in the next.js directory. So I need to click edit here to tell it I want to deploy this project just in the next.js directory. This means it's not going to deploy anything that's not in that directory. The build and output settings. These are fine. We can use the defaults. But we do need to set our environment variables. So Neo4j user is going to be NewsGraph. If we didn't have that aws issue and we all had our own private Neo4j Aura instances, this is where we would put our own individual Neo4j Aura instances. But we don't have that now. That's OK. So the user is NewsGraph. And again, I don't think this part is actually technically required because we do have that .env file checked in. Although it's env.locals. I'm curious if that actually gets read for a production deployment in Vercell. I guess we'll find out. I'm going to go ahead and add these anyway. So Neo4j user, we have Neo4j password is also NewsGraph. And then the Neo4j URI is Neo4j plus s colon slash slash news dot graph dot zone. So this the protocol Neo4j plus s colon slash slash. This is Neo4j protocol for working with Neo4j instances. The Neo4j protocol, this was previously Bolt, who's the binary protocol called Bolt for sending data to and from Neo4j. It's now called Neo4j to sort of simplify the way of working with a cluster when it was Bolt. There was if you wanted Bolt's routing or single instance, if you didn't have a cluster, now it's just Neo4j, which is much easier to reason about. But the plus s means that we want a secure encrypted connection. So we have a certificate on this news dot graph dot zone Neo4j instance, and we want to make sure we use an encrypted connection. So that's what the plus s means. If we don't have a SSL certificate for our Neo4j instance, we would just use Neo4j colon slash slash. Like if we're using local instance, if we're using like Neo4j desktop or something like that. And then I think we also need to set the next public graphql. What do we call that next public graphql URI? I think we called it that. Let's look in our ENV file. Next public graphql URI is slash api slash graphql. Okay, so I'm going to add those environment variables and then hit deploy. And now Vercell is going to clone that repo, do an npm build, and the static content that is generated is going to go out to Vercell's CDN, the api endpoints. So we had what we had slash hello, which was our very simple one, and our graphql endpoint will be deployed as a serverless function so we can take a look at the logs and watch that move along. Once this is done, then we will have a unique URL for our project. If I go, well, we're waiting for this. If I go to my team here to see all of my projects. Here's sort of the status of this. I guess this is already done. Full stack dash graphql dot Vercell dot app. There we go. Welcome to next.js. If I go to slash articles, I should see my bulleted list of articles. Yep. So that's coming from the graphql endpoint that is running at slash api slash graphql. Right here. Cool. So we've deployed our graphql. We can do articles count to make sure querying the same database. Yep. 4,500 articles. Cool. So we've deployed our next.js app, both the backend graphql endpoints and the front end as well, which is pretty neat. So I'll pause here for maybe another five minutes or so to give folks a chance to go through this. So sign into Vercell. Create a new project. Pull in the GitHub repo that you created from the template. Set those environment variables and basically just use what's in dot env dot local and then click deploy and you should see something like this. And if you go to whatever your domain is slash articles, you should see the list of articles. If you go to slash api slash graphql, you should see graphql playground and you can write some graphql queries. So we'll pause on this slide, I guess, for five minutes and then we will move on to the final section, which is going to be adding article recommendation. So we'll need to add some custom logic to our graphql api and then we'll need to take advantage of that functionality in the front end. Let's move on in the interest of time here to talking about adding custom logic. So what we want to do now is we have the basic query functionality for fetching articles, but it would be nice if instead of just showing articles, the most recent articles, if we could say, you know, I'm reading an article and I would like to read other similar articles. So can I recommend similar articles based on the article you're currently looking at? So we want to add that functionality both to the api and then also we want to add that to the front end to fetch that data from the api and show that in the front end. But to do that, first we need to talk a little bit about how we can add custom logic to our graphql api. We'll use the Cypher schema directive, which we mentioned a little bit earlier, but we'll really take a deeper dive at looking at the power of that Cypher schema directive. So when we're using the Neo4j graphql library, there are basically two ways that we can add custom logic to our graphql api. We can do this using the Cypher graphql schema directive where we're annotating our graphql schema, adding custom logic basically by mapping a Cypher query to a field in our graphql schema. And when we do this, the benefit of this is that it takes care of a lot of like boilerplate code that we don't have to write. We're just adding a Cypher query to our graphql schema. We're still generating a single Cypher query that is sent to the database, even with our sort of custom logic query, our query is integrated as a sub query into that generated database query. And then another option for adding custom logic is implementing a custom resolver so we can override the generated resolvers or we can define types that don't actually exist in the database and resolve those using custom resolvers. The downside of that is it's a bit more code that we have to write. We can do basically whatever we want in that resolver. We can query Neo4j, we can query another database system, whatever that is. Well, another downside is that we will call that resolver in a nested fashion. So first we'll send the query to the database, then we'll call this resolver, which might result in another request to the database or to another data layer. So just important to be aware of the distinctions there. So let's look at this Cypher schema directive. So we said earlier that schema directives are graphql's built-in extension mechanism, some indication that some custom logic should occur. Cypher is a schema directive available with the Neo4j graphql library. There are quite a few. So far we've seen exclude and relationship. Let's take a look in the docs at the other directives that are available. Here we go, directives. So drop a link to this page in the chat. We can see we have quite a few directives available, things like for adding authorization rules, Cypher, which we're going to use in a minute here, exclude, which we use, ID, which is nice for generating auto-generating IDs, and the relationship directive we saw, which we used to encode the relationship direction. So quite a few directives that are quite powerful. With Cypher, what we do is we add the Cypher directive and a Cypher statement. In this case, we're returning a scalar for a float field. So the example this comes from is looking at orders that may contain multiple books, and we're calculating the sum of the price of those books to be the subtotal, so returning a float. Then at query time to the client of this graphql api, it's not obvious that this is a computed field. This just shows up as another field in the api schema. We can also return nodes from our Cypher query that map to types that we've defined in the schema. So here's a recommended field for a customer that's going to return books they may be interested in based on books this user has ordered and other books ordered by users. Basically, what users are ordering the same books, what other books for those users ordering, those might be good recommendations. But note that we're returning, in this case, rec, which is booknets. And again, for users, for clients of our api, recommended just appears as another field. In this case, an object field. Any field arguments that we define in graphql and our type definitions for the field where we're using the Cypher directive are passed to the Cypher statement as Cypher parameters. So here on this recommended field, we've added a limit argument that's an integer with a default value of three, and whatever is passed by the user at query time, whatever value for limit that's passed as a Cypher parameter here with this dollar sign limit syntax. That's how we refer to parameters in Cypher. I like to always use default values or make these required fields, because that makes it easier to work with in Cypher if you know that the parameter has been, that a value has been defined for that parameter. So here we're saying limit one, only return one book. We can also return projections from these Cypher queries to return data that may not actually exist in the database. So here, in this example, we're calling out to another api using APOC load JSON, which is, APOC is like the standard library for Cypher, which allows us to do lots of things. In this case, we're querying out to an external api, and we're returning an object that matches the weather type that we've defined. So that weather type does not exist in the database, but we're able to return a projection of that data. We can use the Cypher directive on query fields. So at the root level, one example, this might be nice is for full text indexes. So here, we can create a full text index in the database that allows us to do fuzzy matching. So if we search for graph, but we misspell it, we add this tilde. This is a Lucene index, Lucene of the text engine. This allows us to do fuzzy matching in the database. Well, we can use that in a query field to search for book titles using this fuzzy matching full text index. So that when we're searching for books, even if we misspell it, we'll still get the results that we're looking for. We can also use this on mutation fields if we have some custom logic. We didn't really talk much about the mutations that are generated by the Neo4j graphql library. But if we want to create some specific mutations in addition to the ones generated for us, we can do that with Cypher directives. For custom resolvers, basically the way this works is we add an ignore directive in our schema. It tells the Neo4j graphql library that we are not going to try to fetch this data as part of the generated Cypher query. And you're basically saying that we are defining a resolver. We are responsible for fetching this data. Okay, cool. Here is our last exercise. We have about 12 minutes left, so I think that should be just enough time. So what we're going to do in this one, it says use the article recommendation query from the first exercise to add a similar field on the article type. Yeah, so because we had that issue with provisioning our aura instances, we actually skipped the article recommendation query. That's okay. We'll do that. Basically what we wanted to do was write a Cypher query that would recommend similar articles. So we'll do that and then we'll take that Cypher query and we're going to add that to a similar field on the article type. So now as we're resolving articles, we'll be able to see similar articles based on how we define that overlapping topics, overlapping organizations. We'll figure that out. But then we'll have that functionality, that custom logic in our graphql api. And then we'll need to update the articles react components to add that field to our data fetching and render that for the user. So for each article, you can see other recommended similar articles. So let's start by going to Neo4j browser. Do I have that open here? Here it is. And this is the news.graph.zone and username and password is just newsgraph, all lowercase. Newsgraph, newsgraph, like that. So how would we write a recommendation query? Well, let's start by just grabbing an article. Okay, so here's we're saying match articles and then with allows us just kind of pipe things through or we can do aggregations or limiting filtering. So we're going to just bring through one article. So here's one article. And now I want to write a query to find similar articles. So if I'm reading this article, which what is this about? So how would I find similar articles? Well, one way would be to look at the topics of this article. So what are the topics of this article? It's a bit bigger. So coronavirus, vaccination, antibodies, immune system, science, bone marrow. We can also look at the organization, so Moderna, some nature article, and then a photo. Photos are not going to be useful. Photos are just specific for the article. So one way that I could define similarity would be, well, let's look at articles that are of similar topics. So you're reading this article about bone marrow. Are there other articles about bone marrow? Oh, maybe you're all interested in this article about what is this? Some disease that Colin Powell had that was in his bone marrow and had something to do with COVID. You may be interested in that. Well, we have a bunch of different topics, though, so we don't want to recommend just one. We want to find the article that has the most number of overlapping topics, and that's what we're going to recommend. So how would we write that? Well, it looks something like this. Match A and then traverse out has topic. And this is going to be our topic node here. And then we want to traverse out along the incoming has topic relationship to our recommended articles. So here's we basically follow this traversal from the article resolving to a topic to another article. That is the recommendation, but it's really like the candidate field for recommendations. So it's going to kind of a two step one is get all the candidate for recommendations, which are basically any articles with overlapping topics. And then we need to score those. So let's bring through. Let's bring through the recommendations. And then we're going to do an aggregation. So we'll say count star as numb. So what's going on here? Cipher has an implicit group by functionality built into it. If you're familiar with SQL and you have explicit group buys in SQL where you can do aggregations grouped by some value, that's implicit in Cypher. So we use the width command, which we said is kind of like a like a pipe allows us to do aggregations or limiting ordering those sorts of things. So here this is kind of like saying give me an implicit group by rec. So for each of these recommended articles, because we're going to have a whole bunch of these, right? Like there are going to be a whole bunch of articles that have one or more topic nodes in common. I mean, if we double click on coronavirus, it was probably like a thousand or something. Right. So we want to score these by counting. We say count star, which is the number of paths that we've found for the specific article. So this is basically counting the number of overlapping topics from the article. The single article that we're resolving here to our candidate recommended articles. So now num is the score essentially for our recommendations. So we can return the recommendations ordered by num in descending order. And let's just like limit it to 10. If we run that, we get our 10 recommended articles. If you look at these, look at these in table view. So we have immune cells, COVID booster shots, scientific understanding of variants. So these are all similar to the article that we're resolving, which was that something about bone marrow and vaccines. OK, this looks pretty good. So let's copy this part of our query and go back to our code here. And I'm going to go to my graphql api code and an article I'm going to add. Actually, let's do this as a type extension. So I'm going to say extend type article. This type extension just makes it easier to read so we don't have a bunch of fields cramped together. Typically, you'd use this if we had this part in another file, we can extend the types that exist in our schema. But I'm just going to do it here for readability. So we'll say similar. This is going to be an object array field of articles. We're going to add the cipher schema directive. It takes a single argument, which is a cipher statement. I'm just going to paste this in. And this is going to be pretty similar to the query we wrote in browser, except we need to change a to this. So it was a because here we matched on a single article that we referenced under the variable here. Here, this is a special keyword that refers to the currently resolved article. And this is going to give us 10 article recommendations. So we save that. That'll hot reload. You should be able to go to localhost 3000 slash api slash graphql. And now let's do articles, options, limit. Let's get 10 articles. And for each of these articles, I want the title, the topics. And now I have similar where we can also grab the title. Actually, let's not do topics. Let's make this a bit easier to read. So 10 articles, the title, and then for each one of those, give me similar articles and just the title. So here's what we end up with. So for the first article, immunity to coronavirus. Here are 10 similar articles based on the number of overlapping topics. Here's one other article. Best time of day for exercise. And here's similar articles, low carb diet, cholesterol, exercising, exercising, fish oils. These are like health related articles. So this seems like a pretty good recommendation algorithm that we've got here. What I'm going to do next is now I want to update my deployment. So I'm going to go to the terminal because right now I'm just running this locally, but I want to push this out for my teammates to see as well. So let's do a get status. See, we've made some changes here. Let's add graphql. And we'll say add similar field on article type. And we'll push that up to GitHub. So if I go to GitHub, I can see that I have updated that. Let's go to my repositories. Yep, here it is. graphql Galaxy, full stack graphql workshop. Add similar field on article type. Here's the diff. Just adding this field here on the article. But if I go to Vercell, I should see that Vercell has picked that change up. Oops, we just missed it in the log here. If we go to our deployments, there we go. So here is our first deployment, our initial commit. And then Vercell automatically picked up this commit and did a build. And because we pushed to the main branch, it promoted that build to production. So now if you go to full stack dash graphql, Vercell.app, and we go to slash api slash graphql. And now if we look in the docs article, article now has a similar field. So because we pushed to the main branch, Vercell picked that up immediately and promoted to production. If we had done a pull request, Vercell would have done a preview build and given us a deployment URL specific to the deployment. It would have been like this one, rather than promoting it to production. Cool. So that's half the exercise. The next step is to now use this field in the react component. So I'm going to leave this one for an exercise for you at home since we're out of time here. It's been three hours already. But just to look at what we would do, we would go into pages, articles.js, and we would update this query to include similar title URL to add the similar field. Now, down here, as we are iterating through our articles array and rendering list items, linking to articles. Now for each article, we would then iterate through that similar because that similar field that's going to also be an array of articles. And we would do something like say similar articles interested in this or others may be interested in. I'll leave that part for an exercise for you at home since, again, we are out of time. But thanks. Thanks so much for joining today. I hope everyone enjoys graphql Galaxy Conference when that kicks off tomorrow or no, Thursday, Thursday. Here's some resources. So the slides have all the content for today. The code is also available on GitHub. I've linked the docs. Also, the landing page for the Neo4j graphql library has a good explanation of a lot of the different features and links to other resources. There is a self consumable course focused just on the Neo4j graphql library that goes into a lot of the different features, including authorization. So if you're interested in learning more about the Neo4j graphql library or other Neo4j courses, check out. It's called Neo4j Graph Academy. For the slides, I did leave some sections from the other workshop we did on authorization because I think that's kind of the next step when you're building an application is, okay, how do I sort of protect resources in my api? And there are some really cool authorization features built in to Neo4j graphql library. So I left those in the slides if you want to click through or also we covered those in the training that we did last week. Have a talk at graphql Galaxy. I think it is on Thursday in the Milky Way track. Yeah, here it is at 10, 15, 10, 15 my time. So 10, 15 mountain time, putting the graph in graphql with the Neo4j graphql library. So going into a lot of the concepts that we talked about today, but taking a look at some of the motivations and some more specific features and some of the benefits that we have when we build graphql APIs with the Neo4j graphql library. Great. Well, we're, we're over time. So we will leave it there. The slides and all the code and that Neo4j instance we were running today is public and we'll stay out there so feel free to use those as resources. And do, do check out Neo4j Aura. Sorry, we had that aws DNS issue that prevented us from using it, but those instances will provision once that DNS issue is resolved with aws, it might be already. Maybe not. Hopefully, sometime later today that gets resolved. Anyway, thanks a lot for joining. I hope everyone enjoys the rest of the conference, and we will see you next time. Cheers. Bye bye.
162 min
07 Dec, 2021

Watch more workshops on topic

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career