So a little bit about me, I work for an open source
database company called Neo4j, Neo4j is a graph
database, we'll talk about what that means in a minute, I work on the developer relations team, so largely my job is helping developers build applications with Neo4j and other technologies, it's really important to understand how
database fits in with different technologies, different pieces of your
architecture, so that's a big piece of my job is I think sort of contextualizing the
database piece for different technology communities, so
graphql as well as one of those, which is the focus of our workshop today, I also wrote a book recently published by Manning, it's called Full Stack
graphql Applications, this book is available for free or the ebook version is available for free, sponsored by Neo4j, so I'll drop a link to that, now we'll take you to a form if you're interested in downloading the book, the book focuses on using
graphql in a full stack
architecture with
react for the front end, so today we're going to look at native iOS with SwiftUI as sort of the client front end for our application, if you're interested in similar
architecture but using
react and we look at different
cloud services, like how do I deploy to Netlify, how do I use Auth0, those sorts of things, cool, so here's a rough outline for what we're going to do today, so we will have I guess roughly four sections here, one is we're going to look at Neo4j and AuraDB, which is Neo4j's hosted
cloud service, if you're in the workshop on Tuesday we used Aura as well, so we're going to use the free tier for Aura, which is nice because we can spin up a
database that's private to us that we don't have to put in a credit card or incur any cost, so that's really good for hobby projects, we have something like that where we don't want the
database to go away but we just have sort of lower use of it, that's what we're going to do for the
database layer, then we're going to talk about building
graphql APIs, so building
graphql servers and specifically we're going to use a
graphql database integration called the Neo4j
graphql library that's going to help us provision our
graphql api without writing a lot of boilerplate code, generating
database queries, that sort of thing, then we're going to take a look at SwiftUI, so building native iOS applications using Swift and we'll see how to integrate
graphql and SwiftUI, so we're going to use the
apollo iOS library for SwiftUI, which allows, or for Swift rather, not specific to SwiftUI, SwiftUI is the user interface component that is available with Swift, there's a few different ways of building UIs for iOS, SwiftUI is similar, conceptually similar I think to a lot of web
frameworks like
react, so if you're familiar with things like
react, there's some concepts that transfer nicely in SwiftUI, and then the only local development environment that you need to have set up is Xcode on a Mac, if you don't have that set up, that's fine, you can sort of just watch as we go through the exercise at the end, the SwiftUI part is the last piece we're going to do, for the other pieces for using Neo4j, we're going to use the Aura
cloud service and nothing to download or install for that, and then for building the
graphql api piece, we're going to use Code Sandbox, which is a sort of hosted development environment, so we don't need to set up anything locally for that, but then there is a GitHub repository for the Xcode SwiftUI piece of the project that has just sort of a getting started component. Cool, here's some links to various resources that will be helpful as we're going through things today, the slides of course, and a link to the GitHub repository for the Xcode project,
documentation for the Neo4j
graphql library, as well as an overview page for that, we'll talk a lot more about what that is, and then the
apollo graphql iOS tutorial is a helpful resource that shows how you can install and set up the
apollo graphql iOS package in an Xcode project, and then the developer docs for SwiftUI is a good resource as well. So here's what we're going to build today, it's a fairly simple app, we're not going to focus too much on a lot of the nitty-gritty pieces of SwiftUI to make everything look super nice, really I think the focus of what we want to do today is talk more about how the pieces fit together in this sort of
architecture. What we're going to build is a newsreader iOS application, so we're going to fetch news articles and show them to the user and then think a bit about how we can add personalization features to our iOS app, how can we show news that's relevant for users either by factoring in location or finding similar articles that a user might be interested in. And we're going to do this using Neo4j as our
database, so we're going to be modeling and working with this
data as a graph, so when we're talking about a graph, we're talking about a
data structure that's composed of nodes, these are the entities and relationships that connect nodes. And we're going to do this with
graphql, so
graphql is going to be the layer that sits between our client iOS app and our
database, we're going to build a
graphql api. And one thing that you'll notice when we're talking about using the graph
data model in the
database that's very close to the same graph model that we use in
graphql, and we'll talk a bit more about that. Cool, so let's take a look at what exactly is Neo4j. So I said earlier that Neo4j is a graph
database, that means unlike relational databases that use tables or document databases that use a document, like a JSON document, the
data model in graph databases like Neo4j is a graph, so nodes are the entities, relationships connect nodes. We use a query language called Cypher, which is kind of like SQL, but for graphs is a good way to think of it. There's an example, Cypher example here in the upper right, you can see we're sort of, in the first line, drawing this ASCII art representation of the graph pattern that we are looking for in this
data set. So the first part here, so we're saying match, which is go find some pattern that exists in the
database, and these open and close parentheses are drawing sort of a node, a circle around an address, so we're saying find where this pattern exists. We want address nodes that have a registered address relationship, so these square brackets with kind of the arrow that's representing a relationship that's connecting two nodes, in this case connecting an address node to an officer node, and then we're traversing out from that officer node to find entity nodes. So this query says find addresses in New York, find the officers who are connected to those addresses, and then find the entities connected to those officers with an address in New York. This query comes from the Panama Papers
data set, which was a investigative journalism project a few years ago that was using Neo4j to make sense of offshore corporate records to try to find interesting things around mostly folks hiding assets in offshore companies, which is a fun
data set to look at. That's a public
data set. We can find that on the Neo4j sandbox. Cool, so let's talk through the different technologies we're going to use today, so we're at least on the same page about at least what they are, some of the benefits, and so on. So we talked about Neo4j.
graphql is the next piece. I think a lot of folks here at the conference this week have learned a lot about
graphql if you weren't familiar with
graphql already, but basically
graphql is an
api query language and a way of building
api applications, so
api servers. With
graphql, we have a very strict type system, so we describe the
data that's available in the
api. We have types. Types have fields, and we know the
data type of each of those fields. The example here is we have a project type. We have fields like name, tagline, and contributors. Name and tagline are strings. Contributors is what's called an object field. Specifically, this is an object array field, so this project has one or more users connected to it, and this is where the graph piece of
graphql comes in. So types can refer to other types. You think of this as a relationship field that connects the project and one or more users. So that's the graph piece of
graphql. Then at query time, the client requests basically a traversal through this
data graph in the form of what's called a selection set. So here we're searching just for a project and bringing back the tagline, but we could traverse to the contributors as well and bring back information about the contributors. This is nice for the client because the
data that comes back exactly matches the selection set of the query or the mutation operation, so we have very predictable
data that we are working with when we use
graphql. To make building
graphql APIs easier when working with databases, there's really a whole crop of
database graphql integrations out there. We see this in the SQL world. We see this in the graph
database world as well, and so one of those is the Neo4j
graphql library. So this is a
javascript library focused on building
node.js graphql APIs backed by Neo4j, and so the idea here is that we can use
graphql type definitions to define the
data model for the
api, the
graphql api, but also to drive our
database, and this is really nice because this reduces a lot of the boilerplate
data fetching code that we end up writing when we're building
graphql servers. It also has a lot of
performance advantages because we're able to generate a single
database query for any arbitrary
graphql request, but then we also have some really neat features as well for things like adding custom logic using the Cypher query language that we talked about a minute ago, features for adding authorization rules in our
graphql schema, so really powerful library for building
graphql APIs. And then SwiftUI. Has anyone used SwiftUI before? I'm curious if we have any folks that are familiar with building native iOS apps. So if you're not familiar with SwiftUI, there's kind of two pieces here. One is the Swift programming language. So this was originally created by Apple. This is sort of the successor to Objective-C. Objective-C was a language used mostly by Apple for building iOS, Mac, and tvOS apps. Swift was open-sourced in, I think, was it 2012 or maybe 2014? And then SwiftUI is a UI framework, and specifically Apple's UI framework. So Swift, the programming language itself, is open-sourced. It's not specific to Apple. You can run Swift, the language, on Linux as well, and also on server applications, Linux-based server applications. But SwiftUI is specific to iOS, macOS, and Apple TV, which includes sort of a UI framework for building declarative UIs. So one of the neat features in SwiftUI is the preview functionality. So you can see that here in the screenshot from Xcode. So previously, we had to build and preview the app running to sort of see any changes with SwiftUI. We can sort of see changes in real time to our UI as we're making updates. Yeah, we'll talk a bit more about SwiftUI. So Bee says they're familiar with native iOS apps. Great. We've got some level of experience there. That's good. Cool. Well, let's talk a little bit about working with graphs in Cypher, working with graphs in
graphql, because I think there's kind of some similarities there, right? We're talking about graphs in the
database. We're talking about graphs in the
api layer. Let's sort of see how we can compare and see how we can compare and contrast working with graphs in those two different pieces of our application
architecture. So first of all, at a high level, what is a graph? Well, a graph is a
data structure composed of nodes. Those are the entities and relationships that connect nodes. To be able to work with
data in a graph, we use a
data model called the property graph
data model. And so what this means is that we introduce labels. So labels describe the type of the node. It's a way to sort of group nodes. So in that example earlier, we saw things like the address node, the officer node. Those were labels that described what sort of type of node it is. And then we have arbitrary key value pair properties that we can store on nodes or relationships. And these are the attributes. These are the values that we're working with. Similar to labels, relationships have a single property type and a direction. So that's the basic
data model that we use. Another term that you might hear frequently is the term knowledge graph. And knowledge graph, I guess I like to think of knowledge graphs as an instance of a property graph. So we have some real world
data that we're modeling in a property graph. And the value of a knowledge graph is that they put things in context. And when I say things, I guess what I'm referring to is like a canonical representation of something, of a value of an entity. So this example on the screen, this comes from our news
data set that we're going to be working with today, which comes from the New York Times. And so for every news article, we have the topic or we have multiple topics. We have the people mentioned in the news article. There are geographic regions that may be relevant for the article. And we can see how these articles, topics, and people are connected in this news knowledge graph. So here, for example, we have a canonical representation of the topic, US politics and government. So when we have a new article that is about that topic, we connect it to the topic node and we can see similar articles by traversing the graph here. So we can traverse from one article node to others through the same topic. And this applies also for our geo regions. If we want to see all of the news about a particular geographic region, if we want to see all the news about a certain person and so on. So this term knowledge graph was, I think, really introduced formally when Google released the Google knowledge graph. And they talked about this idea of things, not strings, where we have some context, we have some canonical representation of these entities, which is, I think, a good way to think about knowledge graphs. So the
data set we're going to use today comes from the New York Times
api. So we have set up, let's see, on this repo, I've set up a sort of cron job using
github actions to fetch this
data from the New York Times
api. So once a day, we fetch the most popular articles. There's three kinds, the most popular viewed, the most popular emailed, and the most popular articles shared on social media. And once a day, we fetch that and load that into a Neo4j Aura
database using this GitHub action. And I've been running this for, I don't know, probably about a year or so. So we're going to use a snapshot of this
data to work with. I'll drop a link to that GitHub repository. Cool. So that's the
data we're going to work with. Let's talk a bit about how we can think of interacting with that
data. So how do we work with
data as a graph in the
database? And also, how do we work with
data as a graph in
graphql? So first of all, this is the
graphql api, or very similar to the
graphql api we're going to build today. And this is running without any
authentication. So anyone can open that and query this
data set and zoom in a little bit. So if we look at the Docs tab, you can see here we have queries. We don't have any mutations. So this is just a read-only
api. We can see the
data we're working with here. This is
graphql Playgrounds, which if you've used GraphiQL or if you've used
apollo Studio's sandbox tool, similar functionality based on
graphql's introspection functionality. So there's lots of really neat developer
tooling for
graphql. Most of it based on this idea of introspection, which is that we can query a running
graphql api to say, hey, what are the types that we're working with? We can use this to generate things like
documentation that we're seeing here for the
api so we know all the
data available. It's also available for things like, or say it also enables things like autocomplete in developer tools, which is quite neat. Cool. So there's a query here. I guess this was the last query I ran that this gives us a pretty good idea of what sort of
data we have and how we can construct
graphql query. So feel free to open this up and take a look at the
api documentation, try to write some
graphql APIs to query this
data. This one is a fairly complex query that I think shows a few features of the
api that we're going to build. So first of all, we're starting with the articles query field. So this is our route entry point to our
graphql api. So we're searching for articles and the query type is a special type in
graphql. Any fields on the query type are the entry point, the root level of a
graphql query. So we have to start from a field on the query type to start our traversal through this
data graph. The other special types are mutation and subscription, mutation for write operations typically. So create, update, delete, those sorts of things. We're not going to look at mutations today. Subscriptions are
graphql's sort of pub sub real-time functionality, which we're also not going to look at today. We're going to focus mostly on queries for our news app. But what we're doing here is we're starting at the article query field. We are passing in a couple of field arguments. So this where argument is a filter. So we're filtering for articles that are connected to the topic exercise. And where the geos are not null. So where we have some geographic information about the article. And then we are sorting these by publish date and descending order and bringing back the most recent 10. So this basically says, find me the most recent 10 articles about exercise that have something to do with some geographic location. And then here's the fields we're bringing back. So we want the title, the URL, and the publish date of the article. We want to know all the geographic regions the article is connected to. And then for each of these geos, you can see the nesting in the selection set here. So this is basically anytime we have nesting in the selection set, which by the way, the selection set is this part of the
graphql query, where we're defining, first of all, a traversal through the
data graph. So which nodes are we traversing to, but then also which fields are we returning. And those are the two main purposes of a selection set. And anytime we have this nesting in the selection set, so going from the geographic regions to, in this case, the articles, that's traversing from one node to another. So anyway, so we're traversing from any of these geographic regions to find other articles in those geographic regions, but only three. So we can pass field arguments in our selection set as well, not just at the root. And for each article, we're bringing back the title. So here, first one we have is an article about the Ironman and the URL of that article. It is something to do with Hawaii. And then we can see some other articles about Hawaii and so on for an article about cycling in Brooklyn, and then some articles about Brooklyn, and so on. Cool. So that gives an idea of the type of
data we're working with and the type of
graphql api that we want to build. So this is going to be our goal to build this sort of
graphql api, get it deployed, and then we'll see how to build a native iOS app to query this
api. Anthony says, is there a trick to getting results when I hit the URL? So you should, so if you open that URL, you should see, yours will probably look something like this. It will be blank, right? So mine loaded with a query already. And so the first thing you can do with
graphql Playground is click on this Docs tab. So this will give you the generated
documentation for any
graphql api. So this gives an idea of what sort of
data you're working with and the entry points. And then every
graphql query starts with an open and closed curly brace. And then we can do a control space to get this autocomplete to show, in this case, all of the fields on the query type, which are the entry points. So we can select articles, and then we're going to have another open and closed curly brace, because we know we need some selection set now in our query. And if I do a control space again, I can start to see the fields that are available. And this is kind of the simplest query we can run. This returns all of the articles, which is probably more
data than we want to return. However many 10,000s or so articles that we have. So try, I'll drop this in the chat, try that query. That's sort of the simplest form. From there, we can look at again in the docs for this articles field, we can see here that there are two optional arguments. So where and options. And if I scroll down to the bottom here, I can get more information about the filtering. So where is the filtering options, and then options, those are going to be things like for pagination. So if I don't want to return all articles, I can do things like options limit 10. But then I probably want some sorting on that as well. So we'll say sort by published descending, and you can see mostly I'm relying on autocomplete to tell me what fields are available. And then let's bring back the published date as well. So this should be the most recent news, which if our scraper ran, getting news or getting articles from yesterday. So I guess we didn't pick up today's articles for some reason. Yeah, Anthony says he's getting a syntax error. Yeah, share the query you're using, we can try to
debug that if you're getting an error, it says figured out. Okay, cool. Great. Cool. Yeah, well, this
api, this is up running. So this is a good one to play around with using some real world
data you can always use it to check the day's news as well. But let's see how we can work with the same
data in Neo4j. So let's see, I think we can do news scrap dot zone. Oh, yeah, I noticed some, some DNS issues on this. I have a backup, though we can do news dot graph dot FYI. I think that's my backup. Yeah, there we go. So you can, you can follow along if you like on this one. Here's the URL for this one. This is a Neo4j instance. And then the I think I'm already signed into this, but the username and password is just news graph. All lowercase like this, or the username and password. And it's just a read only user. So don't worry about making any changes or actually deleting
data. I just have read only permissions. So this is Neo4j browser, which is like a query workbench for interacting with Neo4j. So the idea here is we can write
graphql queries. And then we get back a visualization or perhaps a tabular result, depending on the type of
data that we are returning. So let's see how we would write a query similar to this one. So here's how we do this in
graphql to find the 10 most recent articles. Let's see how we would do that in Cypher. So to start off with, we're going to say match. And then so match is the keyword to find some pattern and match takes a graph pattern. And starting off, if I don't know the
data model, I can do a call db.schema.visualization. So call, this is a Cypher keyword that is going to execute some built-in function or procedure. db.schema.visualization is going to give me a graph view of the
data that I'm working with. There's some additional metadata here. You'll see here with the underscore bloom perspective and bloom scene. And this is just some
data for a visualization tool. So we can ignore that. This is the piece that we're interested in. And if I do a colon style read, I'm going to the piece that we're interested in. And if I do a colon style reset, then I should be able to see all my captions. There we go. So this is the
data model we're working with. And this matches what we saw in the slide a few minutes ago when we were talking about how this
data came from the New York Times
api. And we were modeling for every article. We have the people and the topic and the geographic region that the article mentions. We also have organization. So it's like people, place, and thing, basically. So do we have any companies that are mentioned in the article? That would be an organization. These are the standard things you get when you run a natural language processing model on a piece of text. What's nice is this comes directly from the New York Times
api. So we didn't have to do any natural language processing to find those things. And then we also have information about any images, any photos that are in the article. So that's the basic
data model. So now that we know that, we can start to write our query. So we're interested in finding the 10 most recent articles. So I'm going to start constructing my query to look for article nodes. And let's start off. Let's return the article nodes. Let's look at the first 10. And so this A is a variable that gets bound to a piece of the pattern. So the thing after the colon is the node label, in this case, article. The thing before the colon is the variable to be bound to that piece of the graph that matches that piece of the pattern. And then we can refer to that variable later on in the query. So here we're saying find article nodes, return those article nodes, but return those article nodes, but only give me 10. And if I click on these, I can see the properties for the node. So here's an article about someone who illustrated children's books. We can see when it was published, the URL for it, and so on. But this is kind of an old article. We want the most recent. So let's add an order by 10, order by a dot published in descending order. Oh, my order by goes first. And then the limit like that. Cool. And so this is the most recent news, which is yesterday's article. So here's one about Victor Boot. So there's what? This is what? The prisoner exchange in Russia. And it's helpful to have some context about these articles. So if I double click, then we start to the graph. So here we can see the topics, the geo regions, the photos connected to the article, and so on. But I don't want to sort of double click on things to add this information to my query. We can construct a more complex graph pattern to describe that traversal in the query. So we want to include the topics, then we add a relationship piece to our graph pattern. So we want to include the topics, then we add a relationship piece to our graph pattern. So let's bring in the topics as well. And then when I return those in my return clause, I need to here I'm only seeing the article nodes because I'm only returning a, we could add T to that. Let's just add an asterisk to return everything that we have bound on. Cool. So now I'm seeing the most recent articles and the topics they're connected to. I could then go out and do things like let's find other articles connected to those topics as well and return those. You get the idea we can start to describe more complex pieces of our pattern. Cool. And that
database, again, that's public. You can use that using the credentials in the chat there to play around with this
data set. It's a fun one. It updates every day. We can also use visual tools to query this
data as a graph. I won't show a demo of this one, but Bloom is a graph visualization tool that allows us to explore, find insights with graph visualization interactively without having to write ciphers. This is a good tool if we want to expose the
data to, let's say, an analyst type who has some domain knowledge of the
data. Maybe they're doing something like a fraud detection investigation or something like this. If you're a developer familiar with Cypher, you can configure Bloom to include some saved Cypher queries for more complex analysis. We can use graph algorithms with Bloom as well to do things like run PageRank or
community detection algorithms just by a few clicks visually. That's a very compelling tool if you're not interested in writing Cypher to explore the
data set. We've seen some examples now of Cypher and of
graphql. I think it's helpful to compare these two and make sure that we're using the right tool for the right job, depending on what we're trying to accomplish, depending on which piece of our
architecture we're talking about. Conceptually, both Cypher and
graphql are working with graphs. We're querying and interacting with graph
data in each case. Let's maybe compare and contrast a little bit to see where we should use one and not the other. Cypher is a graph
database query language. We said we use this declarative pattern matching functionality where we draw this ASCII art representation of graph
patterns and then the
database figures out how to find where that
data exists or how to work with that
data. Cypher includes all the
database-specific functions we would expect, so similar things that we would find in SQL, things like aggregation functions, math functions,
database operations for things like creating indexes, even importing
data from CSV, and then lots of graph-specific operations, so things like a variable length path operator where I'm trying to find the shortest path between nodes, those types of things. If we look at
graphql, we said
graphql is a query language specifically for APIs, so
graphql is not a query language for databases. We'll see why that is in a minute. Then also,
graphql is this runtime for fulfilling
api requests. We have a strict type system that we talked about a little bit ago that specifically defines the
data that we're working with, and
graphql is modeling
data as a graph. It's modeling your application
data as a graph, so
graphql can be used with any
backend. We can build
graphql APIs on top of multiple
data layers and combine them together.
graphql can act as a federation layer. Then at query time, we're describing a traversal through this application
data graph that
graphql is allowing us to model using this idea of the nested selection set that we saw earlier. Using our articles
data set, let's see a few use cases and see how we would use Cypher, how we would use
graphql to find them. Well, this one we already did. Show me all of the articles. We saw how to do that in Cypher by defining the simple graph pattern we're looking for, which is drawing this ASCII article representation. We're interested in article nodes, returning them in
graphql. We find the query field entry point. In this case, we have one for articles, and then we select what fields we want to return. In this case, we're returning just title and abstract. We saw this one as well. Give me the most recent articles. Cypher has functionality built in for sorting, ordering, pagination, these sorts of things.
graphql does not have ordering, sorting, pagination built into
graphql, but we can use field arguments to model these sorts of things. There's some conventions out there for how to do this. Here we have the options field arguments on the articles query field, where we can specify the sorting and a limit here. How we can do pagination this way. We saw something similar to this. Show me the 10 most recent articles and the topics connected to those articles. The proper way to do this is to use what's called an optional match, because we may have some articles that don't have any topics. You can see this lone node down here is an article without any topic. First, we need to find the 10 most recent articles, and then we can optionally traverse out from those articles to find any topics. If we just included article has topic topic as this top level match here, we would only find articles that have topics. Anyway, that's how we can do that in Cypher. In
graphql, we just add a nested layer to our selection set. Here we've added topics and name to represent that traversal from the article nodes once we find them, to any topics that might exist. Because topics is a nullable field, we will find articles if they may not have any topics. Here's that one here. You can see the topics array. This is an empty array, which is similar in concept to this idea of the optional match. How about adding more complexity to our graph pattern? Now, we want to find the 10 most recent articles, the topics of those articles, but then other articles connected to those topics. Again, this is very similar to the example we saw a few minutes ago. We just add another piece to our graph pattern here. Now, once we've found the topic nodes for today's articles, we add another piece to the pattern to traverse out following that incoming has topic relationship to find other articles that have the same topics as today's articles. In
graphql, we just add another nesting to our selection set here to do that. Within the topics field here, so starting on line 7, on lines 9 and 10, we're now traversing to articles connected to these topic nodes. Okay, what about something like this? Find the shortest path between two nodes in the
data set. Here we want to find the shortest path from the National Park Service organization to the Federal Aviation Administration. Well, Cypher has a couple of built-in functions here that are very useful for these sorts of operations. One of those is this idea of a variable link path operator. Here, we have these brackets with an asterisk. We know that brackets represent relationships, so this is saying a pattern where here's our National Park Service node, here's our FAA node, their organization nodes. If I didn't say this earlier, the way we represent properties in
patterns is within curly braces, so this is saying find a node with a label organization that has the name National Park Service, similar for the Federal Aviation Administration. These are government agencies in the US, but this bracket with the asterisk, this is saying find a pattern where these two nodes are connected, but connected by any number of intermittent nodes, so follow as many relationships as needed to find a connection between these two nodes in the graph. That's what the asterisk means, and I can parameterize this. I can say more than two, but less than five, like the sort of thing. Typically, we don't want to have just this open-ended asterisk, but that's sort of the default, and this is wrapped in a shortest path function, so this is saying find where this pattern exists, these two nodes are connected following any number of relationships, but find me specifically the shortest path connecting these, and specifically Neo4j will do a binary breadth-first search to find the shortest path connecting these two nodes, and it ends up being fairly short, so here's the FAA, here's the National Park Service, there's an article about, the FAA is an article about the National Park Service, they're both about shortages is the topic connecting these two articles, specifically I think they're about worker shortages and having difficulty maintaining normal operations because of worker shortages, so it ends up being a fairly short path connecting these. Now if we think about how we would write this query in
graphql, well
graphql doesn't really have this sort of functionality built in, there's no concept of variable length path, there's no concept of the shortest path between two nodes, we could expose the sort of functionality if we added a query field that took in the sort of information, we could certainly expose this through
graphql, but it's not something that is built in. Here's another one, so show me recommended articles, so a common way to approach this, and if you're in the workshop on Tuesday we looked at this concept similarly for movies, but a common way to do this is to traverse the graph to find overlapping in this case topics or geo-regions or the author, so if I'm interested in an article that I'm reading that has certain topics, show me other articles that are about similar topics, if they have the most number of overlapping topics that's probably the the best ranked recommendation. How would we do this in
graphql? Well
graphql doesn't really have this sort of functionality built in, of course we could add a query field that exposes this sort of functionality, we would build that somewhere in the
data layer, but it's not something built in to
graphql. So then as we're thinking about how to architect our application, we know we want to build a mobile app that is allowing us to read the most recent news, personalize the news a little bit, or should we query the
database directly, do we want to use
graphql to do that? Well looking at the differences between Cypher and
graphql, we know we don't want to just expose the
database directly to our client, that's not typically what we want to do in most cases, we want to build some intermediate
api layer that sits between the client and the
database, allows us to handle things like authorization, caching, custom logic, these sorts of things that we want to control in this
api layer. So instead our
architecture should look something like this, where our iOS app is querying a
graphql api, in this case maybe it's deployed as a
lambda function or something like that, and that
api layer, that
graphql server, is the thing that is querying our
database layer. So let's talk about how we build a
graphql service. There's sort of a standard approach that we can take here, one is we start with our
graphql type definitions, so we define the
data that we are working with, and then we need to implement resolver functions. So resolver functions are functions that have the logic for fetching
data from the
data layer, whether it's the
database, whether it's unwrapping another
api, that's encoded in these resolver functions. Then we combine the type definitions and combine our resolver functions to have what's called a executable
graphql schema, which we can then expose over some networking layer to actually handle incoming requests. So here's an example, this comes from an app that was built for showing conference sessions, you can see some type definitions on the left that describe the types we're working with, so we have a type for the conference session, we have a type for the speaker that's connected to the session, and then things like what company does the speaker work for, what room is the session in, and what is the theme of the session. So then our resolver functions might look something like this on the right, where we have a map of functions that matches the type definitions, so for the entry point, we're not showing the query field on the left, but for the entry point we would have a session field on the query type, that's the root resolver, so in this case, we start by searching for a session with a search string, so imagine a website somewhere where you type in
graphql or whatever kinds of sessions you're interested in, and then this is using an ORM that is injected into this context object here, so the context object is passed to every resolver function, and this is where we can do things like add handles to APIs or databases, or often we may just have some other
data abstraction layer that we use in our resolvers, but here we're grabbing that
database handle for some sort of ORM type wrapper here to search for sessions by some search string, but then when the results of that query come back, so we found some sessions that match our search string, well then we have to go back to the
database to find out what room it's in, we have to go back to the
database to find out the theme of the session, and then another resolver function if we've asked for recommended or what are similar sessions to the ones we have searched for, that might be a fairly expensive operation depending on how we're doing that, and we have to do these these three things for each session that comes back from our search results, that could be lots and lots of round trips to the
database, and so this is what's called the n plus one query problem, this comes up when we follow that sort of standard approach for building
graphql APIs, and there are some ways around this, the one we'll see out there a lot is called
data loader, which is a combination of batching and caching to try to reduce the number of requests to the
database, another option is using these
database integrations that generate a single
database query from a
graphql request, which is what we're going to do today when we use the Neo4j
graphql library, but there's some other issues that come up as well right, so this is a lot of kind of boilerplate
data fetching code that we're writing, we don't necessarily want to be focusing on that as developers, we want to focus on things where we can typically add a bit more value, things like schema duplication, mapping and translation layer for not using graphs on the
backend, and our resolvers, we have to kind of think of how to map from the graph model that we're using
graphql to some other
data model, so this is where
database integrations like the Neo4j
graphql library come in, so in this case we're going to see how we can take just type definitions and generate a fully functional
graphql api without writing any resolvers, but to do that first we need to start with a
database, and so in this section what we're going to do is spin up a free Neo4j Aura instance loaded with some news
data, and then we can start to build our
graphql api, so let's all set up our Aura instance, so there's two things we're going to do here, one is we're going to sign into Aura, you can create an account with either Google sign-in or username and password, email and password if you don't want to use Google, and then we're going to load a
database dump file, so a snapshot of that news
data so that we all have the
data set loaded and ready to go, so the first thing we're going to do is go to neo4j.com slash Aura and you'll see like a start free sign in button, so go ahead and open that up, sign into Aura, and the first thing you'll be prompted with is option to start a
database, you'll see different options, I'll go through this in a minute so we can all see what it looks like, options for loading different
data sets, so there's one for movies, one for stack overflow examples, but we want to create a blank
database, we're going to load our own
data, and then you'll see a generated password pop up, be sure to copy that, paste that somewhere, we'll need to access that later, you can also download a .env file from that screen, so that's a good idea too, just to download that so you have it, and then we'll see the connection URI, so the connection string for your Aura instance as well, which is something we'll note for later. Once you've done that, then we're going to download this dump file, drop a link to that in the chat as well, so this is an archive or a snapshot of the news graph
data, and then we're going to import that into our Neo4j AuraDB instance, so if you click on your instance in the console, go to import
database, you'll see a place to drag and drop or select the dump file to import. So let's all go ahead and do that, so we have our
data ready to go, I'll go through and do that now so you can see what it looks like, and then we'll take a break for a couple of minutes to make sure everyone is set up with that and ready to go. So I'm going to go to neo4j.com slash Aura, and click on start free, and see there's different tiers for Aura, so there's the free tier, which is good for like these kind of workshops or hobby projects, and then there's the professional tier where we can start to scale up our
database if we have production deployments, larger
data sets we want to work with, and then of course there's an
enterprise tier if we need more features for that. So I'm going to sign in, like I said, we can either use Google or you can create an account with email and password, I'll just use Google since that's easy enough for me to do, and then oh I have an instance running, I'm going to kill this one, that's from, I think that's our one from the Tuesday workshop, so I'm going to kill that one, but if you haven't signed into Aura before, you won't see that, instead what you'll see is this screen that says get started by picking a
data set, and if we select one of these, we'll have a
data set already loaded, but I want this empty instance, I'm going to say create that, I'm going to download the .env file, and I'm going to copy my password and save it somewhere, so I have access to that later, yeah it's important always to make sure we grab that before clicking off this screen, since we can't find that initial password again. Okay so this will take a few moments, while that's spinning up, I'm going to download this news dump, so let's copy that, and this will just download a zip archive, and this will just download a zip archive from S3, that's fairly small, I think it's only maybe like 10 megs or something like that, and then once my Aura instance is up and running, this will take a minute or so to spin up, then we can import our news dump, once we have that running, you have just a preview of where we're going to go with this, and then we'll pause for a few minutes, so this will load the the news graph
data set, it's snapshot, so it doesn't have the most recent news, it's from, not sure when I took it, maybe a month or so ago, but the same basic
data model, so articles, authors, topics, people, organizations, and geo-regions about news from the New York Times
api, I linked the site for the New York Times
api, it's free, you just need to request a developer key to work with this
data, it's a good
data set for building applications, they also have things like book reviews and other, I think they have sort of their own knowledge graph for more information about people, these sorts of things, but if you're interested in more in this
data set, this GitHub repository, which I'll link in the chat, this has the code I showed earlier, the GitHub Action for fetching this
data, but then there's some examples for how to work with the
data in Cypher, there's a
graphql directory, which we're going to look at in a moment, and then also I did a workshop on building a
cloudflare Workers
api to fetch this
data. Anyway, so that is all online, let's see, is our Aura instance is not up yet, so maybe let's go ahead and pause here for a few minutes for everyone to have a chance to go ahead and sign into Aura, create a new blank instance, download the dump archive, and we'll wait a few minutes for that to spin up, and then load that
data set. So we'll pause here for a few minutes, maybe we'll come back at 15 after the hour, that's four minutes, so if you run into any issues, let us know in the chat and we'll get that figured out because we do want to have our Aura instance with our
data set loaded before we move on. While we're waiting, I'll just go through the steps here now that mine is running, we can tell it's up and running because we see this green circle that says running, so I'm going to click on this and I can see some sample code and whatnot, but I want to go to import
database, I can either drag and drop or I'm going to click, oops that's not what I meant to click on, that's why I have a larger
data set, I'm going to click on this browse, and this just downloaded to my downloads folder news-graph, mine has number three because this is the third time I've downloaded it, but it's called news-graph.dump, warnings is going to replace my empty
database, yep that's fine, and so this will take a few minutes to upload and then restart the
database, but okay now we will pause to give everyone a chance to go through this process and get your Aura instance set up and then when we come back, we will take a look at building a
graphql api, so I see a question from Anthony, oh yeah talking about the new UI in Aura and not having an option to upload a dump file only CSV, yeah so let's look at that, that's a good point, so there's a new workspace, I think it's called workspace experience for Neo4j Aura, and so you may, I think it's now the default, so you have this open button which my
database is restarting so it won't load right now, otherwise you can toggle between this, if I click on my user icon it says I'm using the new workspace experience, or I can switch back to the classic experience where I have things like explore, query, import, so that's one thing, we can toggle back and forth between those, I'll talk about what that is in a second, it's basically a different way of combining the things like Neo4j browser, bloom, and a
data importer option, so here's what that looks like, if I click open that will take me to to workspace and I can connect to my instance, and Anthony if you're looking at this import that's where the option for uploading CSVs is, but what I want to do to upload a dump file instead is to click on the card, like I should have said this earlier, not click on the open icon, but if I click on the card for the
database then I get this screen, and here I can go to import
database and click browse to find my dump file, so if you find yourself in this screen, so if you find yourself in this screen where it says import for uploading CSVs, that's not the one we want, this is the
data import tool, which is really cool, a way to visually define a graph model from CSV files, which is quite neat, the query bar, this is similar to Neo4j browser, we have a similar functionality here, and then explore, this is the bloom visualization tool, which I showed a couple of screenshots before, so the new workspace UI, the idea is to combine what were previously different developer tools into a single developer tool, anyway, yeah, so instead what we want is go back to the Aura console, click on the card for our
database and look for the import
database option, cool, cool, anyone else get stuck with anything, is there anyone else done, anyone else able to start their Aura instance and then also upload the dump file, let us know if you got through that, or even if you didn't, if you're stuck on something, once the
data is loaded, you'll see the number here for nodes, what do we have, we have 31,000 nodes and 80,000 relationships, and you'll see a percentage of 200,000 and 400,000, so the free tier has a limit on the size of the
data that we can store, so you can see our news
data set that we're working with is fairly small, so we have plenty of more space in our free tier, but that's what the limit there is on the number of nodes and relationships, just because we're using the free tier, if we're using the pro tier, we can choose to scale that up by memory for the different instance sizes, cool, I don't see anyone else say that they are stuck, so let's go back to the slides here, and we'll talk about the
data set, we already talked a little bit about the
data set, I talked a bit about where the
data comes from, I linked that GitHub page, and I said that we're using
github actions to do this, specifically we're using this action that I wrote called flat graph, so flat is a GitHub action that the GitHub open source team published for fetching
data from JSON APIs or from a
database, and then checking it into the GitHub repo, and flat graph was an action that I wrote that just allows you to write a cipher query to define how you want to work with that
data, so in our case we're using that JSON
data that the flat GitHub action fetches for us and then checks into the repo, then with flat graph we just write a cipher query that says how we want to load that
data into, in this case, a Neo4j aura instance, but you can point it at any Neo4j instance, so I thought that was a handy way of just kind of setting up a cron job to periodically fetch
data loaded into an aura instance, which is kind of fun, I have this running also for lobsters, if you know lobsters, it's a tech news site that, kind of similar to hacker news, but I think a little more friendly, so I also fetched the day's articles on lobsters using that same flat graph option, and then I wrote a couple of blog posts about how to do that, there's, I think we have, yeah here it is, there's a just a little visualization tool that I wrote, this also uses
graphql to give us a sort of visual representation of the day's lobsters articles as well, so this is querying a
graphql api to render this visualization, anyway that's a bit of an aside, let's see, we had an exercise here to write a recommendation query, maybe let's go through this one together, since we're maybe a little short on time, let's just do this one kind of quickly, and this will also make sure we're able to work with our aura
data, make sure we loaded the
data correctly, so now I'm going to click this open button, and this is going to launch Workspace, and again I think this is the default, so if you're using aura for the first time, I think everyone will see that, but you may also see this explore query import, so you can either hit query, which will take you to the Neo4j browser, or if you're using the new Workspace, just hit open, and that will then ask you for your Neo4j password, which popped up on the screen, that's the thing you had to click through to say, yes I did save that, cool, and I think by default first it takes us to explore, which is the visualization tool, but we want query, because we're going to write some Cypher queries, and so the first thing we can do is just make sure we have the right
data set, so I'm going to do call db.schema.visualization, and we can see this is the same
data set we were working with earlier, and here's the query we wrote earlier to find the day's news, order by published in descending order, show me the most recent 10, so here's the most recent news articles, oh yeah, and let's see, this is from June, okay, so this archive is a few months old at this point, so we have some old news, that's okay though, it's the same
data model, and we can double click to traverse out, to explore the graph, but okay, so the exercise for this one is, give an article, write a Cypher query to find similar articles, so we've got multiple workspace windows, let's close those, here's the one we want, okay, so give it an article, so let's just say limit one, so just assuming we're working with one article, here's Gerber baby, what is that, that's like the model for baby food, okay, there are actually multiple articles about baby food in our
data set, okay, so we're gonna write a baby food article recommendation query here, so if I'm reading this article about baby food, in our app, we might want to show other articles that the user might be interested in, based on the article they're currently reading, so you scroll through the article, you get to the end, and the question now is, how do I show sort of more articles for the user to read, they're probably interested in reading things similar to the one they sort of clicked on and read through, so how can we write a Cypher query to find similar articles to this one that we're looking at, so I'm going to change this return to a width, width just allows us to sort of pipe through results to my Cypher, later pieces of my Cypher query, and we're going to do another match, and we're going to say, so here's A, this is the article node, and what we're going to do is look for other articles that have similar, or the same topic, rather, and we're going to call that REC, so it's our recommended article, so here's articles that have at least one overlapping topic with our Gerber baby article, but we can score these as well, so we can use a count aggregating function to compute a score, so in Cypher, anytime we use an aggregating function along with some value, we implicitly group by the value that we're returning alongside the aggregating function. In SQL, you would write specifically a group by statement to do this. If you look in the table result, well here, let's return REC.title, so it's a little more obvious, so in this case, we're going to use a title, so it's a little more obvious, so in this case, the score is one, we're always finding just one overlapping topic, so the score doesn't quite help there, but can we add maybe some other pieces to the pattern here? No, we still just get one, so one thing that's nice is we can add other pieces here, so are there organizations that are mentioned, are there people that are mentioned, we can do this pipe which becomes an OR operation, here we go, we found one, so there's multiple articles about, I'm guessing, about Gerber since we added the organization, so now this article has a score of two because it has an overlapping organization and topic, so this is our top-rated recommendation for a follow-up article for a user to read, and of course, this is going to be different, we did like a, let's do a skip and a limit here to find other articles, let's find one that's not about guns and mass shootings, oh yeah, and let's order by order by score, so we want to show the top recommendations first, so here's some articles about coffee and caffeine, cockroaches, various health-related things, so this query should be good for sort of a general purpose article recommendation query, and so we'll use this later on to add some personalization to our news app, cool, so let's see where we are now, so we did that, now we're ready to build a
graphql api, did anyone have any questions before we move on to the next session, you can always ask any questions in the chats, but just want to call that out, oh and I'm also looking at Discord too, if you're asking in Discord, we can do that as well, but just be sure that that option is available to folks, if you get stuck on something or want to clarify something or want to dig in more to a certain topic, feel free to just go ahead and do that, if you want to dig in more to a certain topic, feel free to just ask in the chat, okay, let's talk now that we have our
database set up, we've got our news articles,
data loaded, our knowledge graph of news
data, let's see how we can now build a
graphql api to expose that
data to our client application, so we've talked about the Neo4j
graphql library a couple times now, we are going to use it to build a
graphql api on top of the Neo4j Aura instance that we each configured and set up just now, so let's talk a little bit about some of the features of the Neo4j
graphql library and how that relates to what we are trying to do with building our news application, so first of all the high level goal of the Neo4j
graphql library is to support this idea of
graphql first development, so the idea is we take our
graphql type definitions that define the
data model for our
graphql api, but also for the
database, so we're defining the
data model for the
database with
graphql type definitions, now we don't necessarily want to expose all of the
data in our
database, maybe we want to add some authorization rules, maybe we want to tweak some of the mappings for how we're exposing
data, and we can do that by adding schema directives to our
graphql type definitions, so schema directives are
graphql's built-in extension mechanism to indicate hey there's some sort of custom logic that should happen here, so we'll see a few of these, so here's an exclude directive, think of a directive as kind of like an annotation on a field or on a type, so this exclude directive is specific to the Neo4j
graphql library and this is saying exclude the following operations in the generated
api for the article type, so exclude, create, update, and delete, so because we're not adding
data to our
graphql api our news reader app is going to be just a reading app, we don't want users to be able to make updates to the
database from the app, so we're going to exclude any mutation operations, we also need to add the relationship directive to any relationship fields, so fields that are connecting types to include the direction of the relationship in Neo4j, so when we were talking about the property graph model earlier we mentioned that the property graph model includes a direction for every relationship, and then we can also specify the type of relationship, and this is nice because we have different conventions for the naming in the property graph model that we use with Neo4j and in
graphql, so here we're saying that the photo field which is a relationship field in the
database that's represented as has photo in what is this called snake case, whereas in
graphql we typically use camel case, and so that allows us to have a different mapping of how we want to expose that
data as a field in
graphql to how we want to store that
data in the
database. The concept here is
graphql type definitions define the
graphql api but also the
database, and we configure the generated APIs, we're going to generate a
graphql api using the Neo4j
graphql library, we configure that by using schema directives which are these annotations in our type definitions. The Neo4j
graphql library is going to auto generate a
graphql api from our type definitions, and so this is you think of this as sort of augmenting the type definitions to include things like the query or mutation fields, the arguments that we saw earlier for things like ordering, pagination, the filter arguments, and then adding types that are native in the
database, so things like the geospatial point type or the date type that we have in the
database, adding those to our schema in
graphql. Then at query time the Neo4j
graphql library is going to translate or generate a
database query from any arbitrary
graphql request, so here we're looking for the 10 most recent articles, some fields on the article node, the topics, that's going to be translated automatically with the generated resolvers to this cipher statement that's going to fetch just exactly the
data that we need from the
database. So far we've been talking about basic sort of CRUD operations, so create, read, update, delete, so searching, filtering, we've skipped over mutations, but by default we're also generating operations for creating nodes, for updating, deleting, those sorts of things, but how do we deal with custom logic? Well, for that we can use another schema directive, this is the cipher
graphql schema directive, where we can annotate a field in our
graphql type definitions with a schema directive and attach a cipher statement that defines custom logic, so now we've added a similar field we've added a similar field on the article type, so now we're using this cipher statement, and this is using a graph
data science function called jacquard similarity to calculate jacquard similarity of articles to generate recommendations, so that's another way of generating personalized recommendations, we saw previously this query where we were finding recommendations for an article by traversing the graph, so imagine we wanted to add this functionality to our
api so that we can expose custom logic, we would take this cipher query and we would basically add that cipher query here in our
graphql type definitions to expose that functionality through our
graphql api, so there are two ways to get started with the Neo4j
graphql library, one is we can build a
node.js graphql server application, and then use a
graphql server like
apollo server,
graphql yoga, any
javascript graphql implementation will work, or we can use a sort of low code in browser tool for development and
testing called the Neo4j
graphql toolbox, here's what this looks like for building a
node.js graphql server with the Neo4j
graphql library, we're going to install our dependencies, so the Neo4j
graphql, and you don't need to follow along, we're going to use a code sandbox that has this set up for us in a minute, just showing how we would get started, there's some dependencies we need to install like the Neo4j
graphql library from
npm, we need the
graphql javascript reference implementation and the Neo4j driver, those are peer dependencies of the Neo4j
graphql library, so the Neo4j
javascript driver just allows us to make a connection to our Neo4j instance from our
javascript code, and then whatever flavor of
graphql server we're going to use, here we're using
apollo server. Mohamed says, sorry for joining late, oh yeah no worries, thanks for joining, we're building a newsreader iOS app, you should be able to see the slides and the various repositories linked in the chat if you want to kind of follow along, yeah thanks for joining, no worries. Here's the basic snippet now for using the Neo4j
graphql library, basically we pull in those imports, the first step is defining our
graphql type definitions, here we're using movies and actors, then we create a driver instance with the connection credentials for our Neo4j instance, we pass the type definitions and our driver instance, when we instantiate the Neo4j
graphql, this gives us a Neo4j schema object which we can then pass to
apollo server to spin up our
graphql api, so that's one way building a
node.js graphql server, the other option, which this is really nice for
testing and development, is to use this tool called
graphql Toolbox, which is a low-code tool for working with Neo4j
graphql library and Neo4j, so we're going to start with this one, and this has a really powerful introspection feature, so because we're going to start with this one, and this has a really powerful introspection feature, so because we're starting with a
database, we can load type definitions that match the
database without having to write them automatically, so let's go ahead and open up
graphql Toolbox, and remove this piece of the instructions, that's no longer relevant, so what we're going to do is open up
graphql Toolbox, so here's the URL, I'll drop this in the chat, so we'll open that up, and then the first thing we're going to see is a prompt for what
database we want to connect to, and this is where we're going to use our Neo4j Aura instance, so here we're going to go back to the Aura console, and this connection Aura console, and this connection URI, so whatever that is for your
database instance, copy that, and then the username by default is going to be Neo4j, and then your password for your instance, cool, and this loaded, this has some type definitions from a previous project I was working on, but you'll see a box to ask if you want to introspect your
data set, so go ahead and click that to introspect the
data, what that is going to do is that's going to go to your Neo4j Aura instance where we loaded
data about the news articles, and generate
graphql type definitions that matches the
data that we have in the
database, so we'll see a type for article, a type for the geo regions, a type for organization, person, photo, and topic, and the connections between them, those relationship fields, and by default some of these names don't make a whole lot of sense, so the convention is to use the name of the relationship type combined with the node label for the field names, so things like article about geo geos, that doesn't make a lot of sense, we can change this, this is just sort of our initial starting point, so we can change this to geos, we can change this to organization, we can change this to people, and so on, for something that makes a bit more sense, and then if we hit this build schema button, that's now going to go through the schema generation process and generates a
graphql api based on those type definitions, and we can see the operations, this is a query from a previous project, I'm going to delete that, but we can see the entry points here, this is a
graphql explorer, you can also toggle the
documentation on if we want to see the
documentation view, the
graphql explorer allows us to see the query fields and the various options available to build up a selection set, so we want what probably publish date, title, and URL of the article, we want to limit, so you'll need the first 10, and let's sort by published descending, you can see how as I'm just sort of clicking through here on explorer, that query is getting built up in the query editor, we'll give that a run, and we should see the most recent articles in the
database, if I open up the developer tools, I'll go to the
javascript console, and we also need to enable
debug mode, and then build my schema again, but now when I run the queries, I'll zoom in a bit on the developer console, when I run the queries, I can see the generated Cypher statements, so here's the generated Cypher statement for this
graphql query, so this is really nice for development, I can see what
database queries are being generated for my
graphql, and I can also see the queries that I'm running, cool, let's pause here for folks to set up
graphql toolbox, point that at your Neo4j Aura instance, and write a few queries, if you already have that done, and you want to get ahead a little bit, think about how would we recommend articles that users might be interested in, so we saw the query that we wrote here in Cypher, and we talked about the Cypher schema directive, think about how we could update our type definitions here in the type definition editor to include that field on the article type to show recommended articles, so if you want to work ahead, think about that, we'll pause for a few minutes, and then when we come back, we will take a look at adding that recommended article feature to our type definitions, I'll drop a link to the
documentation, which we should be looking at that, so if we go to neo4j.com.docs, we have all the
documentation for all things Neo4j, but we're using the Neo4j
graphql library, so this is a link to the
documentation for the library, and then for that specific Cypher feature, if we look here under directives, we can see all of the directives available with the Neo4j
graphql library, specifically we want Cypher, so here's the docs for how we would handle that custom logic with Cypher, okay, cool, so I see a question from Anthony in the chat, this is in toolbox, I'm looking at the response, updated type definitions, toggle and enable
debug, but not seeing the
debug panel, yeah, so the way that works, I'll close this, so the way that the
debug option works, so here in the type definition screen, if we toggle this, and then hit build schema again, to go back to the query editor,
debug mode basically logs to the console, and so you have to go to open developer tools in your web browser to see that, so in Chrome, that's view developer
javascript console, if you're using Firefox or Safari, they have something similar, I'm not sure what the flow is to get that, but you want the developer console or the
javascript console, whatever it's called in your web browser, and then that will show the things that the application is logging to the console, and that's where you should be able to see the
debug output, how about everyone else, did everyone get the toolbox pointed at their Aura instance and generate type definitions, are folks able to write a
graphql query to find the most recent news articles, what about the recommended article feature, did anyone get that one, well let's take a look at that, so finding the most recent articles, we've seen that, we've done that one a couple of times now, this is what that looks like, we're going to use the options field arguments to do a limit 10 and sort by published in descending order for the articles, published in descending order for the articles, but the next question which is, okay, I'm seeing some articles in the app, I want to add some sort of personalization, so that after a user is done reading it, I want to show them similar articles, and we saw how to do that in Cypher, but we don't have that functionality exposed through
graphql, but we can express that custom logic in Cypher, so that's this query here where we were traversing from the article to find other articles that have overlapping topics, people, or organizations, and we're using the count of that overlap as sort of a score for the recommendation, so let's take this query, we'll just copy this, and go back to toolbox, and in the type definition editor, I'm going to add a field to the article type, and let's call this similar, and the similar field, this is going to be an array field of articles, and we're going to add a Cypher directive, and the Cypher directive takes a statement argument, which is going to be my Cypher query, and it's a little awkward, it's a long traversal statement here, but this is the same query we were looking at earlier, where we're looking at earlier, where we're looking for overlapping topics, people, and organizations. So this Cypher directive field, let me zoom in a bit, make that as big as I can, so what we're saying here is the article type, we're adding a field called similar, that's going to evaluate to an article object array field, but we don't just have this in the
database somewhere, so we can't just fetch that from the
database, this is something we need to compute using Cypher, and so the Cypher schema directive allows us to take a Cypher statement and add logic to a field, so that when we request a similar field, we are executing this Cypher statement, and so we need to tweak this Cypher statement that we copied and pasted a little bit, instead of matching on any article, we want to compute this recommendation for a specific article, and that specific article is the article that we're currently resolving, and so there's a convention here that we use to inject a Cypher variable called this, so this now refers to the node that we are currently resolving, so I don't need this width and the order and limit, and instead of starting my traversal from some node A, I'm going to start it from this, and what I'm going to return now is the recommendation, so now I'm going to return the recommended article nodes, and I'm going to go to build schema, and now if I look in explorer over here, I should have now a similar field, it's going to give me similar articles, and let's add title and URL, and let's run this, so this is saying find the 10 most recent article news articles, and then for each one of those, for each one of those, show me similar articles, and now, so here's red flag gun law, and the similar articles I'm getting to that are articles about gun control, school shootings, this kind of stuff, Anthony says, can I paste the snippet in the chat? Yeah, definitely, so here's the similar field that we added, let's grab that, I'll just paste that in the chat, hopefully that formatting is okay, there might be some weird spaces in there in the Zoom chat, I'm not sure, hopefully that works, okay, so one thing to think about is when we run this, we're returning as many similar articles as we find, which basically, just for this one article, this looks like hundreds of overlapping topic nodes for this article, so we probably want to tweak this a little bit to allow the client to say only show me the top 10 or top 3 or whatever, and so we can do that by adding a field argument here, so similar is going to take, we can call it first, and this is going to be an integer field, and we can give it a default value, so this is just saying we're going to add a field argument first, it's an integer, and we're setting that default value to 3, so now any field arguments that we define here, these are available in the Cypher statement as Cypher variables, so we can add a limit first here, we're only going to return the first by default 3, but we can configure that number, we just pass in a value, I like to add a default value when we do this because we know that this is always going to be defined, so when we reference these variables in Cypher, we know that those are always defined, so now I hit build schema, and then I execute the query, and now we're only getting three similar articles for each one, and we can change that to say let's just bring back one, and now we're just bringing back one similar article for each of our most recent 10 articles that we're searching for. Cool, so that's the Cypher directive, that is a super powerful functionality for adding custom logic to our
graphql api, we can really use any logic that we can express in Cypher here, we can attach to our
graphql schema to add that custom logic, which is a super powerful feature when we're using the Neo4j
graphql library, and we're also, let's look at the generated Cypher statement for this, looks a little weird, but we can see that we're generating a single Cypher statement, even with our custom Cypher statement that we wrote for finding recommendations, that's embedded in the overall generated Cypher statement as a subquery, which is really cool because we still are addressing that n plus one query problem with custom logic just by sending one round trip to the
database, so super cool feature, super powerful. So that was a look at Toolbox,
graphql Toolbox is still in beta, so not the finalized feature set or the finalized name even if you have ideas for naming, definitely taking suggestions there. Cool, so Toolbox, that's just a hosted web app, you can use that any time and just point it at a Neo4j
database. Let's take a look at the other option that we talked about, which is the case where we have an application that we want to build and deploy somewhere, so Toolbox is useful for
testing and development, but it doesn't give us a
graphql server application that we can deploy somewhere and query our clients using our clients. So now we're going to look at actually writing some
javascript, excuse me, some
node.js javascript code to build a
graphql server. So let's open up Code Sandbox and I'll drop this link in the chat, so go ahead and open up this link, this will open up Code Sandbox which is like a in-browser development environment, so this allows us to write
node.js javascript code just in the browser that runs on a container somewhere for free that we don't have to think about. This code you can see here, this links to a GitHub repository. Okay, and so what we want to do, this is just pulling the code from GitHub and we can see there's this .env file with a, this is a Neo4j
database that we were looking at earlier, although I did notice there was some DNS issue with this, so we want to replace this with our Aura
database anyway. What we want to do now is fork this, so we want to fork the sandbox so that we can make changes to it and it'll be personalized to us. In order to fork it, it'll ask you to sign in to Code Sandbox, which you can sign in with like GitHub or Google or create an account, something like that. But the first change I want to make is in this .env file, and we'll take a look at all the code in a minute, but in this .env file, I want to change the connection credentials to my Neo4j Aura instance, the
database that we created with our news
data. So I'm going to go back to the Aura console, I'm going to grab the connection URI from right here, so this is specific to whichever instance we created for ourselves, and that goes in the Neo4j URI environment variable. So this is a .env file that's just setting environment variables when our
graphql server starts up, and then we reference these to create a connection to Neo4j. So this, the protocol here, by the way, this Neo4j plus s colon slash slash, the Neo4j, this is the protocol, the binary protocol for how to connect to Neo4j, and then the plus s just means this needs to be a secure connection. If we didn't have that plus s, we would allow unencrypted connections, but with Aura, we have that ability to make secure connections, so that's what the plus s is, and this is just the domain for my
database in this case, yours will be different. The Neo4j user is going to be Neo4j, and then the password is going to be whatever your Aura password was. I'm going to paste mine in here. Okay, and then I saved that, and then I think I need to restart the server, maybe, to get that to pick up again. So that's going to restart my container to pick up those changes. Anthony asks, can you clarify syntax for providing arguments in a
graphql query? And so specifically with looking at the first argument in the similar field. Yeah, Anthony, in that example that you pasted, I see you have quotes around the one, and so that is going to make that a string with the quotes around it, and we specifically want to pass integers. But yeah, that's a good one. Let's do that right now, actually, for our... We'll do this in code sandbox since we're here. So let's look at the code. So here's our .env file. If we look at sort of package.json, we can just see what packages we're bringing in. We're bringing in the Neo4j
graphql library,
apollo server, .env is just for setting environment variables, and then the peer dependencies for the Neo4j
graphql library are the
graphql javascript implementation and the Neo4j
javascript driver. In index.js, we're pulling in those packages, loading our environment variables. Here we're creating a connection to Neo4j using the
javascript driver, and then we're loading our type definitions from the schema.
graphql file, which we'll look at in a minute. Then we're passing those type definitions in our driver instance when we instantiate a new instance of Neo4j
graphql. It's this Neo schema, and then we go through the schema augmentation process. So that's this neo schema.gitschema. This is an async function. The reason it's async is because there can be some index configuration directives. So we have the ability to say, hey, we should have an index or a constraint on this field. And so this is an async function because the Neo4j
graphql library will go to our
database and make sure those indexes are online before generating the executable schema object. And then we're passing that to
apollo server. We're using the
graphql playground
apollo server plugin so that we're just being consistent with using
graphql playground. The default now with the
apollo server is the
apollo Studio sandbox. Okay, here's our
graphql schema, and this should look pretty similar to the schema that we generated in our toolbox application. And so Anthony's question was on clarifying syntax for arguments in the
graphql query. So let's look at that. So if we go back to toolbox, I'm going to grab our similar field here that we added and go back to my code sandbox. And here we're going to, let's just use, let's use the extend functionality. So this is useful if we have our type definitions split up across multiple files, which is a common pattern. We can, instead of just adding a field in our initial type definition, we can use the extend to add fields. And we're going to add this similar field. So Anthony's question was, okay, here I've, let me paste this into chat as well. So we have the full thing. So this Cypher statement is finding articles similar to the article we're currently resolving. So that's this is the special keyword for the article we're currently resolving. And we added this first field argument with a default value of three that gets injected into the Cypher statement using Cypher variables here. With this first Cypher variable, we're referring to the field argument. And it has a default value of three. So if we don't specify it, then we, we're using that value of three. So I saved that change. I thought, I thought I had node ENV or node mon set up for this, but I don't. So I need to go restart. I need to at least restart the sandbox to pick up those changes. So let's restart the server again, pick up those changes. I think that's how that works. I should edit this to, if I had this using node mon instead of just node that I think anytime we change those files, it will update the app. So kind of a pain to restart our sandbox each time. So now go articles, options, limit 10. Let's not worry about sorting. And I can bring back the title and URL. Let's run that. Oh, can't connect to the
database. Yeah, I think for some reason that didn't pick up my changes to that dot ENV file. So I think we're still trying to access a different
database that's not actually available for DNS. So code sandbox is great when, when we don't have issues with it. But anyway, I think we should still see the syntax here. So similar first one title. So that's the syntax that we use. And so now that that we use. And so now that this similar with the first one is the field argument passed in to our cipher statement here. And now we get a different error. Why is that? Unknown function. Well, it shouldn't be unknown. This is my Aura instance. Yeah, that's odd. Yeah, something's going on. I think we're not. Oh, here we go. So now that picked up our
database change. Maybe our sandbox wasn't quite restarting. Not sure what the issue is there. Anyway, yeah, that is a look at the code that we use for writing a
graphql server using
node.js. So notice that we didn't have to write any resolvers. That is very nice for
developer experience that allows us to get up and running really quickly. Everything is driven from our type of everything is driven from our type definitions, which is super cool. Okay, cool. So we have a little bit of time left. So let's jump to talking about Swift UI so we can put our
graphql api into use in an iOS app. Swift UI is, like we said earlier, is Apple's UI framework for building iOS, macOS, and tvOS applications. I say one of Apple's UI
frameworks. There's UIKit, which is an older option typically used when Objective-C was the common language. Objective-C and UIKit are still around. When I was a mobile developer, that was what I was using. Although I did do a little bit with Swift when it first came out. I was working as an iOS developer for a company that made
mobile apps for the real estate industry. So something that allowed you to search for property listings. And then we would brand those for a real estate agent. So here's if you follow these steps in Xcode, which you don't need to. We're going to fetch an Xcode project that has kind of a skeleton for what we want to work with initially. But if you follow these steps in Xcode to create a new Swift UI project, you'll end up with something like this. This is the basic starting point. And so Swift UI gives you this content view struct, which allows you to then use what are called view modifiers and other views. So Swift UI basically allows you to compose multiple views and use view modifiers to style those views. So what does that mean? Well, here in our body variable, we're using a text view, passing in hello world to render in the text view. And this dot padding, that's a view modifier to tweak the text view. And then the text view is part of our overall content view. So we have just one view object here, but we could have multiple. This is just the default that we start with. And so the view modifiers are a declarative way of sort of saying this is how I want to style this. And then Xcode figures out how to combine the styling for multiple views to render our overall app. That's the basic idea of Swift UI. So if you're following along in Xcode, there's this GitHub project, which I will drop in the chat. If you don't have Xcode up and running, that's fine. I'll go through this. You can just kind of watch as we go through it. But if you have Xcode up and running, you can download that Xcode project from GitHub and open it up. And that has the code for basic skeleton for our app. We're going to tweak a couple of things to add some
graphql functionality. So I guess a few things from the screenshot. One is that on the right, we can see the preview of our app running inside Xcode, which doesn't seem like that big a deal. But if you've been a mobile developer, having to build your app and use a simulator to see any changes, having that preview that updates in real time as you're making changes to your Swift UI code is nice. So let's talk about how we can do
graphql data fetching in an iOS app with Swift UI. So we're going to use the
apollo iOS library. This is written in Swift by
apollo. If you're not familiar with
apollo,
apollo makes
tooling for
graphql both on the client and the server. So we were using
apollo server just a minute ago. That's maintained by
apollo. They also make client
tooling. I think the most popular version of
apollo client is the
react client for building
react applications. But they've also released and maintained
apollo iOS, which is a Swift
graphql client. So the main functionality in
apollo iOS, there's a few interesting things going on. One is caching. Caching is an important function for a lot of
graphql clients. We don't want to make lots of unnecessary requests to the server. So we can use in-memory caching or on iOS, and it's also true, I think, for the
apollo Kotlin, which is the Android clients using SQL lights, which is an embedded on-device
database for caching so that
data can stick around between app restarts, which is quite nice. The other big piece of functionality in
apollo iOS is code generation. So Swift is strongly typed.
graphql is strongly typed. So we can take advantage of the typing in both of those languages to generate code. And what kind of code are we generating? Well, a couple of things. One is we're generating model code for our models. And then the other thing is generating
api code for executing our
graphql queries. And we'll see what those look like in a minute. There are some other Swift iOS clients out there. There's one maintained by the Guild, which I think is just called Swift
graphql, something like that. So there are a few different options. I'm not too familiar with that one. I can't speak to what the differences are between that and
apollo iOS. There are also clients for Android. That's the
apollo Kotlin. And then also for
react Native, there's an
apollo client for
react Native as well. So these are kind of the steps that we go through for using
apollo iOS in a Swift UI project. And I guess I should say it doesn't have to be in a Swift UI project. We can use UIKit and Swift with
apollo iOS. And I think we can bridge Objective-C and Swift. So I think we can even use Objective-C to interact with
apollo iOS through kind of a Swift bridge, although I haven't looked at that recently. But these are the basic steps. So we need to add the
apollo iOS package, depending on which package management we're using. Swift package manager, I think, is now becoming kind of the default. But CocoaPods is still around. And there's another one, the name of which is Escaping My Mind, that we can also use. But we're going to use Swift package manager today. And then we need to download the
graphql schema. And this is a JSON representation of the schema that we download into our Xcode project. And the reason we do that is to enable code generation. So for the code generation to work, we need to know what is the
graphql schema that we're working with. Then we need to define any operations that we want to use in our app. So any queries, mutations, subscriptions, we need to go ahead and write those and have those available in our Xcode project. Then we can go through the code generation step, which is going to use our downloaded
graphql schema and the
graphql queries, the operations, going to be mutations as well, that we wrote and included in our Xcode project to generate Swift
api code and Swift model code for use in our Swift code. And then we can work with that
data. And we'll see how we can use Swift UI specifically to work with that
graphql data. So those are the basic steps. I'll show those sort of in a screenshot. These are set up already in that Xcode project that is available in GitHub. So this is how we use Swift Package Manager to add a dependency for
apollo iOS. There are a few different packages, depending on what we're trying to do. One of these, I think it's supporting subscriptions. We just need the
apollo package. Cool. So that will show up in Swift Package Manager as a dependency. Then the next thing we need to do is set up a build phase script to do two things. One is to download the
graphql schema. And then once we've downloaded the
graphql schema, we want to add a step in the build phase script to go through the code generation. When we add
apollo iOS as a dependency, we also bring in some command line tools that will enable downloading the schema and going through that code generation step. So this is a script that I just copied from the
apollo documentation and added that. So here we've created in the build phases script in Xcode, I've created a new build phase script. So this is going to run any code that we want to run. So this is going to run any time we build our project called
apollo graphql. And we can see what the script is doing here. Starting on line 26 is using the bundled command line tool to download a schema from some endpoints. And I've pointed it at the news graph endpoints. We're going to change this to point to our code sandbox
graphql endpoint. So that will download a JSON version of our schema in this schema.json. And then this next line, line 28, this is triggering the code generation to look at any .
graphql files. So those are going to be the operations that we've written. So any queries or mutations that we've written in our Xcode project that we want to use in our app, it's going to use those. And then also our schema.json, our
graphql schema file to generate
api.swift. So that's the generated
api code that the
apollo iOS is going to co-generate for us. Here's what the schema.json file looks like. This is just a JSON representation of our schema. This is a result of running the introspection query. And then here's the
graphql query that we wrote. So we're going to just search for the most recent articles. So giving the 30 most recent articles ordered by publish dates and the associated information for those. And then here is the generated
api.swift file. And so this we don't want to tweak. This is generated by that build phase script. And you can see basically it embeds the query that it picked up from any .
graphql files. So any of the queries and mutations, we just want to make sure that we're saving those as .
graphql files in our Xcode project. And this has the logic for interacting with our
graphql api. So then we just need to create a network class that in this case is going to create an instance of
apollo clients and the URL for our
graphql api. Then we have a few options for depending on kind of what paradigm we're following. The common way to, the common framework, common way to build apps with SwiftUI is to use model view view model, where we have a model class or struct that defines the
data that we're working with. We have a view that defines in SwiftUI how to construct the view given some model
data. And the view model is basically where we are interacting with the
graphql api. We may need to modify some of the
data that comes back depending on how we want to think of our models. What we're doing here in our view model, we've created an articles view model that we're saying is an observable object. And also we've added this publish directive here on our articles, which are an array of articles. And we define a fetch function, which is using our shared network class and
apollo client to execute the most recent articles query. This is from our generated
api that picked up our most recent articles,
graphql query that we wrote. So what's going on here? Well, the observable object and this publish directive, this is kind of similar if you're familiar with
react to the way that
data binding and
react works with state variables. So you can think of our view model as kind of a state object and indeed in our SwiftUI code over here, which we'll look at in a minute, we are declaring that our article view model instance is a state object. And so when that object changes, we need to re-render our view, take into account how that
data has changed. This is a really powerful feature of SwiftUI. We can then use that in our view to show the result of that
graphql data fetching code. Let's go ahead and open up Xcode and look at that. So if you downloaded the project on GitHub and open that up, you'll see exactly the code that we walked through. So we already saw what the schema.json looked like. Here's our articles.
graphql, the most recent articles
graphql query. And we saw here creating an instance of our view model. Let's look at the content view. So this is our SwiftUI code. And we're not going too crazy here. This is this is using a scroll view. So we say that our content view, which is the overall app, is composed of other views. And in this case, we have a scroll view. Then we're iterating over each article that we found in the article's view model. And because article's view model is an environment object, like a state variable is a way to think of that. As the article's view model changes, we will rerender pieces of our views. When the app initially launches, there's no
data. The article view model changes as
data comes back from our
graphql query. That triggers a rerender for iterating over each article. And then for each article, we create an article view card, which is another view that we've defined down here. And this is just a simple view for rendering this piece. So for each article, each article is a article card view struct. And that takes a title, an abstract, and then combines a couple of text views. We can see the view modifiers that we use here. Zoom in a little bit more. The view modifiers that we use here to do things like set the font for the title. We have the abstract text, and we have a simple divider. So our scroll view is composed of a bunch of these article card view structs, which is a view that we defined here that's composed of two text views and a divider view, taking in
data from our articles view model. We also wanted to find a preview provider. So when we're working with
data, we can either use the same environment object that we're using in our app. So this will actually fetch
data and use the fetch
data. Or if we want to, we can just mock some
data so we don't have to think about handling like network requests. Maybe we don't want to test that piece of our app. We could create a content view here in the preview that just has maybe some hard-coded
data or something like that. And that's how we get
data in the preview mode in our app, which is quite nice. And we can see, so that changes as we are making changes here. Let's see what this looks like. Let's set maybe medium or something. We can make changes and see how that changes live without updating our, without building and running Simulator. Let's go ahead and build our app in Simulator. Let's see what this looks like. So here's Simulator on a iPhone 14 Pro. And here is our app with the most recent article. So we're using the
apollo iOS library to handle our
graphql data fetching. We're querying a
graphql api that we've built using the Neo4j
graphql library on top of the Neo4j Aura instance, where we're using
data from the New York Times
api to show the most popular articles in a newsreader app, which is pretty cool. So that was a look at
apollo iOS. We have an exercise here, which is to do a couple of things. One is we want to change the
graphql api that we're using instead of that's in our network layer. This is sort of the default one that was up and running. We want to change this to the
graphql api that we built with Code Sandbox. And then we want to see how to incorporate some personalization features. How can we update that
graphql query to show maybe local news or show some personalization? But it seemed like there were some issues with Code Sandbox, and it's just a few minutes before the end of time on a Friday. So maybe we'll just leave that for an exercise for folks to do at home. So that's pretty much all that I had for us today. Here's a link to the resources from today. I'll drop a link to this in the chat if I can copy it. Copy link. There we go. So everything is linked in the slides. Which are available here. So that's probably the best place to go. If you have questions or comments or anything, let us know in the chats. But I think since we're so close to the end of time anyway, that we will call it a day there. Just to reiterate a little bit again on what we did was we looked at, we looked at Neo4j in the property graph model. We looked at the Cypher query language. So how do we query
data as a graph in a graph
database using Cypher and some of the graph pattern matching functionality there. We looked at
graphql. We sort of compared and contrasted
graphql and Cypher. Tried to think about when we want to use one versus the other. When it makes sense to use Cypher in the
database. When it makes sense to use
graphql with APIs. We took a look at the Neo4j
graphql library which allows us to build
graphql APIs backed by Neo4j. We took a look at the Neo4j
graphql toolbox. Sort of a low code way of building and
testing graphql APIs. We also looked at building a
graphql server in
javascript. So
node.js graphql server using the Neo4j
graphql library. And then we took a look at SwiftUI and the
apollo iOS client for building native iOS apps with
graphql. So we covered quite a bit. Hopefully that wasn't too much of a whirlwind. I don't see any more questions in the chat. So I guess we will call it a day. If you're interested in learning more things about
graphql or Neo4j, the best way to get a hold of me is probably on Twitter. My Twitter handle is here. I also publish a blog at ynwg.com. It's my personal site as well where you can find me. Cool. So I hope everyone enjoyed the
graphql Galaxy conference. I think today is the panel. The talks were yesterday, I think. So a question from Anthony. Will
graphql bindings be added to AuraDB and what will they look like? Yeah. So that's a good question. I think like we discovered,
graphql is not a
database query language. So we're not interacting directly with the
database with
graphql. A few
database folks have tried that and I think it didn't quite work out well. I think
graphql was designed to be an
api query language. And so we wanted to use it to build that
api layer that sits between the client and the
database. Having said that, of course, like the Neo4j
graphql library, the whole point is to make it easier to build
graphql APIs backed by a
database. So there's definitely space for these
graphql database integrations. Now, when we move to
cloud services, I guess the question is, what does that look like? So that would be something more like a managed
graphql service backed by Neo4j Aura. I think is what that would look like. And actually the
graphql team is looking into that and they are taking feedback. So if you notice on Toolbox, there's a link here at the top that says, want us to manage your Neo4j
graphql api, register your entrance here. And it's a Google form that's basically, this form basically asking for feedback about a potential
graphql api managed service that would integrate with Aura. So anyway, so it's a long answer to your question, Anthony. If
graphql bindings are going to be added to Aura, I think the answer is that would look something like a, think of like a
graphql as a service,
graphql managed service, where you have some interface more similar to Toolbox, where you're configuring an
api and that
api is then deployed somewhere managed by Neo4j combined with Aura. So something like that. You can also see maybe
graphql Toolbox integrated with the workspace flow in Aura with the other developer tools. That might be something that makes a lot of sense. So there's a lot of interesting possibilities there for sure. It's going to think so. So type definitions we saved to the server, then what? Yeah. So so it would be basically with Toolbox, you have type definitions and a query editor, and this is all in your browser. The next step would be something like deploy this
api. And what we did here is we sort of took the
api type definitions and then we went to code sandbox and that was managing a
graphql server application for us. But in sort of the
cloud world, rather than building our own
node.js server that we have to manage, how could we sort of think of integrating that into a
cloud service where the just like
serverless doesn't mean that there isn't an actual server. It's just that as a developer your sort of layer of abstraction is no longer a server. So taking that concept where the layer of abstraction for the developer is your type definitions. So we saw how we can use these type definitions and specifically directives to configure the generated
api. So a managed
graphql service I think would look something like that where your layer of abstraction is the type definitions and that's how we're configuring as a developer the
api. And then there's some
cloud service integrated with Aura behind the scenes as a developer we don't have to think about that's deploying and managing a
graphql endpoint for us. I think that's sort of the shape that a managed
graphql integration with Aura might look like. And then Anthony says the client would be different because it doesn't know about the schema just endpoint. Yeah so then for the
graphql clients it sort of doesn't matter where that
graphql service is hosted. It's just a
graphql endpoint and through the powers of things like introspection and all the other developer
tooling that we have with
graphql we can build apps that take advantage of that. And again yeah I mean this is not something that exists today. Something though that I think folks at Neo4j are thinking about. I think it makes sense sort of the next evolution. If you think about it the Neo4j
graphql library which this is one of the pages that we've linked that has a lot of overviews here talks about you know all about the features for building this
api layer but there's still a lot that you kind of have to manage and think about as a user that maybe necessarily don't add a lot of specific value right. Like we have to manage a what is essentially an express
node.js app and deploy that somewhere and scale that horizontally with multiple instances and like that's not really something that developers are able to add competitive advantage around anymore right because we have things like
lambda functions that we can just sort of use to deploy these apps. And so I think it's largely thinking about what are some of the common boilerplate things that developers are doing that don't add a lot of competitive advantage to their app. What kind of what are some of those features we can move into the move into
cloud services. And so yeah so again like thinking of Cypher versus
graphql like Cypher you know has its has its use cases for interacting directly with the
database and when we're building those kinds of applications that we want to have that sort of logic querying the
database directly with the power of Cypher that's sort of the time and place for it but when we're building the more sort of general purpose
api that's sitting between client and the
database graphql is a great is a great option for that. Again
graphql is typically not something we want to think about as interacting directly with the
database we want that
api layer and there's all kinds of features too that we didn't talk about today like authorization I think there's some examples on this page where we can add authorization rules to specify like only users who created an order should be able to edit it like these sorts of things this sort of functionality you don't necessarily have in a
database query language these are like application level authorization functionality. So yeah understanding you know like how how Cypher and how
graphql fit into different pieces of your application
architecture hopefully we touched on some of that today. Well cool well thanks a lot hope everyone has a great weekend and thanks for joining and thanks for hanging out at
graphql Galaxy. We will see you next time. Cheers everyone.