Load Existing Data from a Hasura Database using Netlify Serverless Functions

Jason Lengstorf
InstructorJason Lengstorf
Share this video with your friends

Social Share Links

Send Tweet
Published 3 years ago
Updated 3 years ago

We'll load existing data from our Hasura database using serverless functions. The first step will be to create a new mutation in the Hasura GraphiQL named InserOrUpdateBoops.

We need to make sure that all the corgis are being loaded into our database. Once they are loaded, we can set the count to zero. We do this by defining a GraphQL mutation using an autogenerated variable provided by Hasura called, boops_insert_input!.

Our application loads the existing data but the functionality to save the values from the client-side is still not available.

Instructor: [0:01] Loading this Hasura data into our existing object is going to be a little bit weird, because what we want to do is we want to make sure that all of the corgis that have been loaded exists in this database. Right now, only one exists.

[0:15] What we're going to do to make sure that this keeps in sync is, instead of querying, we're going to use what's called a mutation. What we want to do is add a new mutation. We're going to give it a name of, insert or Update Boops.

[0:31] A reasoning for that is that we need to make sure that all of the corgis that we're querying for exists in this database. We're going to insert them with a count of zero. If they already exist, they're going to have a count, which means that we don't want to change that count.

[0:47] We'll just update the ID, which allows the mutation to succeed, but it doesn't affect our data. This is a way for us to query the data, while making sure that all of the things that we need to query actually exist.

[1:00] This one's going to take a variable. This is going to have a name of, boops insert input. This is auto generated by Hasura. We can see it if we look over here, we've got the mutation, and then insert boops.boops insert input. That's why we're using that name, and what that is is an array of ID and count. Effectively, the shape of this object here, that's the shape of this boops insert input.

[1:30] Over here, we're going to run, insert boops. In that, we want to do objects. For objects, we're going to use corgis. On conflict, we want to make sure that we don't override anything, so the constraint is going to be the primary key, which is the ID. That's what we need to choose, but then for our update columns, we don't want to update the count. We want to update the ID.

[1:57] Again, that's effectively a no-op. That's going to make sure that nothing explodes. Then returning, we want to get the ID and the count. With that, we can take this over here. Add it as a variable, so we'll say, corgis, and paste this in.

[2:18] If I run this, it inserts, and note that it didn't change any of this. If I go into our data and I change this boop, let's edit this one and say, five and save. Then, I come back here and I run this again, it stays five even though the count here is one. What we've done is we've basically said, if it doesn't exist, initialize it. What we'll actually be initializing with is a count of zero.

[2:49] We'll have an initial count of zero. If it exists, we leave it alone. That way, we'll keep our count historically, and our site will be able to create any new corgis that come in, but it will not override any data. With this, we can grab this mutation, and we can come back out to our code.

[3:12] Here, in load corgis, underneath unsplash promise, we're going to create a new one. We're going to call it, Hasura promise. This one is going to be the result of Hasura request. That means that we need to import this. Up here, we'll get Hasura request.

[3:31] We exported it as a named function, which is why we're destructuring here. That will be, require util Hasura. Now we've got access to Hasura request. Inside of this, we're going to set the query. For the query, we can paste in this whole mutation that we set. For the variables, we need to pass in, corgis.

[4:05] That's what is going to be mapped here, whatever value is here. This needs to match this boops insert input, which means it needs to be an array. Fortunately, we already have corgis, which is an array that has the ID that we need. We can run corgis.map. Then I'm going to destructure to get that ID.

[4:28] What I'm going to return is an object that has the ID and a count of zero. That initializes all of the corgis in our database that come back from the API. It'll say, "I want all of these corgis." If they don't already exist, insert them into the database with a count of zero. If they do exist, we're going to bounce that out on conflict, and it will return the actual count.

[4:55] If I save this, then I can go over here and add this to the promise. Here's my Hasura promise. As the second object now, I'll get back Hasura data. I can save that. To use this data, this data is going to map to here. It's going to be data. and then it'll be insert boops. I want this to be a little easier, so let's alias it.

[5:22] This is just a shortcut in GraphQL. Whatever we put here, it'll rename that. Now it's going to be our result.boops.returning. That's what I want. In here, to use this data, I can create a new variable called boops. It's going to be, hasura data.boops.returning. Then I'm going to find the data in here.

[5:45] We'll use another short variable, so that we can get to the individual boop, and we'll look where the boop ID equals the corgi ID. Now, we're going to get the photo up here and the boops here. I can drop those boops as the boop, boops.count.

[6:07] On saving this, now, we should be loading all of our boops, which means that if I come back out here, start up my server with netlify Dev, we're loading in our hasura URL, our hasura admin secret and our unsplash access key. I can go to localhost 888, reload the page, and we get five boops here, zero boops, zero times. We're not saving these yet.

[6:34] If I hit these buttons, and then reload the page, it'll reset back to zero, but we kept this five. If I go and look at our data, I can see that each of these has been added. If I go to edit one, change it to two, and reload out here, and we can see now we've got two boops, five boops. Those numbers are used in our app appropriately.

[7:03] All that's left to do is add the function that will save these values.

Antal Tony Tettinger
Antal Tony Tettinger
~ 2 years ago

Could you please help and elaborate how is this working? mutation MyMutation($likes: [likes_insert_input!]!) { likes: insert_likes(on_conflict: {constraint: likes_pkey, update_columns: id}, objects: $likes) { returning { count id } } } I understand what it is doing, but its confusing a bit. Thank you in advance!

Jason Lengstorf
Jason Lengstorfinstructor
~ 2 years ago

sure!

Hasura supports "upserts", meaning it will create OR update something in the database, which is a nice convenience method to avoid needing a strict "create" and "update" function and needing to reason about when to use each one

to support this, we need to know what to update when a conflict (an existing entry with the same key) is found

so the constraint identifies the key that means a conflict exists, and the update_columns identifies which fields should be updated. any fields that are not included in that will be ignored

this is especially useful if you have something with partially sensitive data. imagine a User and they have permission to edit their name and email, but not their permission level — the constraint would be their user ID, and the update_columns would be name and email

let me know if that doesn't make sense!

Markdown supported.
Become a member to join the discussionEnroll Today