Using Neo4j 4.2 With Cloudflare Workers
Building a location aware endpoint with edge handlers using Jolt, Cypher, & HTTP
In this livestream we'll take a look at the new Jolt format introduced in Neo4j 4.2 for using Cypher over HTTP. Then we'll build a location-aware endpoint using Cloudflare Workers and Neo4j.
Links And Resources#
- Introducing Neo4j 4.2 blog post
- Neo4j 4.2 release notes
- Neo4j HTTP API
- GRANDstack documentation
- GraphQL Architect
01:57 hey folks 01:58 welcome to the neo4j stream my name is 02:01 will 02:02 and today we are taking a look 02:06 at some of the new features introduced 02:08 in 02:09 neo4j 4.2 so 02:12 nifty 4.2 was released 02:15 earlier this week just two days ago 02:19 so we'll talk a little bit about some of 02:22 the the new features 02:26 and oops sorry i had some some feedback 02:29 audio there 02:30 yeah um we'll take a look at some of the 02:33 new features 02:34 in neo4j 4.2 but 02:37 what i want to do is specifically dive 02:39 in on 02:41 one feature that i think is really 02:43 interesting 02:45 and that is an update in 02:48 the neo4j http 02:52 api so typically if you've built an 02:56 application 02:57 using cipher and neo4j you've probably 03:01 used one of the 03:02 language drivers like the javascript 03:04 driver the java driver 03:06 for neo4j that allows you to send cipher 03:09 queries to the database 03:11 and work with the results in the 03:14 language of your choice 03:15 and not really have to think about the 03:19 underlying transport and serialization 03:22 layer that's going on under the hood 03:23 which is which is bolt 03:25 but there are some cases where you may 03:28 want to use 03:29 the http api which allows you to 03:32 send cipher requests 03:35 and work with data using 03:38 http instead of the bolt protocol and 03:41 instead of using one of the 03:43 language drivers for neo4j and 03:46 specifically 03:48 the use case we're going to look at is 03:51 if we're building a cloudflare 03:55 edgeworker function so we'll talk a 03:58 little bit about 03:59 what cloudflare workers are what the 04:02 http api is 04:04 how we can use that and what is new in 04:07 it 04:09 but first i want to take just a little 04:11 bit of a 04:12 an overview look at the neo4j 4.2 04:15 release 04:16 which like i said came out 04:19 just on tuesday of this week 04:22 so this is the blog post 04:25 from my colleague richard who richard 04:27 who's a product manager 04:30 for the neo4j database drop a link to 04:33 the blog post there so you can 04:36 so you can read that and he highlights 04:39 some of the 04:40 some of the features that are new in 04:43 ufj 4.2 um he makes a good point here 04:47 that you know with with product releases 04:51 and especially in the database world 04:55 you know there are some releases that 04:56 are are sort of 04:59 breaking new ground uh we'll talk about 05:02 maybe some of the greatest hits of neo4j 05:05 releases 05:06 in a minute where some really 05:09 groundbreaking new features are added 05:11 that enable new cases new use cases new 05:14 ways of using neo4j 05:15 introduce architecture changes 05:19 and things like that and 05:22 then there's other releases that are 05:25 more like 05:26 incremental uh improvements 05:29 where they focus on maybe stability 05:32 performance um those sorts of things 05:36 rather than changing the architecture 05:40 of the database or introducing new 05:42 features 05:44 uh and as richard points out this uh 05:46 this 4.2 release 05:48 is focused around things like 05:51 performance 05:53 stability security improvements so you 05:56 won't see 05:57 i think in the 4.2 release these sorts 06:00 of 06:01 groundbreaking releases features that 06:05 are introducing 06:06 new ways of new using neo4j new 06:08 architecture 06:09 and that sort of thing um so this blog 06:13 post you know 06:13 gives you i think a good high level 06:15 overview of 06:17 what's better relating to performance 06:23 relating to operability so 06:26 easier ways of using fabric and 06:29 neo4js sharded architecture 06:33 uh improvements to the cypher planner 06:36 uh and then of course talking about 06:39 how efj 4.2 is available 06:43 on aura and actually it has been on 06:46 aura for several months so aura if 06:50 you're not familiar 06:51 with aura neo4j aura is 06:54 everyday's database as a service 06:56 offering 06:58 and what's neat about aura is we don't 07:00 have to think about 07:02 managing upgrades and that sort of thing 07:05 these sort of rolling upgrades happen 07:07 behind the scenes so 07:09 if you've been using neo4j aura 07:12 well you've already been using neo4j 4.2 07:17 so that's a good uh overview blog post i 07:21 think 07:21 from richard let's dive into 07:24 a little more technical 07:28 detail here i think i have 07:33 the release notes 07:37 so i won't go through the release notes 07:40 but i want to at least drop a link 07:42 in the chat so you can dig into that 07:46 that goes into a lot more detail of some 07:49 of the new features 07:50 in the 4.2 release across lots of 07:53 different 07:53 functional areas and also pointing out 07:57 some 07:58 any important changes in configuration 08:00 and that sort of thing 08:03 uh what i do want to take a look at 08:07 is more of an overview 08:11 of where this release fits into 08:16 some of the previous releases and 08:18 functionality 08:19 that's been released in neo4j in 08:23 the last few years and you know i 08:26 already hinted at 08:27 today the feature i want to dig into is 08:31 using the 08:34 cypher transactional http endpoint and 08:38 this new jolt format so i want to 08:41 highlight specifically sort of how 08:43 the api changes for neo4j 08:47 have maybe evolved a little bit and how 08:50 that fits in 08:51 so going all the way back to the 3.0 08:54 release 08:55 which was in april of 2016. 09:00 this was i think one of those 09:02 groundbreaking 09:04 game-changing releases for neo4j because 09:08 it introduced the bolt binary protocol 09:13 so previous to this 3.0 release 09:17 the way that we interacted with the 09:19 database was 09:21 by sending cipher queries over 09:24 http and we got back 09:27 json now there were there were language 09:31 drivers that were built 09:33 uh on top of that http layer previously 09:36 so 09:37 as an application developer you may not 09:39 have actually realized that your 09:41 requests were going over http and being 09:43 serialized 09:44 to json but that's what was going on 09:48 and the 3.0 release introduced the 09:52 bolt binary protocol and 09:55 official language specific drivers for 09:57 neo4j 09:58 so you now had 10:01 a more efficient protocol for 10:05 serializing data coming back from neo4j 10:09 but you also now had 10:13 a bolt type system so you could 10:18 clearly encode types using 10:22 bolt bolts the binary protocol is 10:24 similar to 10:26 message pack if you're familiar with 10:28 message pack 10:29 but it's basically a way to ensure that 10:31 when you're talking about 10:33 say a date time type or you're talking 10:36 about 10:37 one of the geospatial types like a point 10:41 or a float that you're not relying 10:44 on how the client chooses to interpret 10:48 the json instead that is 10:51 clearly expressed in a compact binary 10:54 format 10:56 so bolt was introduced in the 3.0 10:59 release 11:00 in 2016 uh that then enabled 11:05 exploring adding some of these new types 11:08 to the database 11:09 and really building out the 11:13 driver functionality so later on you saw 11:17 the date time and spatial types that i 11:19 mentioned uh added 11:20 to neo4j which previously we would have 11:24 had to 11:25 think about how to represent those in 11:26 json because we have bolt didn't have to 11:28 really 11:30 think about that too much in our 11:32 application 11:35 and then along the way right there's 11:37 been new 11:38 clustering architecture that's 11:41 introduced 11:42 new language drivers graph algorithm 11:45 functionality with the graph data 11:47 science library 11:50 and then that brings us to the 11:55 x 4.x of the 4.0 series 11:58 i think 4.0 was another one of those 12:03 groundbreaking fundamental 12:08 releases this brought um 12:12 improv improved cluster performance 12:15 um but it also brought things like 12:19 using multi-database functionality it 12:23 also brought in 12:24 more granular granular role-based access 12:28 control 12:30 [Music] 12:32 and later on in 12:36 4.1 we saw more improvements 12:40 in these areas also things like 12:44 fabric and sharding were also very 12:48 groundbreaking foundational features 12:52 so that brings us to the the 4.2 release 12:55 which we can see again like we said it's 12:58 very much focused 12:59 on performance improvements 13:02 uh improving scalability 13:06 and those sorts of things and here we 13:08 have a few things 13:09 talking about this concept of content 13:11 negotiation 13:12 for the http api and a lossless 13:15 interchange 13:16 format for the http api 13:21 so that's what we're going to dig into 13:22 today are these changes 13:25 in the http api 13:32 so the first is 13:36 this idea of content negotiation and a 13:39 new 13:40 result format 13:43 to represent the neo4j type system 13:48 so what this means is content 13:49 negotiation this means that you can 13:51 specify 13:53 that you want json results so if i send 13:57 a cipher request 13:58 over http and i get back either json 14:02 or i can now say i want 14:06 the jolt representation 14:11 so the json response for the http api 14:16 that's been around for a while what's 14:18 new is 14:19 this jolt representation so jolt 14:24 stands for jason bolt so it's a way 14:27 of serializing the types that we have 14:31 from bolts or these native database 14:33 types serializing those 14:35 in a json-like format that also 14:39 preserves their types and is also 14:43 small and efficient 14:46 so let's jump over to the 14:50 neoj docs and we'll talk a little bit 14:53 more about 14:55 the http api and then we'll jump into 15:00 doing some hands-on things and building 15:03 a cloudflare 15:04 worker in a minute so there's the link 15:07 to the 15:08 http api docs 15:12 if we take a look at the 15:17 discovery api 15:23 so by default if we're running neo4j 15:25 locally on 15:27 localhost 7474 15:30 we can make a get request 15:34 and we get back the different 15:37 hp endpoints that are available so by 15:39 default these are enabled 15:40 you can disable different components 15:44 of these but you'll see that 15:47 there's the bolt endpoint and this is 15:50 typically what we use 15:51 when we're building applications 15:53 typically we want to use 15:55 the bolt endpoint using one of our 15:57 language drivers 15:59 but we also have this transaction 16:02 endpoint so this is the cipher 16:06 transactional endpoints we can send 16:08 cipher queries 16:09 to this endpoint and that's where we get 16:12 back 16:12 results via json or now via jolt 16:18 so let's take a look at 16:21 the cipher transactional api 16:24 [Applause] 16:26 this is an important diagram to help us 16:28 understand 16:29 the options here so 16:33 it's a transaction endpoints we can use 16:35 it to manage 16:36 transactions in the database 16:40 we can open a transaction 16:44 and then send other http requests with 16:47 more cipher statements 16:49 to be run in that transaction and then 16:51 either commit or roll back the 16:53 transaction 16:54 once we've opened it or in a single http 16:57 request we can say open a transaction 16:59 here are the cipher statements that i 17:02 want to run in this transaction and 17:04 commit it 17:11 and here's the structure 17:14 that we send in the body of our request 17:17 so we basically say here is a list 17:20 of statements cipher statements that we 17:23 want to run 17:24 here are any parameters 17:28 for that statement and that's 17:31 that's basically it and then what does 17:34 the result format 17:35 look like well if it's json 17:39 we get back 17:42 results in this format um so 17:46 columns where the cop what are the 17:47 columns that our cipher query returns 17:50 uh what data is it returning represented 17:52 in 17:53 json but if we use the new 17:57 jolt format then 18:00 our results will be encoded somewhat 18:03 differently 18:04 to be sure to encapsulate the types so 18:07 that was one problem with just using 18:10 json 18:11 is we're not able to always encode the 18:14 types 18:15 and sometimes 18:18 types can be misrepresented by the 18:21 clients when they're 18:22 deserialized so if we're working with a 18:25 date time 18:26 object we want to make sure that that is 18:28 being expressed 18:30 so here's the example of how we 18:32 represent that so 18:33 let's say that we have a date time 18:37 property well in jolt we will use the 18:43 we'll encode this as an object so we'll 18:45 encode the 18:47 date time value as a singleton object 18:50 where the key of the object is uppercase 18:53 t 18:54 that indicates that it is date time uh 18:58 and then the value so that our client 19:00 knows how to 19:02 uh deserialize that date time value 19:05 similarly for geospatial geospatial we 19:07 have uh what's the at sign 19:10 as the key that says hey this is going 19:11 to be a geospatial 19:14 type and we use the well-known text 19:16 format which is a 19:18 common way to represent geospatial types 19:23 now you can also return nodes and 19:26 relationships 19:28 so we also have a way to specify those 19:32 as well 19:33 so nodes which i quite like are 19:35 represented 19:36 by an open and closed parenthesis 19:39 which is how we represent those in 19:41 cipher so that that's 19:43 um i think a nice representation 19:46 and we include things like the 19:49 node id the labels of the node and then 19:52 any properties 19:54 that are stored on that node as well 19:58 and any properties again are represented 20:01 using that singleton object encoding so 20:05 z in this case if we refer back to our 20:08 table here z means that's an integer 20:12 u means that is a string 20:18 relationships are represented with the 20:21 key 20:22 either uh dash uh 20:26 greater than or less than dash which is 20:29 our sort of 20:30 ascii art directed way of drawing a 20:34 relationship 20:35 in cipher pattern matching so again this 20:37 is should be familiar 20:39 if you are familiar with how we define 20:42 patterns in cipher 20:48 uh okay cool so that's um that is 20:52 an overview of jolt and 20:55 the cipher http endpoint 21:00 um let's take a look at how 21:04 we can actually use this 21:08 so i have a data set 21:12 let's see am i running this locally i 21:14 think i am 21:16 uh yeah so i have this data set um 21:21 that i've been playing around with that 21:24 has 21:25 us election results 21:31 visualization let's look at the schema 21:34 and the schema is pretty simple so 21:37 we have states we have counties 21:41 counties are in estates i also pulled in 21:44 airports which may seem weird for an 21:47 election result 21:48 data set but we'll we'll see in a minute 21:51 why we have those airports so 21:55 the data that we have here let's look at 21:58 oh i don't know delaware 22:01 let's reset our styles we lost 22:05 some of our colors there there we go 22:13 okay so here's delaware and we have 22:17 some data that we're pulling in 22:20 so things like the number of total votes 22:24 in the state which candidate was 22:26 declared a winner 22:27 and then each state is connected 22:30 to counties or say each state is 22:33 composed of counties so delaware 22:35 has three counties sussex kent and 22:38 newcastle 22:39 and as properties on these counties 22:42 we're storing 22:43 the number of votes that went to each 22:45 candidate 22:48 and in this case we also have the 22:51 data from 2016. so the total number of 22:54 votes that were cast in 2016 22:56 as well and then we have airports 23:00 so for the airport we know the code or 23:02 the airport the location 23:04 which is a geospatial point and then its 23:07 name 23:09 so this data 23:13 i started playing around with on 23:15 election night so i thought it would be 23:16 fun to explore 23:17 some of this data in neo4j so have that 23:19 lean around so we'll use that 23:24 so i'm going to switch over to 23:28 postman so postman 23:32 is a nice tool for 23:37 text a bit bigger there we go postman is 23:39 a nice tool for 23:41 sort of testing apis it allows us to 23:47 specify headers and bodies and 23:50 authorization 23:51 and things like that um in a way that 23:54 we can then save later we can also 23:56 export 23:57 the code for it in different formats 24:00 which i like so we're going to do 24:04 starting off here is 24:07 make a request 24:12 to localhost 24:16 747 db 24:19 neo4j tx slash commit 24:23 so this is we switch back to 24:26 the docs and look at our discovery api 24:30 page 24:32 this is the default transactional cipher 24:35 http endpoint so 24:40 uh logoh7474 slash db 24:44 and then slash the name of the database 24:47 so 24:48 starting with neo4j 4.0 we have 24:52 multiple databases so we need to specify 24:55 the name of the database 24:56 by default the database name is neo4j so 25:00 i'm using the default database name here 25:08 and if we just send this 25:11 we get a no 25:14 authentication header supplied error so 25:16 let's add 25:17 our authorization header 25:22 now the http endpoint uses basic auth 25:27 so postman has a nice way 25:32 for us to add that 25:36 so we add our authorization header 25:41 and 25:44 method not allowed right so we want to 25:46 send a 25:47 post request not a get 25:50 and cool now we get back 25:54 some results so this is a 200 25:58 okay response results is a blank array 26:02 so no results no errors and well we 26:05 didn't send any 26:07 any cipher queries that's why we didn't 26:11 get any results 26:12 so we can send a raw body 26:15 and if we go back to the docs here and 26:18 to the cipher transactional api 26:22 and query format 26:25 let's copy this example so this is the 26:28 format 26:30 that we want to use for our requests 26:34 and let's delete 26:38 the second statement we only need to 26:39 make one 26:41 statement here to simplify things 26:45 let's zoom out a little bit so we have a 26:48 bit more 26:48 screen real estate to work with 26:53 okay so instead of a create statement 26:55 let's just run a simple 26:58 match in return count 27:01 in as number 27:06 so let's count all the nodes in the 27:08 database 27:12 okay unsupported media type 27:15 so let's go to our headers we want to 27:18 make sure that we are 27:20 sending 27:24 json so content type 27:29 we need to add a new let's add a new 27:34 content type 27:38 is application 27:40 [Music] 27:41 json and we want to accept 27:50 accept application 27:54 json so let's see what the 28:00 json representation of this as before we 28:04 switch to the jolt format 28:09 okay so i get back some results the 28:11 columns so what are the columns that i'm 28:13 returning from my query 28:14 well num is the only 28:17 column that i'm returning and it has 28:21 12 269 nodes in the database 28:26 okay let's make this query a bit more 28:30 complex so if i go 28:34 to neo4j browser 28:40 and i write a query that is something 28:43 like 28:46 find delaware 28:56 and let's find 28:59 how about the airports in 29:02 delaware 29:08 so here's delaware and the airports so 29:11 now instead of our previous query 29:14 that was returning 29:18 just a single number now this query is 29:21 returning 29:23 nodes and relationships so 29:26 let's grab this query 29:30 go back to postman here 29:33 and notice we're using parameters so 29:36 instead of hard coding delaware let's 29:39 switch this to 29:41 a parameter called state 29:46 where the name is delaware 29:53 that says parameter missing 30:04 so just uh 30:07 state delaware 30:11 there we go 30:14 so here's the json response for this so 30:17 three columns a r and s so a is the 30:20 airport 30:20 r is the relationship s 30:24 is the state 30:29 and here we have the airport 30:34 node with its properties and we have 30:37 some metadata 30:38 that's telling us okay this is a node 30:41 this 30:41 is the node this is its id 30:46 the next object is a relationship 30:52 here so okay this is a relationship and 30:55 actually this is the relationship 30:57 doesn't have any properties the third 30:59 object 31:00 is of type node 31:05 so we're also representing 31:11 the location as an object 31:14 type and coordinates and linking to the 31:16 crs and that sort of thing 31:19 so this is the the json representation 31:22 which 31:23 you know like we said earlier doesn't 31:25 always 31:26 encapsulate encoding of the types 31:31 so what we want to do now is look at the 31:34 jolt format so we go back to the headers 31:40 and instead of the accept header 31:44 application json 31:46 if we look in the docs 31:50 it says that for the jolt format 31:55 we can add this to the request accept 31:58 header 32:02 and if we make that request again 32:11 what happened there got an error 32:17 replication vmd 32:24 near j 32:36 replication vmd neo4j dot 32:40 jolts messy cue 32:49 what did we do wrong there 33:03 content type except 33:14 oh am i oh i'm not using a 33:18 4.2 database oh that's why 33:21 so uh this is 33:25 a 4.1 database 33:31 let's that's an important 33:35 distinction so i'm getting this this 500 33:38 internal internal server error 33:40 when i switch 33:43 the accept header to 33:46 tell me that i want jolt and that's 33:49 [Music] 33:50 because uh 33:52 this is a 4.1 version of the database 33:55 which doesn't 33:56 recognize that jolt format so i forgot 33:59 to 34:02 switch to a different version of the 34:03 database but that's okay i have 34:06 i have a database running in the cloud 34:11 somewhere elections.graph.zone i think 34:15 it is 34:18 i'll have to change the header 34:23 the authorization header 34:28 let's try that there we go 34:34 so 34:37 same cipher query uh it's the same data 34:40 set just in a 34:41 a different database that's actually a 34:43 4.2 version 34:44 and so now now we can see what jolt 34:47 actually looks like here so 34:50 here we have 34:53 the header with the fields that we've 34:57 returned so ars 34:58 a is the airport ours the relationship s 35:01 is the state 35:02 node um and that's that's an object 35:05 so you'll notice that this isn't this 35:07 isn't quite json 35:08 right like this is a kind of like a 35:11 streaming 35:12 format so um 35:15 inspired by json but not quite exact 35:18 json 35:18 but here we can see okay here's the data 35:23 and this first object that's returned 35:26 the key 35:27 is an open and closed parenthesis that 35:29 indicates 35:30 hey this is a node this is the 35:33 internal id of the node and these are 35:36 the labels 35:37 of the node in this case it has the 35:40 label 35:40 single label of airports but nodes can 35:44 have one or more labels 35:45 that's why zero or more labels really 35:48 but that's why this 35:49 is a array to represent 35:53 the labels then the properties 35:57 and we didn't specify 36:00 the strict mode for jolt so if you 36:03 remember 36:04 in the 36:07 [Music] 36:09 jolt encoding table that we saw here 36:12 said that well hey if you have a string 36:14 we're going to represent it 36:15 as an object where the key is a u 36:19 but if we look at our string here well 36:21 it's just a string 36:22 and that's because by default anything 36:26 that 36:27 can be represented in json without 36:30 sort of not encoding the type so json 36:34 can represent 36:35 strings floats 36:39 integers without 36:42 specifying the type so those are left 36:46 off we can add 36:52 strict equals true 36:56 to the header 36:59 let's try that 37:09 if we add strict equals true then you 37:12 see yep 37:12 now all of those type encodings 37:16 are used even for 37:20 properties that are not ambiguous 37:26 but if we don't need that let's remove 37:30 strict mode 37:35 uh so a question from the chat how safe 37:38 is it 37:38 against cipher injection 37:46 well um i guess do you mean 37:49 do you mean in the sense of if we're 37:52 taking 37:53 some user input from our application 37:56 and just passing that through as 38:00 as like a parameter or something like 38:02 that um 38:05 yeah i mean i think we we want to 38:09 sanitize our you know user inputs and 38:14 use database parameters wherever we can 38:19 i'm not sure of other other types of 38:22 cipher injections 38:23 if you could give me an example we can 38:26 dig into that 38:30 um okay so 38:34 that is the basics of 38:38 the http transactional cipher endpoint 38:41 and jolt uh one thing i'll point out 38:45 this is one thing i i really like about 38:47 postman is we've 38:49 we've now like built up our requests and 38:51 we can 38:52 generate uh like the curl 38:55 statement 38:58 so if we copy that and 39:01 go to a terminal 39:05 we can run that request in curl and see 39:08 the results 39:10 or it's also nice i can generate 39:14 code in different languages so if i want 39:16 to do this in javascript here's 39:18 the javascript example 39:21 okay so this this all seems fine like we 39:25 we said that most of the time 39:28 we're using the neo4j language drivers 39:31 so let's look at those for a minute 39:36 most of the time we're using one of 39:37 these language drivers 39:40 to 39:43 uh to talk to neo4j in the language of 39:47 whatever i'm using to build my 39:48 application and under the scenes is 39:51 using bolt 39:53 so that it is fast streaming 39:57 compressed rather than http 40:00 and json or jolt so why would i ever 40:04 want to use the 40:05 http transactional cypher endpoints 40:09 if we have bolt and these language 40:10 drivers well 40:12 i can think of a couple cases that are 40:15 interesting to explore 40:18 one is the case well what if we're using 40:21 a language where there isn't a 40:25 bolt language driver so these are 40:28 available in 40:28 in lots of different languages but of 40:31 course 40:32 you know there may be some languages 40:35 where a 40:36 driver just doesn't exist so in that 40:38 case 40:39 we may want to then use the http 40:42 endpoint 40:43 because we can any language that we can 40:45 construct 40:46 a http request we can then use neo4j 40:52 the other case though are environments 40:56 and frameworks where we may not be able 41:00 to open arbitrary tcp connections 41:05 so what do i mean by that well bolt 41:10 it bolt uses tcp 41:14 on a high numbered port by default 7687 41:18 and there may be some environments 41:22 where that simply isn't available to us 41:24 either because of the runtime 41:25 or because of some some restrictions 41:29 and the the example that i want to dig 41:33 into 41:33 now of that is the case 41:36 of cloudflare workers 41:41 let's take a look at cloudflare workers 41:46 so cloudflare workers this is a 41:49 a technology that and i should say an 41:52 edge handlers in general 41:54 uh is a technology area that i'm really 41:58 bullish on i guess is the right the 42:01 right phrase 42:02 um i think this is this is basically the 42:05 next 42:05 iteration of serverless the next 42:09 iteration of 42:10 uh currently we have functions as a 42:12 service 42:14 but the idea here uh with things like 42:17 cloudflare workers 42:19 are that we're now deploying serverless 42:22 code 42:23 that now runs on the cdn 42:27 the content delivery network so it 42:28 actually executes 42:31 these functions that we write 42:34 on the edge network so 42:38 that means that once i've deployed one 42:41 of these workers 42:43 it's now available at the edge so with 42:46 uh with a function as a service like 42:49 lambda 42:50 we are deploying typically to 42:54 one zone we can deploy our application 42:57 to multiple zones but typically we're 42:58 still 42:59 thinking about you know hey we're 43:00 deploying these functions 43:02 to usd ii 43:05 or us west one whatever but in this case 43:09 it's instantly deployed and available 43:12 on the entire global cdn network so if 43:16 i'm 43:17 if i'm somewhere in europe i'm going to 43:19 hit the edge 43:20 that is closest to me so a whole 43:24 reduction in latency because i don't 43:26 need to go to 43:27 the data center in the region where i've 43:30 deployed 43:31 my uh my application 43:35 so that i think is is really interesting 43:37 but also that means that 43:38 then there's no uh cloud starts because 43:42 these are 43:43 run times that are specific to 43:46 the cdn specific to this 43:49 worker network there's no 43:54 cold start problem while i'm waiting for 43:56 like a jvm 43:58 or uh or the node.js environment to 44:02 spin up uh and then we have the other 44:05 benefits that we're familiar 44:07 with things like functions as a service 44:11 where we have 44:13 we're not thinking in terms of servers 44:16 instead we're just thinking in terms of 44:19 our code so 44:21 anyway so those are the reasons that i'm 44:23 pretty 44:24 excited and bullish on workers 44:28 on i guess edge handlers is another term 44:30 for it 44:31 cloudflare workers is the specific 44:33 example we'll look at today 44:35 i think netlify also has a product 44:38 offering 44:40 um are they called what edge handlers 44:45 netlify edge handlers yeah 44:48 so a similar idea here 44:52 so okay well 44:55 what does this have to do with 44:59 neo4j http api 45:02 well in a worker we're not able to 45:07 open arbitrary tcp requests 45:10 so that means that inside a worker 45:14 we can't use a bolt 45:18 language driver to connect to neo4j 45:22 and this is a problem with with lots of 45:24 other databases too 45:26 so if we're building a worker 45:30 and we want to connect to neo4j in that 45:34 worker 45:35 instead of using the 45:38 neo4j language drivers that use bolt 45:42 instead we can use the cipher 45:45 http endpoint 45:50 so so that's what we're going to do 45:54 let's log 45:57 in here 46:01 there we go cool so this is my dashboard 46:04 for cloudflare workers 46:08 um i've created a couple 46:12 of workers before but let's start a new 46:16 one 46:19 there we go so we can either use this uh 46:22 this command line 46:23 tool called 46:28 wrangler i think it's linked here 46:32 uh yeah this wrangler command line tool 46:35 we can either use that to push and 46:38 deploy 46:39 or we can just use this this nice 46:42 ide in browser to 46:45 write our code so because we're just 46:47 playing around here we'll just 46:48 use that 46:51 a question from the chat could this 46:54 replace the graphql api 46:56 we use in the grand stack um 46:59 it could be a way that we deploy 47:03 a graphql api yes yeah so that 47:08 that would be something fun i think to 47:10 look at 47:11 uh maybe in 47:14 uh maybe in another session is how we 47:16 can use 47:18 the graphql integration for neo4j 47:21 as part of grand stack so if you're not 47:24 familiar 47:25 let's jump over there for a second if 47:27 you're not familiar with grand stack 47:32 the idea drop a link to that 47:35 in the chat the idea here let's look at 47:38 the docs 47:42 and zoom in on this image a bit perhaps 47:46 so 47:46 the grand stack this is graphql react 47:48 apollo neofj database 47:51 the api piece is where we're building 47:55 graphql apis that 47:59 are backed by neo4j so we have a neo4j 48:02 graphql integration 48:04 that is able to generate 48:07 cipher queries uh and handle data 48:10 fetching logic 48:11 for a graphql api so in this context 48:14 yeah we we can 48:18 possibly deploy our graphql api 48:21 instead of as you know we previously 48:25 we've seen 48:26 deploying these as like a node.js 48:27 express server 48:29 or as a lambda function but we could 48:32 also deploy them as 48:34 a cloudflare worker where that worker 48:37 then is responsible for generating the 48:41 database query sending that to neo4j and 48:43 resolving the graphql request 48:45 so yeah that's that is totally something 48:47 we can do 48:51 but today what i want to do is 48:56 build just sort of a simple 48:59 location aware endpoint 49:02 so you may be wondering like what are 49:06 what are some common use cases for 49:09 workers and edge handlers 49:13 we talked a bit about like okay well 49:15 these are the benefits over something 49:17 like functions of service but 49:18 you know what other use cases do edge 49:21 handlers and workers 49:23 enable and a great example 49:26 is personalization and specifically 49:30 location based personalization so we 49:33 switch 49:34 to the docs here 49:37 um i think there's a page that talks 49:40 how workers work is that the one yeah 49:43 this is 49:44 this is a good one to look at uh look so 49:47 a use case that cloudflare workers 49:50 really excel at 49:52 is location based personalization 49:55 so for example 49:58 when i'm anywhere throughout the world 50:02 and i make a request in this case 50:05 let's say we're building an api endpoint 50:10 and this api endpoint is going to 50:12 request some data for the database and 50:14 and return that to the user um 50:17 because the request of the user makes is 50:20 routed 50:21 to the nearest 50:24 the nearest machine in cloudflare's edge 50:27 network 50:28 that's where the worker is going to run 50:30 well then it knows something about where 50:32 the user is 50:33 so let's say that if i'm in europe 50:36 and i make a request to a 50:41 machine that's running in spain 50:44 on the edge network well then i know 50:47 that i can personalize 50:48 the results specific to a spanish user 50:52 so that may be 50:54 language specific in terms of like an 50:57 e-commerce site i may 51:00 pull recommendations specific for spain 51:03 versus the us something like that so 51:07 basically basically personalizing uh the 51:10 results 51:11 of the endpoints depending on where 51:15 the user is making the request from in 51:18 the world 51:19 so what i what i want to do today so we 51:21 have this 51:24 election result data set and 51:27 what i want to do is create an endpoint 51:31 that is going to run on a cloudflare 51:33 worker 51:35 that is going to 51:38 find election results near me 51:42 basically so show me all the election 51:45 results 51:46 for uh for the state or for all the 51:48 counties 51:50 based on where i am right so sort of a 51:53 location aware election 51:57 results in points is what we want to do 52:00 so 52:00 what we want to do is figure out okay 52:03 where is the user making this request 52:04 from 52:05 based on where in the edge network 52:10 they're connecting from fetch the 52:12 relevant 52:13 election results and return that 52:17 to the user 52:20 so let's 52:24 build a worker that does that so first 52:26 off 52:28 in this worker 52:32 ide says i can deploy 52:35 to go live and this is by the way this 52:38 is a free 52:39 tier for cloudflare so i haven't i 52:42 haven't put in my credit card or 52:44 anything 52:44 um i get a certain number of 52:48 i think like 30 workers or so that i can 52:52 deploy and a certain number of requests 52:56 that i can make for free 53:00 okay so it starts me off with a pretty 53:01 simple 53:04 endpoint here 53:07 uh that is just returning 53:11 hello world 53:15 i can change this to 53:21 whatever i want my cloudflare worker 53:25 if i test it again yep great 53:29 if i save and deploy this 53:33 and then open up a new tab so here's the 53:36 endpoint 53:37 that we're building this is my 53:39 cloudflare worker 53:40 i'll post it in the chat you can 53:43 you can ping that and you'll get 53:45 hopefully the same response 53:49 so the first question that i have 53:53 [Music] 53:54 is 53:56 how do i figure out where in the world 54:00 i am so i can see here there's lots 54:04 of machines that are deployed throughout 54:07 the world 54:08 on this edge network how do i figure out 54:13 where the request is coming from 54:17 if we look here at the examples 54:22 and accessing the cloud flare object 54:33 there is a 54:36 cf object 54:41 on the event 54:44 that has some specific 54:47 information about 54:52 how this was handled in the cloudflare 54:54 network so let's see if we can 54:57 access that 55:05 so we're passing in the 55:10 event.request object to our 55:15 handler here 55:22 so let's uh let's just return 55:25 that cloudflare object um 55:35 so we'll return event 55:41 uh not event uh it's just request 55:44 so request dot c 55:48 f um let's json 55:52 stringify that so we can read it 55:59 and then in our 56:02 response options here let's add 56:06 a header that says 56:11 that this is json 56:14 because we're building uh we're building 56:16 a like an api endpoint we want to return 56:19 json we're not going to build up a web 56:22 page or something like that this is just 56:24 meant to be like an api endpoint 56:32 okay so i'll save and deploy that 56:35 and test it and we get back 56:39 an empty result 56:42 if you notice in our example it checks 56:45 to see if 56:46 if the request.cf 56:49 object is undefined and says hey this is 56:51 not available in the preview so i think 56:53 that's expected 56:54 that in this preview environment we're 56:56 not going to see it but if we switch 56:57 back 57:00 here and hit the same endpoint 57:03 now we can see some json response 57:06 so there's a bunch of information here 57:09 and actually let's look in the 57:10 documentation 57:13 uh is this in 57:17 platform 57:22 learning debuggers how workers work 57:28 runtime apis 57:36 coding durable objects fetch fetch 57:40 event request 57:44 request 57:48 yes request is what we want 57:51 incoming request cf properties yeah so 57:54 here we go so this is the 57:56 request.cf object and there are a bunch 57:59 of things in here 58:01 we don't have all of this information so 58:04 if you notice here this says we should 58:07 have 58:08 or we could possibly have things like uh 58:11 city of the incoming request 58:13 latitude and longitude of the incoming 58:15 request so that 58:17 to to really optimize uh our 58:20 location aware endpoint we would want to 58:23 have 58:24 latitude and longitude that would be 58:25 great because we could if we had that 58:27 we could just go to the database and say 58:30 find the county that this latitude and 58:34 longitude is in and give me the election 58:35 results for that county and that's what 58:36 we're going to return 58:38 unfortunately though if we look at our 58:40 response we don't have 58:42 county we don't have city we have 58:44 country 58:46 and we have colo so we look in the docs 58:51 uh colo is the three letter airport code 58:55 of the data center so 58:56 colo is telling us what data center 59:00 this request hit so that gives us 59:04 pretty good geographic information not 59:07 necessarily where the user is but 59:09 at least the closest data center to the 59:12 request 59:14 the reason we don't get latitude and 59:15 longitude and that more specific 59:17 information 59:18 is because we're on the free tier 59:20 cloudflare has 59:21 a geoip service that if we were 59:26 a paying user that we could just 59:29 click a box to enable and then that 59:32 information 59:33 would be available to us in this 59:36 here but we don't have we don't have 59:38 that 59:39 but that's fine this colo information 59:42 should be should be good enough so 59:45 in my case i'm hitting the 59:48 seattle so sea this is the 59:52 airport code for seattle so i'm hitting 59:56 the seattle data center which 59:59 i guess is the closest data center to 60:02 where i am 60:03 in montana so yeah makes sense 60:07 um if you if you hit this endpoint again 60:10 i'll link it in the chat 60:11 you should see information specific 60:14 to you 60:18 okay cool so that 60:22 tells us where 60:25 the user is so the next piece 60:29 is let's go to neo4j um 60:32 [Music] 60:35 actually i want i want to make sure i'm 60:36 using the right neo4j so not 60:39 not my localhost database i want 60:45 elections.graph.zone 60:49 and this is anyone can access 60:53 elections.graph.zone this is publicly 60:56 available 60:59 you will have to sign in the username is 61:02 elections and the password is elections 61:04 that's just a read-only user so feel 61:07 free to play around 61:08 with this data set so 61:12 if we look at the schema again 61:17 now it becomes clear why we've included 61:20 airport into our data set 61:24 so what we want to do is now write a 61:26 query 61:27 that okay if we know the airport code 61:31 for the nearest data center where the 61:34 request came 61:35 in well then we can find what state 61:38 that airport is in 61:41 and then traverse out to all of the 61:43 counties in that state 61:45 and grab the election 61:49 result details 61:52 to return to the user for all the 61:55 counties in that state since that's 61:57 that's how the election results are 62:00 reported they're reported on the county 62:04 node 62:06 broken up by which candidate received uh 62:09 what number of votes 62:14 so our query is going to look let's 62:17 zoom in a bit queries going to look 62:20 something 62:21 like this we're going to match 62:24 uh no not a state first we're going to 62:26 start off with the airport 62:30 report has a code so we're going to pass 62:33 in a parameter 62:35 for the colo that stands for the 62:37 co-location 62:38 right so so a colo is what is a 62:42 machine in a co-located 62:45 data center i guess is what we mean by 62:47 cola 62:50 i learned that i learned that term 62:54 one of the first jobs i had at a startup 62:57 where 62:57 we were trying to rent a 63:01 colo machine in a nasdaq data center but 63:04 it had to run on apple hardware so we're 63:06 trying to find 63:07 a vendor to put a mac mini 63:11 in a data center co-located with the 63:14 nasdaq data center which was 63:16 which was a fun exercise but anyway 63:20 uh so we want our relationship to go the 63:23 other way so 63:24 once we've matched on the airport we 63:27 want 63:29 to know what state it's in 63:33 and then really what i want is then to 63:37 go from the state 63:43 to the county 63:46 and like return well let's just do a 63:48 return star 63:53 and let's just 63:56 let's set up parameter for that uh how 63:59 do we do that colon 64:01 params colo 64:06 sfo uh sfo is that that's the 64:10 accept parameter there we go parameter 64:18 okay so that gets us 64:24 all of the counties um but we don't want 64:27 to return 64:28 these graph objects because this is 64:31 going to be 64:32 an api that's returning json 64:36 one thing we can do that's really nice 64:39 cypher especially when we're creating 64:41 these sort of json api endpoints 64:44 is we can actually do a map projection 64:48 to build out the 64:51 json object that we want our api 64:54 endpoint to return and we can just do 64:55 that in cypher 64:59 so what does that look like well 65:04 oops so 65:08 instead of now traversing to 65:11 the county we're going to use pattern 65:14 comprehensions 65:16 um let's take 65:20 a look at that pattern comprehension 65:23 neo4j i think there's a blog post 65:27 the yeah new cipher features inspired by 65:30 graphql 65:32 so pattern comprehensions were added in 65:35 i think the 3.1 65:36 release so 65:41 map projections allow us to 65:46 build a map or a dictionary or an object 65:50 based on and select like which 65:53 node properties we want to return and 65:56 build that up 65:57 which is nice but when we combine that 65:59 with pattern comprehensions 66:02 it's way more powerful because 66:05 we can then uh include patterns 66:10 inside that map projection so it's super 66:14 powerful 66:15 uh when we combine those two to be able 66:18 to build up 66:19 so like here we're 66:22 returning an object 66:25 uh we have the title of the question 66:29 then under the author key now we're 66:33 specifying 66:34 a traversal from the question to 66:40 the answer i guess oh no to the user and 66:42 only returning 66:44 the user name so 66:47 that's a pretty cool feature this was 66:49 inspired by 66:50 graphql actually and 66:53 we actually ended up using this feature 66:55 in cypher for the 66:57 implementing the neo4j graphql 66:59 integration 67:00 which is a fun little fact i'll drop a 67:03 link to that 67:04 blog post in the chat if you want to 67:07 take a look at that anyway so okay so 67:10 now so now instead of traversing out 67:12 to the county at this point we're just 67:15 going to return 67:16 this object not absentee votes we're 67:19 just going to return 67:21 an object that we're going to build out 67:24 so for the state 67:27 let's turn the name 67:31 we have also on the state we have 67:34 the number of votes 67:38 and we also have i think the number of 67:43 absentee votes 67:52 camel case it 67:56 some t-votes not and some t-votes 68:05 and then we have 68:10 oh i don't want this to be s this is 68:14 going to be the key for the object we 68:15 return so 68:17 let's see if this works 68:22 yeah so california 68:25 has 17 million 68:30 votes what happened to my absentee votes 68:32 oh spelled around absentee 68:36 votes 68:39 cool so that's the number of votes cast 68:41 and then the number of absentee votes 68:43 she had a lot more because we had 68:45 mail-in elections this year 68:49 um and then also on the state we 68:54 have whether or not this state 68:58 was called for biden in that case 69:00 there's a 69:01 biden winner 69:05 yeah there it is 69:12 trump winner 69:17 there we go so biden 69:21 one california but to get the individual 69:26 votes and here's where our pattern 69:29 comprehension comes in 69:32 is we want to go to the 69:35 county level 69:39 and this is going to be 69:42 a list because we have multiple counties 69:45 and here we're going to specify our 69:47 pattern 69:49 so in state and we can bind 69:54 new variables here so 69:58 traverse out from this state to find all 70:02 of the incoming 70:03 estate relationships to the county 70:08 and then for each of those paths that we 70:12 find 70:12 i want to now return an object so we're 70:15 going to return an 70:16 object for each county and here 70:19 we're going to project out 70:22 the name of the county 70:25 [Music] 70:27 let's get the number of votes 70:31 for trump 70:36 the number of votes for biden 70:39 see if that works 70:44 no what did i do wrong 70:49 [Music] 70:56 um 70:58 uh let's alias this as data 71:01 so it says invalid input curly brace 71:06 so counties is the key 71:18 uh oh is it this trailing comma 71:23 yes okay cool so now for every county 71:26 i've got the number of 71:29 votes for each candidate 71:33 we can also instead of just returning 71:37 results we can also evaluate expressions 71:40 here so 71:41 for example we can calculate the 71:44 percentage of votes 71:51 that went to each candidate 72:00 biden 72:04 number of votes biden divided by 72:08 number of votes total in the county this 72:11 this isn't quite perfect because 72:14 um there are third parties 72:18 why is that zero oh we 72:22 so in cypher by default we have integer 72:24 division i think that's the problem 72:26 so if we cast one of these things to a 72:28 float then we'll do floating point 72:31 division 72:32 is that the problem 72:36 so um so like 72:39 this isn't quite perfect because i'm 72:42 excluding any 72:43 third-party candidates um 72:46 but this gives you the relevant share 72:48 between the two major 72:51 candidates okay cool so now i've got 72:55 my cipher query 72:59 [Music] 73:01 so given an airport code 73:04 find what state it's in then for every 73:07 county in that state 73:08 compute the election results and 73:12 return that 73:15 okay so now if i go back to my 73:18 cloudflare worker the next thing i need 73:21 here 73:22 is to connect to the database 73:30 so i'm gonna cheat a little bit 73:33 and go to postman 73:38 and i'm just going to copy this 73:44 so we said we like postman because 73:48 it can generate code in different 73:50 languages for us 73:52 so we want javascript using fetch 73:56 which then we can just kind of copy 73:58 paste in here 74:00 in our cloud fireworker 74:03 and can i 74:08 there we go so if i do f1 i get the 74:11 command palette and 74:14 format document so this by the way this 74:17 this embedded editor this is the monaco 74:19 editor which this is the same one we use 74:22 in 74:23 graphql architect if you're familiar 74:25 with graphql architect um 74:30 graphql architect so graphql architect 74:34 is this graph app for neo4j desktop 74:38 that allows you to 74:41 build graphql apis without writing any 74:44 code so we embed 74:46 uh here and this this is the editor 74:49 there's a better picture of that sort of 74:52 anyway this is a graphql specific 74:57 embed of the monaco editor which gives 74:59 us 75:00 uh yeah here we go this gives us like 75:02 the 75:04 command palette options and the schema 75:07 aware syntax highlighting 75:08 and that kind of thing monaco editor 75:12 comes out of 75:13 the 75:14 [Music] 75:16 bs code project so 75:20 anyway that's why that's why i figured 75:22 we could do that 75:24 f1 to get the command palette and then 75:27 format based on the code styling 75:32 a question from the chat it's possible 75:36 to compute the average 75:38 number of votes inside the pattern 75:40 comprehension 75:43 do you mean the average number of votes 75:48 for the county so average in that case 75:52 is going to be 75:52 [Music] 75:55 do switch to neo4j um so 75:58 in this case average is going to be a 76:04 um a aggregation 76:07 function so if we want to 76:11 compute the average number of votes over 76:13 each county 76:17 what we would have to do 76:21 is do that traversal up here 76:24 i think so we were bringing the counties 76:26 i don't think we can 76:30 do an aggregation 76:36 um in the pattern comprehension 76:41 can we let's try it 76:45 so i think what you're asking is can we 76:47 do something 76:49 like this 76:55 number of biden votes 76:58 per county or across all counties 77:02 so i think what you're asking is can we 77:04 do something like this 77:07 where we're doing an aggregation 77:09 function 77:11 in the pattern comprehension 77:18 um it says we have a syntax 77:22 error but that's because i'm 77:28 missing 77:31 this 77:34 invalid use of aggregating function in 77:36 this context yeah so i don't think we 77:38 can do 77:40 aggregation functions inside a pattern 77:43 comprehension 77:48 but that is a good question 77:58 um okay so we're talking about monaco 78:01 editor i shared a link to that 78:03 graphical architect blog post if you 78:04 want to see how that works 78:08 back to our worker 78:11 so okay so we're 78:15 connecting to the database making a 78:18 query 78:23 uh let's change this a little bit so 78:26 instead of 78:28 doing this chaining with the promise 78:30 here 78:31 let's uh say that 78:35 the response 78:40 equals slide this over a bit more room 78:43 here so response let's 78:46 await yeah so we're in an async function 78:48 so we can 78:49 do async await uh refess 78:52 fetch request we don't need these 78:57 we'll just ignore error handling for now 78:59 and we'll say the result 79:03 is await response dot 79:06 json so this will 79:09 give us the json representation of the 79:13 body of this 79:14 response 79:18 i'm going to switch the 79:22 format from jolt 79:25 to json so that we 79:29 we don't we don't really need any of 79:32 that special 79:34 jolt magic here for representing types 79:38 since we're already constructing the 79:40 object 79:41 that we want to return in our cipher 79:48 query 79:50 um query 79:57 let's grab our query so 80:00 that's over here 80:06 is this the right one i think so yep 80:09 so let's grab our query 80:14 paste that in here 80:20 so our query takes 80:23 a colo 80:27 parameter so we need to 80:30 grab the colo 80:33 up here so let's let's just add 80:44 color 80:46 as an argument to this function so 80:50 we'll add that as an argument to our 80:52 handler function here 80:54 and then 80:58 our statement 81:02 so instead of this 81:06 cipher statement our statement is going 81:09 to be 81:10 query so this is the query that we want 81:13 to pass 81:14 and parameters instead we're going to 81:19 pass colo colo not color 81:24 and then colo we need to grab 81:29 from the event object so 81:37 events.request.cf.colo 81:41 but that's not always going to be 81:46 present so i think remember in the 81:48 preview mode 81:49 we didn't have that cf object 81:52 so let's return sfo as a default 81:57 and then we need to check so that we 82:00 don't try to 82:02 access a key on an undefined object so 82:06 we'll say 82:08 if event dot request and 82:13 event.request.cf 82:15 then give us the colo otherwise that's 82:18 undefined 82:19 use sfo as a placeholder then pass that 82:23 colo to our handler function here which 82:25 will then pass that 82:26 as a parameter to the database 82:30 and we've got the json 82:34 response now so 82:38 let's return that that's what just 82:41 results i think 82:50 let's save that and see if this works 82:58 cool so here's the data so we get this 83:01 for 83:02 california because 83:07 we're in this preview thing we don't 83:09 have 83:11 the cf object with that special 83:13 cloudflare network 83:15 data so it falls back to sfo 83:18 for san francisco 83:23 um i'm i don't like this nested 83:26 structure so let's let's pull out 83:29 um so result 83:32 dot results 83:36 which is an array so give us the first 83:39 and then dot data which is also an array 83:43 so give us the first 83:44 element there and the row 83:48 object is what we're interested in 83:51 which is also an array and we want to 83:53 return a json object 83:57 yeah there we go okay so let's save that 84:05 so okay cool so now i'm getting 84:08 results for california 84:12 just as this json object 84:16 but that's not actually testing we're 84:17 actually finding the right 84:21 [Music] 84:22 the right data center the right colo 84:25 we're just hard coding that so let's 84:27 take the endpoint open a new tab 84:31 martin says sup guys hi martin thanks 84:34 for joining 84:36 okay so now i'm going to hit this 84:37 endpoint 84:39 in my web browser and 84:43 if you remember before when i ran this 84:46 it said i was hitting the 84:47 seattle data center so now i should see 84:50 election results for the state of 84:53 washington 84:55 and i do cool great so this is 84:59 this is working so anyone 85:02 who's on the stream now drop this in the 85:05 chat and you should be able to hit this 85:07 endpoint 85:08 and if you are in the u.s 85:12 anyway you should see election results 85:16 for this the state whatever 85:19 state you're in um 85:23 this was this is perhaps a bit more 85:26 interesting 85:27 on election night as uh 85:30 we were pulling in data live because 85:32 then we can sort of refresh this and 85:34 and see um the data as it's changing and 85:37 coming in but 85:41 should be useful anyway for seeing 85:44 location specific 85:45 election result data 85:49 i guess if you're not in the u.s 85:53 what happens here um 85:57 if you're not in the u.s you're gonna 86:00 not find one of these airports no we 86:02 have all we have 86:04 lots of other airports in here so 86:13 ed air in indiana what's 86:18 what's an airport that's not in 86:22 the u.s um 86:25 lhr is that london heathrow i think 86:32 yeah so here's london heathrow it's not 86:34 connected to any states 86:37 so 86:41 you'll not get any 86:44 data back 86:47 from the cipher query 86:50 right so like cipher query that we run 86:55 only is going to return data if it 86:57 matches 87:00 a state so 87:07 this part is probably what's airing out 87:10 so yeah so let's 87:12 if you're not in the u.s let's say lhr 87:16 we run that yep 500 error so let's fix 87:19 that so 87:21 in the case where we don't find any data 87:25 for the 87:28 data center that you've connected to to 87:30 the nearest airport 87:32 to state election results 87:36 let's handle that case so here we can 87:39 say 87:41 so let's check so if we have a result 87:45 and 87:48 results has 87:51 the results array has a result in it 87:56 [Music] 87:58 and 88:00 there's a data array 88:05 then return the row object from that i 88:10 think 88:10 in the case where don't so if that 88:14 cipher query to the database 88:15 doesn't find anything um 88:19 i don't know let's return the the name 88:22 of the data center 88:23 let's try that okay so that's 88:27 something at least so let's let's save 88:28 and deploy that 88:32 um okay so now so yeah marcel says he 88:35 was getting an error from spain 88:37 yes that makes sense so you're probably 88:39 getting an error because we were trying 88:40 to 88:41 access results data 88:44 in that object that comes back from the 88:45 database but because there was no 88:48 results array there was no row object to 88:50 grab 88:52 but now we're checking for that and 88:55 if data does not come back 88:59 then from the database then it should 89:02 tell you 89:03 what data center you hit so 89:07 try that again marcel from spain you 89:09 should 89:10 get um whatever your whatever your 89:12 closest 89:14 uh data center is in spain 89:18 let us know if it makes sense for where 89:20 you are 89:21 i'm going to change this back to sfo so 89:24 we actually get 89:27 some default election data if we 89:30 run it here 89:34 let's just make sure this still works 89:38 we refresh yeah still getting washington 89:40 state 89:41 and marcel says yes works now cool so 89:44 you're 89:44 it's just it's just telling you what 89:46 data center you're hitting 89:48 not not giving you any election results 89:50 but 89:52 oh well cool um 89:57 hopefully for the folks in the u.s 89:59 you're seeing 90:00 election results for your state 90:06 cool so that was um 90:10 that was i think what we wanted to 90:12 accomplish 90:14 so we we now built this 90:17 cloudflare worker that is 90:21 locationaware to query neo4j and 90:25 give us election results 90:28 that will vary depending on where in 90:31 the world we're making that request from 90:34 um 90:34 if we enabled the the cloudflare go ip 90:37 we could then look at latitude and 90:39 longitude 90:40 um but since we're just on the free 90:43 version this 90:45 is hopefully good enough 90:48 cool well i think we will um 90:54 stop there 90:56 [Music] 90:58 question from marcel is neo4j aura 91:00 deployed on a global 91:02 cdn as well 91:05 so neo4j aura 91:11 let's switch over to neofj aura so with 91:15 aura 91:16 you have your choice of region let's see 91:18 if this is 91:19 listed you have your choice of region 91:24 when you provision your database 91:29 so it's not distributed 91:32 in the same sense as like cloudflare's 91:34 edge 91:35 network um 91:39 your deployment is in a specific region 91:42 there's a number of regions that are 91:44 supported not sure what those 91:46 are actually if we go look at it we can 91:50 find it 91:52 and then also 91:56 aura is looking at multi-cloud support 91:59 as well so being able to 92:03 deploy um to different clouds currently 92:07 there is a gcp integration 92:11 for aura 92:16 but yeah so not not distributed in the 92:18 same sense 92:19 as the cloudflare edge network 92:24 in that sense 92:29 cool well thanks um thanks for joining 92:32 today hopefully you found that 92:33 interesting um hopefully that gives you 92:37 some perspective for the 92:41 neo4j 4.2 release definitely 92:44 take a look at the the release notes or 92:47 the blog post 92:50 that talks a bit more about some of the 92:51 other features that are new in neo4j 92:55 i found the http and 92:58 jolt feature really interesting 93:01 specifically because this 93:02 enables us to work with 93:06 cloudflare workers where we're not able 93:08 to 93:09 use bolts but there are other 93:10 environments as well 93:13 i think where we may want to be able to 93:15 work with http 93:17 um anyway so that was that was a look at 93:19 that 93:20 specific new feature in the 4.2 release 93:24 4.2 is available now as of 93:27 tuesday i think so it's 93:30 available in neo4j desktop 93:33 so even though i was trying to use this 93:36 4.1 93:37 database when you create a new database 93:39 you can choose 4.2 93:42 or you can also upgrade existing 93:44 databases 93:46 as well and then it's also available 93:50 on your aura 93:53 cool well thanks a lot um for joining 93:56 today 93:58 i think next week 94:02 is thanksgiving in the u.s so i will 94:05 skip 94:05 my thursday time slot on the live stream 94:09 next week 94:10 um so we'll pick it up the week after 94:14 and what i want to do is start a new 94:18 series on the stream looking 94:21 at um building 94:25 a new application from scratch so so far 94:28 we've done i have these linked on my 94:33 personal website so far we've done 94:37 we have the real estate search 94:38 application uh from 94:40 start that was a fun one so that all the 94:43 videos 94:44 are linked for that one um 94:47 i should change this to link to the 94:49 github instead since that's probably 94:50 more interesting 94:52 to look at the code for those since 94:55 we're linking the 94:58 um the videos here as well 95:02 but so far we've done the real estate 95:03 search application 95:05 with grand stack we did the gatsby 95:10 travel guide where we built 95:13 a travel guide of central park using 95:16 neo4j graphql and gatsby and some of the 95:20 the routing functionality in neo4j for 95:23 real-time routing 95:25 we did the full stack graphql book club 95:30 so digging through the exercises 95:33 of the full stack graphql book 95:37 we've looked at cloudflare workers and 95:39 the next thing i want to do is now pick 95:40 up another one of these series where we 95:42 do a deep dive into building an 95:44 application from scratch 95:46 and what i want to do next when we come 95:48 back from the thanksgiving break in the 95:50 u.s 95:51 is build a podcast application 95:54 from scratch uh so i was i was 95:57 complaining about 95:58 the podcast app i use and my wife said 96:01 well why don't you just build your own i 96:02 thought hey that's a 96:04 that's a great idea maybe we will do 96:06 that um 96:07 so we'll pick that up next time uh how 96:10 we can build 96:11 a podcast application using 96:14 neo4j we'll probably use graphql um 96:18 but the other technologies we use i 96:20 don't know maybe a bit open-ended 96:22 so hopefully you can join us when we 96:24 start that 96:26 not next thursday but the thursday after 96:30 so thanks everyone for joining today and 96:33 uh 96:34 we'll see you next time bye 96:54 you
Subscribe To Will's Newsletter
Want to know when the next blog post or video is published? Subscribe now!