Serverless GraphQL with Hasura
In this episode, Christian Nwamba teaches us how we can build incredibly powerful apps without the overhead of managing lots of infrastructure by combining Hasura, serverless functions, and the Jamstack.
Links & Resources
- https://hasura.io/docs/1.0/graphql/manual/getting-started/docker-simple.html
- https://github.com/octokit/rest.js
- https://www.netlify.com/products/functions/?utm_source=learnwithjason&utm_medium=hasura-jl&utm_campaign=devex
- https://github.com/Azure/azure-functions-core-tools
- https://hasura.io/docs/1.0/graphql/manual/auth/index.html
- https://hasura.io/learn/graphql/react/introduction/
- https://twitter.com/eveporcello
- https://work.herm.dev/
- https://www.onegraph.com/docs/auth_guardian.html
Full Transcript
Click to toggle the visibility of the transcript
Captions provided by White Coat Captioning (https://whitecoatcaptioning.com/). Communication Access Realtime Translation (CART) is provided in order to facilitate communication accessibility and may not be a totally verbatim record of the proceedings.
JASON: Hello, everybody, and welcome to another episode of "Learn with Jason." Today, on the show we have the one and only Codebeast, Christian Nwamba. How are you doing, man?
CHRISTIAN: I'm doing great. Thank you. I like when you say the word Codebeast. It makes me feel like I have wings and I can fly.
JASON: I'm super excited to have you on the show. I feel like I see your work in the community all the time. We've worked together a little bit with concatenate, but that was remote. It's good to be doing something together, right? This is going to be super fun.
CHRISTIAN: Yeah.
JASON: For those of us who are not familiar with your work, do you want to give a quick background on who you are?
CHRISTIAN: Yeah, absolutely. Hi, everyone. My name is Christian, just like Jason mentioned. I'm a senior cloud advocate at Microsoft. I do a whole lot of serverless and GraphQL stuff. I'm just saying hey. Basically, focusing on GraphQL serverless and trying to do that. Basically, trying to see how we can use the cloud logistics as well as this amazing open source GraphQL and Jamstack and serverless, all the web dev 2020. It's like abstract with skill as much as possible.
JASON: Yeah.
CHRISTIAN: That's what I do.
JASON: I think something that's really exciting about this world of GraphQL and serverless is I feel it has made complex app development so much more friendly to a front end developer.
CHRISTIAN: Yep.
JASON: From my experience, what I've noticed is that I'm much more willing to build something complex when I can just write a serverless function because I don't have to go and stand up express server. I don't have to figure out how to get my Heroku app hooked up to my domain name. I just get that and it works. In your experience, what have you found have you noticed the same thing? Are you seeing the same thing?
CHRISTIAN: How I like to describe this is basically the idea of having a low hanging fruit. What I tell people is, hey, this function it is an irrelevant function. When you request objects, it has everything about a command request. It processes everything on the server and sends back a response. People don't have to care about infrastructure anymore. They run a particular command. They have a function, and they can write a function that can handle the HTML request. It is the fastest way to start deploying servers for front end developers. For people who are doing a lot of frontend code, it is a whole lot of journey, having to fight their brain on which to use. All this thing. Then you have the optimization and have to deal with user experience and optimizing for speed and for people in regions that don't have super speed. You have to deal with all those things. The last thing you want to deal with at the end of the day is to come back and start thinking about how we have a good skill level and background for application. Most serverless providers allow you to basically they try to handle everything for me from setup and scale. It's a deployment. You don't have to worry about it anymore. Just run this command to create an app to deploy the function as well.
JASON: It's so exciting. I think it's such a cool thing. With that being said, I'm really excited to get into it. A quick shout out to our sponsors before we go. The show is being live captioned at lwj.dev/live. If you want to read along, you can do that at lwj.dev/live. That is brought to you by Netlify and fauna. This is being done by White Coat Captioning, so huge thanks for them being here today.
Christian, I want to get into this and play with some serverless functions. One thing that we haven't talked about yet is a serverless function is a way to eliminate servers and allow us to do some work with just writing some JavaScript, right? But what that doesn't cover is what if I need to get data or what if I need to store data. How do I do that? How do I make that connection from my frontend to my serverless function to what? Like what happens after that?
CHRISTIAN: Yeah. This is what I can talk about today, which is GraphQL. At the end of the day, having a delta layer means you would want to do a lot of mutations and queries and all the plumping to get the data to the frontend app. For front end developers using GraphQL a lot, what happens when you want to access the data from GraphQL? This is when it becomes really, really painful for front end developers because GraphQL APIs in as much as they are fancy on the frontend, they're less seen on the backend. You have to be very careful basically designing the types. It's not like one of the things where you run the command and you have something going. You have to repeatedly spend some time to think about how this thing would look. If you don't do that, you'll end up shooting yourself in the foot because you'll make a lot of security mistakes. It happens to GraphQL. Generally, people don't want to worry about it. If they get stuck they love GraphQL as a front end developer, but they get stuck when they try to use it, when they try to build one for themselves.
Today, I'm going to show this amazing open source tool called Hasura, which takes out this problem and allows us to literally keep breathing. The word serverless I'm trying to find the best analogy, but it's enough to get you excited.
JASON: Yeah. The way that I got brought into GraphQL was I was making at IBM. We had this really complex API layer. Our data teams and our backend teams were building API endpoints and it was all REST. Those were getting more complex. They had to create special bespoke for end UIs. The other teams would build proxy APIs over the top of the backend APIs. As you can imagine, this was so hard to debug. It just got so complex. When things broke, we didn't know how or why, so my team worked to introduce GraphQL over there. We hit exactly what you just said. It was so much fun to use GraphQL, but building that server, oh, my God, it was like everything that we wanted to do. It just felt hard, and it felt like we were going to get ourselves into trouble. What you're saying is Hasura is going to take that problem, that how do I design a GraphQL API, how do I make sure my GraphQL APIs are secure and scalable and resilient, they're just going to make that all go away.
CHRISTIAN: Exactly. Every single thing.
JASON: That's exactly what I want.
(Laughter)
JASON: Yes, bespoke endpoints is 100% the Portland hipster version.
(Laughter)
JASON: Every one of our endpoints was wearing a flannel shirt, had a beard. Also, before we get started, thank you so much for the subscription. I really appreciate it.
With that, I'm excited. I want to do this. Can we jump in? Let's write some code.
CHRISTIAN: Yeah, yeah absolutely. Let's do this. The first thing we need to do is set up the GraphQL endpoint before we start. The idea is to have a GraphQL endpoint and then extend that GraphQL endpoint with serverless.
JASON: Do I want to start in my terminal or where am I going first?
CHRISTIAN: Let's do what every developer does and go to the writeups.
JASON: Here's Hasura.
CHRISTIAN: Yep. Let's find where the docks link is.
JASON: Okay. I'm going to go to the sorry, I'm getting trolled in the chat here. Sarah is not making this easy on me.
(Laughter)
JASON: All right. Here are my docs. Getting started. We're probably getting started from scratch today, right?
CHRISTIAN: Yep. You can do the quick start on the left.
JASON: Oh, perfect. Okay.
CHRISTIAN: For everyone who hasn't used Docker Docker is for front end developers. We don't care about what Docker is. We just need it to start in Hasura API locally. Don't ever worry about this. It's code. Someone who is not comfortable with Docker, like me, is going to set this up as well.
Select the link on step 1. Let's not do in the magic. Let's just copy the link.
JASON: Oh, perfect. Yeah, let's do that. I'm going to get this. Oh, well that doesn't look like magic at all.
CHRISTIAN: Exactly. Basically, there are two surfaces. One is a Postgres database and the second one is a GraphQL engine.
JASON: Okay.
CHRISTIAN: Even though we have this GraphQL magic first, we still need the data area. Right now, they are Postgres. Basically, this is you connecting to a Postgres database with Hasura's GraphQL engine. We're just going to copy everything here now.
JASON: Okay. Then I'm going to create what's our folder structure going to look like for this? We're going to make a Hasura database, and then we're also going to make a site. We can probably yeah, okay.
CHRISTIAN: I don't know how long we have. I don't know if we'll actually make a website, but we'll give them everything they need to make a website. We'll have an API folder.
JASON: Okay. I'm going to make a folder called Hasura API so I can remember what I did later.
CHRISTIAN: Yeah. Exactly, yeah.
JASON: Let's see. Let's get in it. Then I'm going to open this one in a code editor so we can look at it. Here's my empty folder. There's nothing in it. I'm going to create a new file. This is called Docker compose?
CHRISTIAN: Yeah, Docker dash compose dot YML.
JASON: Paste all this in here.
CHRISTIAN: Believe it or not, you have a GraphQL API.
JASON: Awesome. Do I need to edit this stuff?
CHRISTIAN: Nope. Nope, you don't have to do anything. All you have to do is save this file.
JASON: Okay.
CHRISTIAN: Go back to your terminal. Just do Docker dash compose space up, space hyphen d.
JASON: I got ahead of myself. Sorry.
(Laughter)
CHRISTIAN: That's okay. Basically, when it starts, it is processes with the terminal. Oh, no.
JASON: Uh oh. Build programming. External connectivity. You know what? I bet I'm running something. That would not surprise me.
CHRISTIAN: People can see they can change the port as well. Go back to the Docker compose file.
JASON: What am I already running in here? Oh, I'm running something in Docker on 8080. I have a confession to make. I don't know when the last time I opened Docker was, so I have literally no idea what this is.
CHRISTIAN: Okay. Let's see. Run Docker space ps.
JASON: Oh, boy.
CHRISTIAN: Let's stop that. Since you don't care much about what's going on here, let's stop everything.
JASON: Okay.
CHRISTIAN: Type Docker stop space dollar sign then open bracket Docker ps hyphen q and then close the bracket. It will close every process you have right now on Docker, like stop it.
JASON: Oh, okay. To break this down, I'm passingly familiar with how this work. What I'm doing here is I'm running this command, and then that turns into a list of arguments to this command.
CHRISTIAN: Exactly that.
JASON: Okay.
CHRISTIAN: What's different between hyphen Q you can see hyphen Q prints only the ID. What Docker stop needs is the ID. Hyphen q means quiet. If you do Docker ps now, see.
JASON: Docker ps, empty. Now I can run this Docker compose up.
CHRISTIAN: Exactly.
JASON: All right. See, this is the kind of debugging that I need. The last time I did this I just closed Docker and walked away.
(Laughter)
CHRISTIAN: Now you can do Docker ps first to make sure everything is okay.
JASON: Hasura Postgres.
CHRISTIAN: You can see Hasura Postgres and port 88. Let's see what happens at port 88.
JASON: This is already working?
CHRISTIAN: Yep.
JASON: I don't want to close that. Local host. 88. Holy crap!
CHRISTIAN: Yes.
JASON: That's super cool. Basically, we did nothing and this just worked.
CHRISTIAN: Exactly.
JASON: That's awesome.
CHRISTIAN: The mind blowing thing is we haven't actually done the mind blowing thing. We just set up the mind-blowing thing.
JASON: Wait. Hold on. There's more? I don't think I can handle this.
(Laughter)
JASON: I might need a nap midway through this episode.
CHRISTIAN: Yep. Now let's do some mind blowing thing for the audience. Let's go to the data menu from the number bar. At this point, the data tab a normal GraphQL page doesn't have a data tab. The data tab and actions tab, all of these are just Hasura giving you all these things. If you've ever used any database system, if you download any SQL graphic user interface to modify tables and rows, that kind of thing, that's what's happening on this page.
JASON: Okay.
CHRISTIAN: If you click on create table okay. Let's just do a post. Let's say blog. Then we'll put title and column type.
JASON: Title, text. You said content?
CHRISTIAN: Yep.
JASON: That's also text. What was the other one you said?
CHRISTIAN: Auto.
JASON: Like this?
CHRISTIAN: Yeah, like you write out the article.
JASON: I'm sorry. I'm having I'm so glad we have live captioning too. That's one of my favorite things about this. Whenever I speak at conferences, people find it difficult with my accent at first.
JASON: Author. I'm sorry.
CHRISTIAN: Yep. We have the column type text as well.
JASON: Do we need any IDs?
CHRISTIAN: Exactly. We just do ID. Then the type is going to be integer auto increment. It is back on the top. You just need to check the primary key field to code ID.
You can scroll to the bottom now.
JASON: I'm going to close this.
CHRISTIAN: Okay. This is the mind blowing thing. Go to browse. Go to insert row.
JASON: Okay. Just make it both?
CHRISTIAN: Yeah.
JASON: Okay. Does that all look good to you?
CHRISTIAN: Yeah. Perfect. Then save.
JASON: Okay.
CHRISTIAN: Now go to browse rows. You can see we have the table here. This is the part that is very, very mind blowing. Go back to the GraphQL tab.
JASON: Okay.
CHRISTIAN: Now you have a GraphQL API. You can explore on the left.
JASON: Ooh, okay.
CHRISTIAN: Select the title. I can just run the query.
JASON: Look at it go. All right. There we go. Oh, okay. All right. I'm going to do something real quick.
CHRISTIAN: Okay.
JASON: I'm going to go into my table, and I'm going to insert a row. Just putting words in your mouth.
CHRISTIAN: (Laughter).
JASON: All right. Let's save this. Now if I go out here, I can run this. All right. There we go. Now check this out. I want to a filter, and I can just say equals
CHRISTIAN: Equal.
JASON: Oh, my God. That is this is, I think, where it's really, really easy to set up a simple GraphQL database, like something that just stores things and then retrieves those things. But when you start getting into complex stuff like filtering or where you want to do sorting or pagination, that gets so hard.
CHRISTIAN: Exactly. Yeah. Actually, I use Hasura for up to eight months now. I still find it mind blowing that it does this. It gives you all this flexibility. You can literally use Hasura and do whatever you want to do with it, which is amazing. How about relationships? We're going to see that. That's the next thing we're going to see right now.
Let's bring up the data point once more. Let's have one more table. Let's call this table comments.
JASON: All right. What do you think?
CHRISTIAN: Just call it content. Content and ID. That's all. Author as well. ID.
JASON: I need to make this the primary key.
CHRISTIAN: Let's save it first. Back table, yeah. Every time we have an existing table we can more or less come back to the modify tab to edit it. Let's scroll down.
By the way, if you click on frequently used columns right above, it can display
JASON: Oh, cool.
CHRISTIAN: It's a really cool thing. Yep.
JASON: Actually handy.
CHRISTIAN: Yeah. Let's go to foreign key section.
JASON: Foreign keys.
CHRISTIAN: You can add a foreign key. Then scroll down to reference table. Pick blog. Click on the "from." ID. Okay, we have to add one more column to comments. That would be like a post. Let's go ID column.
JASON: Like blog ID or something like that or I guess we could just do blog.
CHRISTIAN: Yeah, exactly. Let's do blog ID because we'll be able to tell it is an ID. The type is just integer.
JASON: Then we don't want this to be nullable. This should be required.
CHRISTIAN: Exactly.
JASON: Okay.
CHRISTIAN: We can scroll down
JASON: I'm going to have to refresh, right? Let's just start over.
CHRISTIAN: Okay.
JASON: So, blog. For my comment ID I need to refresh. Was it there and I just didn't see it?
CHRISTIAN: Yeah. That's okay.
(Laughter)
JASON: All right. ID. The yeah, I get it.
CHRISTIAN: Just save this.
JASON: Do you know what these are? I remember seeing these before.
CHRISTIAN: Yeah. It's basically SQL. Let's say I want to delete something that has a relationship to something. Restrict means if I had comments and I want to delete the blog comments, I don't delete the post. Just the comments.
JASON: Oh.
CHRISTIAN: That option allows you to say keep the blog post but delete all the comments.
JASON: Okay, I get it. That makes sense. I'm going to save this. There's a good question in the chat, which I don't know if we're going to have time to get to today, which is where is the best place to host the Hasura container. Right now, we're running locally, right?
CHRISTIAN: Yeah. You can put it in any containers, the Hasura Cloud as well, which they launched two, three days ago.
JASON: Where did it go? Just Cloud. I saw it just a second ago. Here.
CHRISTIAN: Yeah. Basically, if you sign up, you can basically create it.
JASON: Yeah. But this will work on anything that can support containers, so like DigitalOcean or Heroku or Azure, AWS, Google Cloud. You can run it anywhere, right?
CHRISTIAN: Exactly.
JASON: Basically, that's the benefit of Docker, is that it sandboxes the whole thing so we can do it feels the same to use everywhere. We just need a place to put it.
CHRISTIAN: Exactly, yeah.
JASON: Awesome. All right. Now I've created this field.
CHRISTIAN: Exactly, yeah. If you go back to the GraphQL tab, normally you would expect to see comment inside blog or blog inside comment, but we aren't seeing that now. The reason we're not seeing that is you need to understand there's a data layer and a GraphQL engine there.
JASON: Okay.
CHRISTIAN: Think about it from the way if you are creating a GraphQL API. If you're doing MongoDB or Postgres, you still have to define the relationships and the types. You remember?
JASON: Uh huh.
CHRISTIAN: You define the post and the comments. That's the kind of thing that I was asking before to say, okay, this is how we should handle this data for this user. Go back to data.
JASON: The reasoning for that, just to try to wrap my head around it a little bit if I'm building a database in Hasura, I'm going to be creating the ability to read, write, create, update, delete, everything, anything that I want to do, I can do from this Hasura database.
CHRISTIAN: Exactly.
JASON: When I start to define the way the GraphQL API works, I don't necessarily want to make all those things available to the public API, so this is a way of me being able to say I can create things with admin privileges in here, but I don't even necessarily want people to be able to attempt to try things externally. Am I getting that right?
CHRISTIAN: That's a different feature called permissions.
JASON: Okay, all right. I'm getting ahead of myself.
(Laughter)
CHRISTIAN: This one is more like this is basically you playing with Postgres. Just imagine Hasura doesn't have access to the data tab. This is just you let's say we throw away this window and open Postgres in GraphQL user editor and start adding tables and relationships. That's what we've done here. We still have to tell Hasura that the GraphQL level that these two are related. Okay? Yeah.
If we go to the blog table now and click on relationships
JASON: Relationships. Oh, look at this.
CHRISTIAN: It is suggesting based on the keys we added that these are related. You can see the suggestions because a blog would have many comments. It's suggesting an array relationship here.
JASON: That's really nice. When I clicked that button, I did like the Drake meme face. Okay. Then do I need to do the same on comments?
CHRISTIAN: Exactly.
JASON: Okay.
CHRISTIAN: You'll see it is on object side because comments would have one blog related side.
JASON: Awesome.
CHRISTIAN: Save.
JASON: Saved.
CHRISTIAN: Go back to the GraphQL tab. You can start querying for comments.
JASON: Oh, it's beautiful. We didn't create any comments, so I didn't pull anything back, but I can pull that in at least.
CHRISTIAN: Exactly.
JASON: The title. Yeah, it just sends back an empty array now because that's all we've got.
CHRISTIAN: Yeah, exactly. Yep. I'm just going to show you one more thing. It's with the permissions. If you click on data
JASON: Data.
CHRISTIAN: and click on blog once more.
JASON: Okay.
CHRISTIAN: Because this is the one you asked about. Click on permissions. By default, admin has access to everything. Let's add the user rule.
JASON: Okay.
CHRISTIAN: Then click edit. Literally, you can come here and start adding custom permissions. You can define the columns that they have access to. You can define the rows they have access to. They allow you to use you can pass in a token, and you can get data and check if the person accessing the data is they have a dedicated docs on this, on how to do the permissions. It's not very challenging.
JASON: Yeah. And this is really cool too because I know there are some features where, for example, you can send a header with a request and it will automatically set the user. If we had the header, we could do something like where the author is
CHRISTIAN: Exactly. Exactly, yeah.
JASON: Access Hasura, user ID. Incredibly powerful stuff.
CHRISTIAN: Yeah. If we start the permission stuff, it is a rabbit hole to get into. Let's see if we can do some really fun thing with serverless functions.
JASON: Okay.
CHRISTIAN: Cool. There are two ways that Hasura treats extensibility. There's one called actions, and there's one called events. You can see both of them. Actions, you can define a custom query that doesn't theoretically write to the database. That custom mutation does not write to the database. It calls something outside Hasura. Let's see an example. Let's click on actions.
JASON: Okay.
CHRISTIAN: Click on create.
JASON: Oh, cool. I like this. See, this is really nice. This is a good touch in any app. You'll see that you have all this power, but you're not really sure what the thing is, so having just this thing here that shows me immediately, oh, this is what you're doing, that's really nice.
Okay. I'm going to create one.
CHRISTIAN: This is basically like a GraphQL this is a little bit of what we do on GraphQL backend. You have your mutation. This mutation, when it is called, what it basically does the mutation we have right now writes to the database directly, but this one doesn't write to the database. Instead it calls a function I provide. If you scroll down a little bit, it calls this function. The handler is how it communicates outside itself. We have 3000. Let's say we have a serverless function on this port or we're trying to get an API on this port. Once you call this mutation, it will trigger and go to this endpoint.
JASON: Okay.
CHRISTIAN: Actions are basically interceptors. They communicate requests. Whatever request is coming in is not going if it is coming in from an action, it is not going to write directly to your database. You can do validations, clear the data, and do a few things before taking any action.
JASON: That's super cool because this basically means that now I could use Hasura as the gateway to my entire company's suite of software.
CHRISTIAN: Exactly, yes. That is a valuable architecture that people use. What you want front end developers to have access is a front end developer API. You want to connect them to GraphQL endpoints.
JASON: My question is, it looks like we can do this with queries too, right?
CHRISTIAN: Yeah.
JASON: Actually, I know you have an idea. I know we're going to run out of time if I start rambling, so how about we do your thing and I'll ask quiz at follow up?
CHRISTIAN: That's okay. I wanted people to see because we have something nice cooked for them. I want them to see it before we run out of time.
JASON: Yes.
CHRISTIAN: Definitely, I will take all the questions at the end.
The second part is calls. When someone calls, you need to maybe process a payment with stripe. We'll call a stripe endpoint. You go to the URL. You can set headers for the other endpoints that I need to get it from. You can use this to process payments on Stripe, send emails, send notifications. This is basically Hasura's solution for it.
JASON: Very cool.
CHRISTIAN: The other thing with actions is events. If you click on
JASON: Events?
CHRISTIAN: Yes. It is on the other side of actions. Actions are the interceptor. The events are I have successfully written to the database. Do you want me to do something else? You can trigger a function to do something. Actions is, hey, I need to be sure we can do this before we write it to the database. Event is more like, hey, it doesn't matter if we can do this. Just write the code and we can try to do this. If it fails, that's fine.
JASON: Yeah.
CHRISTIAN: That's basically the difference between both of them. This is the one we're using today. The demo will have a post database. If somebody writes to it, it could create an issue, that kind of thing. I'm more familiar with the GitHub API.
JASON: Yeah, I'm more familiar with the GitHub API as well.
(Laughter)
CHRISTIAN: Yeah, cool. Let's do this. First of all, say you work at Netlify and I work at Azure. They seem to talk about Netlify functions. I want Azure people to go home with something as well.
Let's start with Netlify, if you don't mind.
JASON: Okay.
CHRISTIAN: We need to create a Netlify function.
JASON: I will create that. We'll just put it right in this site. I'm going to create functions. Let's see. Down here, I'll create a Netlify dot toml. The Azure functions, is that file based? I could also create a Netlify folder and we can have the example in the same repo.
CHRISTIAN: It needs a root folder for GraphQL functions. Yes, definitely, we can have let's call Netlify functions. We'll put Azure functions there as well.
JASON: Let's do this. We'll do Netlify functions. Then I can rename this to Netlify functions. Basically, what I'm saying here is I'm just telling Netlify to use this folder when we build functions. Then inside I can create, just as a test, boop dot js. Then I will export handler equals async. Then that is just going to return a status code of 200 and a body of boop. Now that I've got this, I can let's just open the terminal in here actually. Let's run Netlify dev. Okay.
Out here, I with go Netlify functions boop, and we get our boop back.
CHRISTIAN: Sweet, yes.
JASON: That is like the general serverless function flow. Now we can build whatever for Hasura.
CHRISTIAN: Yeah, this is perfect. Can we take a request and log the request to the console?
JASON: Yes. Do you want to call this create issue?
CHRISTIAN: Yeah, create an issue in GitHub, yeah.
JASON: We'll export handler. That is going to give us the event, and then the event we get back is it sent as JSON? Do you know?
CHRISTIAN: Yeah, it is sent as JSON. Yeah. It is JSON on the request of body.
JASON: Okay. Then I will return status code of 200 and the body will be JSON stringify body. I think that will work.
CHRISTIAN: Exactly. Let's get the URL.
JASON: That URL is going to be "create issue." That's going to do nothing now because it didn't get a body.
CHRISTIAN: Exactly, yeah. What we need to do is to just copy oh, is there an error?
JASON: The error is because we didn't send it a body. This will only work with a post request.
CHRISTIAN: That makes sense. Let's just copy from init init init down to the end of the URL. From the port to the end of the URL. Copy. Go to Hasura.
JASON: Hasura.
CHRISTIAN: Click on create.
JASON: Create.
CHRISTIAN: Let's just call this issue.
JASON: Can I put parentheses on it? Is that going to work?
CHRISTIAN: Exactly. Yeah, that should work. Schema/table, call it blog. This is where I want to do something. Now we need to type we need to go the actions part, sorry. Actions is in a new window. Actions tab. Click on create.
JASON: Oh, Docker internal?
CHRISTIAN: Yeah.
JASON: Okay. I can just get this, right, and then copy this across?
CHRISTIAN: Exactly. Just paste it here.
JASON: To clarify, this is local host on Docker?
CHRISTIAN: Yeah, exactly. This is basically Docker's local host.
JASON: Okay. All right. Then I'm going to go and create. Please match the requested format.
CHRISTIAN: Let's do hyphen Netlify.
JASON: Okay. All right. Issue Netlify works. Now, if I make sure that's running
CHRISTIAN: Exactly. Let's go back. If you open independent events
JASON: I'm sorry.
CHRISTIAN: That's okay. Events are where it was successful, stuff like that.
JASON: Nice. We get logs. Oh, this is cool. Now if I create a post, we should be able to make this thing run?
CHRISTIAN: Exactly. Click on the GraphQL. Scroll down to the bottom. You can choose mutation. Just click on the plus button to add mutation. Let's do insert blog, author, and then the title.
JASON: Oops. Title. Got it.
CHRISTIAN: Then we can return
JASON: Kind of return whatever, right?
CHRISTIAN: Exactly, yeah. Let's run this and see.
JASON: Okay, so it ran. Now I should see my events.
CHRISTIAN: Yeah. Click on events. Click on issue Netlify.
JASON: Cool. I see it worked. Invocation logs.
CHRISTIAN: Successful. This is exactly the same thing that you said.
JASON: This is cool. Here's what we got. We got headers. It sent us application JSON, and it said it is from Hasura. We can validate that, if we wanted, and make sure that it actually came
CHRISTIAN: Exactly.
JASON: Cool. Oh, no. I get the
CHRISTIAN: This is what it sent. Let's see your console function.
JASON: I didn't log anything, so it just said it worked.
CHRISTIAN: Exactly. Since the response was 200.
JASON: Yeah.
CHRISTIAN: Now what we can start doing is basically use Oktokit.
JASON: Which one do I want, GraphQL?
CHRISTIAN: No.
JASON: Hold on. Sorry. I'm going to grab the docs here. I want the JavaScript, right?
CHRISTIAN: Yeah, exactly.
JASON: JavaScript. Oh, just tell me how to install it though.
CHRISTIAN: Yeah, that thing there.
JASON: Okay.
(Laughter)
JASON: We're here. I'm going to stop this. I'm going to do an npm and init yes. Then I can just run this. We're installing Oktokit. Now in here I can
CHRISTIAN: We can import and basically click configure. It will forward it to the new Oktokit thing.
JASON: I'm going to grab a new Oktokit. Now we've got access to
CHRISTIAN: Inside the Oktokit, you'll see objects. The first one is const, then auth. I know how we're going to do this, but we need to pass an access token to this.
JASON: Got it. Give me just a second. What I'm going to do is I'm going to go to what is it? I'm going to go to my settings. In my settings, I'll be able to here.
CHRISTIAN: Scroll down to developer.
JASON: Developer settings.
CHRISTIAN: Developer settings. Then you can create.
JASON: Personal access token, right?
CHRISTIAN: Yeah.
JASON: I'm going to pull this off screen so you hackers don't steal my stuff.
CHRISTIAN: You can also put this in your environment as a variable.
JASON: That part I can actually do you hackers. You dirty hackers. That's you, Chad.
(Laughter)
JASON: All right. This is Hasura. All right. Then I just need repo, public repo. Actually, I can show this part. I'll show this part, and then I'll have to pull it off. I'm creating a new personal access token. This is a name that just helps me remember what I did. Now I have to select scopes. I need to be able to create issues, right?
CHRISTIAN: Yes. I think that's everything.
JASON: Access
CHRISTIAN: People can literally do stuff on your public reports.
JASON: Yeah, I'm not going to show the key. I'm just going to show the scopes. It is just public repo is all we need, right?
CHRISTIAN: Yeah.
JASON: Okay. Let me pull this off. I'm going to create this key. All right. I have the key. So, now what I'm going to do is just get the Netlify let's set up the site. Oh, I need to Git create, so we'll set up a repo first. Now I can Netlify init. I'm going to set up a new site, put it on here. Hasura serverless events.
CHRISTIAN: Yep.
JASON: And then my build command is nothing. We're not really deploying a directory, so we can do that as well. And that's done. So, then if I open this, which I want to open it over here, right?
CHRISTIAN: Exactly.
JASON: This takes me in here. I can go to my site settings, build and deploy, environment, and that is safe, so we'll do GitHub API or access token.
CHRISTIAN: This is cool. You can access this from locally as well.
JASON: I can. That's the Netlify build that we did for Netlify dev.
CHRISTIAN: Interesting.
JASON: It pulled in the environment variable. Now we have access to that. We can do auth. Let's see. Let's look back at Oktokit.
CHRISTIAN: I'm just showing you. Just process the token.
JASON: Got it. Okay.
CHRISTIAN: Cool. Let's go back to the GitHub stuff.
If you want to go to this documentation, scroll to the top.
JASON: This one?
CHRISTIAN: Yep, on the right. Just click on the link.
JASON: Okay.
CHRISTIAN: We need to click on "issue."
JASON: Issues. I want to create an issue, right?
CHRISTIAN: Yeah. Exactly. Create an issue.
JASON: Here's where we're going. That's what we're going to be working on.
CHRISTIAN: Create issues is on premise, so we can take everything in front of it and then pass all of this. You have already created an issue, so we can use that.
JASON: Then the repo that I just created was in here somewhere.
CHRISTIAN: Yeah.
JASON: What did I call it? Hasura serverless events, I think.
CHRISTIAN: Yeah.
JASON: No, Hasura API. Then the title, let's pull that out from the thing, right?
CHRISTIAN: Exactly. The title is going to be
JASON: I was over here, logs.
CHRISTIAN: It's going to be event dot data dot new dot title.
JASON: Event, data, new, title.
CHRISTIAN: It's going to be yeah, body there. There's a body for issue creating. Not content. It is called body.
JASON: Oh, it's called body. Got it, got it, got it. Then data new what did we call this?
CHRISTIAN: Content.
JASON: Content. Nice. Okay.
CHRISTIAN: You could basically just return this or do nothing. This should generally work.
JASON: Let's log the GitHub response now so we can see what happened.
CHRISTIAN: Exactly. You can also do console dot log.
JASON: Let's do that. Console dot log dot response, if I can spell it. All right. That should be good to go.
Let's create a new host.
CHRISTIAN: We can just name this one oh, if you want to create new ones.
JASON: All right. Let's run this. There it goes. Created post number 4.
CHRISTIAN: In console, take a look at event. This worked.
JASON: Let's just go look. I just want to see it.
CHRISTIAN: Yea!
JASON: Oh, my God. This is so freaking cool. I can't
CHRISTIAN: (Laughter).
JASON: I'm trying to think back to how my yeah, when I was younger, I remember trying to develop stuff like this. I wanted to be able to create a thing and then when that thing happened, I wanted something else to happen. I would just get buried. I would to set up my own database and figure out how to administer that. I have to set up my own server and figure out how to administer that. I have to figure out how to talk to these APIs and tie that together and trigger that stuff. Oh, my God. It was just such a pain, right?
CHRISTIAN: Yeah. I'm not sure if we've done up to one hour left, but we have an API with serverless functions that is talking to GitHub. It is amazing doing that, which I find quite fascinating.
JASON: Yeah. It's so cool. Let's do this same flow but with Azure.
CHRISTIAN: Okay, cool. Let's google Azure function CLI.
JASON: Azure functions CLI. Is it this one? Let's get into that.
CHRISTIAN: We can just scroll down and see.
JASON: All right.
CHRISTIAN: There should be an API. It's npm. The first option, you skipped it already.
JASON: I skipped it already? Oh, got it. All right. I understand.
CHRISTIAN: Yeah.
(Laughter)
CHRISTIAN: Can you use version 2? If we get stuck yeah, let's do version 2.
JASON: I'm going to install. I'm installing globally Azure functions core tools version 2. I don't know what this means, but I trust you, so yolo.
CHRISTIAN: (Laughter).
JASON: Okay.
CHRISTIAN: This is just going to pull down the SDK.
JASON: Okay. That did the thing. All right. I'm ready. I've done that. What should I do next?
CHRISTIAN: Let's type func init.
JASON: Like this?
CHRISTIAN: Yeah.
JASON: Okay. I want node. I want JavaScript.
CHRISTIAN: Yeah, JavaScript.
JASON: You don't want to watch me write typescript. That's going to go poorly for all of us. (Laughter).
CHRISTIAN: It's going to share this JSON. We got some files. Yeah, there's local dot settings dot JSON. That's where you would have to these two functions, walkaround time is available in your code. This is where you set your variables.
JASON: Nice. Okay.
CHRISTIAN: Because it is in Git, it will generate one.
JASON: Okay. Let me add that. Local settings JSON. Okay. That's ignored.
CHRISTIAN: Exactly.
JASON: Then I need to add my GitHub key, right?
CHRISTIAN: Yeah, exactly. Take it off seen. Take it off screen.
JASON: We're going to call it access token, and then I nut and then I need to put the token in there. Then I need to grab this value, put it in here, save, close local settings, cancel here, and bring this back on screen. All right.
CHRISTIAN: Perfect.
JASON: Okay.
CHRISTIAN: What you've just done is initialize a project. There's no function yet. It's like five minutes. This is basically settings for the function.
JASON: Gotcha.
CHRISTIAN: We can do func space new.
JASON: Func new. Sounds like we're about to start a party with that.
CHRISTIAN: A lot of options, but what we're looking for is HTTP trigger.
JASON: Okay, number 8.
CHRISTIAN: Just call it issue Azure.
JASON: Do I need to put a dot js on it or anything?
CHRISTIAN: No, that's all. It creates a folder. The host dot JSON is the global settings. You can see it has the Netlify function. Now we can run func start.
JASON: Okay.
CHRISTIAN: Yep. Then we'll have an endpoint. If we go to this endpoint, yeah, it works.
JASON: Beautiful.
CHRISTIAN: If you pass a query to it, it will do it.
JASON: Yeah, I can just put in whatever I want here.
CHRISTIAN: Yeah.
JASON: Nice. Very cool. Very cool. That was easy. All right. That was pleasant.
CHRISTIAN: We just basically have to start with the previous one.
JASON: I think we can just copy this out, right?
CHRISTIAN: Yeah.
JASON: We'll pull this over, drop that in, and then the request query
CHRISTIAN: You can just delete all this.
JASON: Okay. I'll start up here. The body is going to be request dot body, right?
CHRISTIAN: Yeah. Exactly.
JASON: Do I have to parse it or anything?
CHRISTIAN: No. That's all.
JASON: From here, I can just take the rest of this, right?
CHRISTIAN: Yeah, exactly.
JASON: I'll take all that.
CHRISTIAN: And just replace.
JASON: And for my response, it defaults to 200.
CHRISTIAN: Then the body is basically the variable we had.
JASON: Excellent. Okay. I just realized what we should have done. Let's do this real quick.
CHRISTIAN: Okay.
JASON: Because that way we can see where it came from, right?
CHRISTIAN: Yeah.
JASON: We can do and update these.
JASON: Okay.
CHRISTIAN: Now we can basically copy the URL. We can just stop this and start it again. Yeah, this is fine.
JASON: Actually, I think I broke it. Oh, I have to stop and start it, so I'll stop and start. It's running again. Copy.
CHRISTIAN: We can just copy and go to Hasura.
JASON: Go here.
CHRISTIAN: You've created the event that's called issue Azure.
JASON: This one is going to go on blog, insert. It was http
CHRISTIAN: Host dot Docker internal, I think.
JASON: Let's validate that real quick. Events, Netlify. Yep.
CHRISTIAN: Yeah.
JASON: Create. Created. All right. Is it going to fail if this one is down? Do I need to start that server?
CHRISTIAN: No, no. It will try them independently. If that one fails, it's fine.
JASON: Okay, cool. I'm going to go back out to GraphQL. We'll say one more. All right. Let's run it. Post number 5. We should see a new issue from Azure functions. Damn it. That's cool.
Here's the thing that's interesting. I think that took us nine minutes. Once we got the base set up, it took us nine minutes for us to get something up and running. That's such a vote of confidence for how much power this gives you, like how fast you can be once you get the knack for serverless functions.
CHRISTIAN: Yeah. It's very cool. I think that's basically the important things I had, but you can ask your questions. We can go back to the dashboard and start digging in to see if there's anything. I will take questions from the comments if people are asking as well.
JASON: Let's see. There's some questions about streaming. I'm using two computers. That's why my computer is not imploding right now, because this is an old Mac. This is a 2017 it's an old computer, but I'm running I feel like VS code has gotten really good at this. It doesn't eat up a ton of CPU. Chrome has had updates that aren't eating CPU. Then I offload the streaming and the video. My camera, the Zoom call that Christian and I are on, and the streaming that happens to twitch happens on a separate PC. Sorry, Ashlee. Not calling your computer old. I was only talking about my computer.
(Laughter)
CHRISTIAN: Yeah. This was the first time I tried livestreaming, which was a teaching thing. My marbles want to blow. I have a digital software and app with the wave form stuff. I have ops and everything running. It is just a very crazy experience for a laptop.
(Laughter)
CHRISTIAN: Literally, it's an issue. It's like what we've done today.
JASON: Your computer just packed itself up and went home.
(Laughter)
JASON: All right.
CHRISTIAN: I had to get a new computer for streaming. It seemed so complex.
JASON: Yeah. The streaming stuff is very computer intensive. It goes from feeling like everything's fine to all of a sudden your computer is starting to hover off the desk and the fans are running faster than you ever thought was possible.
Chat, now is your chance. You have the expert here for another 15 minutes, if you want. What questions do you have about serverless, about GraphQL, about where we could take this? I'll kick us off.
Christian, if I want to build more complex stuff here, what should I start looking at? Where should I go next from here? Because I feel like what we've done thus far is we've built a very cool proof of concept. Anything further is going to require access controls, user accounts, things like that. What would you recommend as a next step to make sure that we don't get overwhelmed as we go deeper down the rabbit hole?
CHRISTIAN: The one thing I have to tell everybody that they should watch out for is authentication. Just like GraphQL doesn't give you authentication. It's full of examples, but it doesn't say this is what you should go for. I've spent two weeks on authentication. You figure out how this is how GraphQL works before you do this. The good thing Hasura is mindful about literally, by default everything is not accessible to everybody. You have to go in and start switching things. GraphQL opens everything by default. Then you go and start closing each of the tools. GraphQL opens everything. Now you're intentional about every single field you are allowing people to have access to. When you're taking Hasura from just giving you the simple CMS for your blog to doing something like a comments site or something very, very huge, you have to dance with authentication for a while. The pattern is promising enough. As much as we're trying to figure it out, we are protecting you from yourself by not allowing you to open it by default.
JASON: Sure.
CHRISTIAN: You can gradually open the doors to let people in.
JASON: That's cool. Oh, go ahead. Sorry.
CHRISTIAN: Just one last thing I want to address is people also often have questions about production level and skill set. I'm a front end developer. When people ask me this stuff about Hasura, what I've realized is Hasura is so flexible. You can drop it into anything and it will work as expected. Also, you can extend it whichever way you want. There's schema stitching. If you go back to the GraphQL tab there's your remote schema. You can get another GraphQL endpoint and drop it in here. It measures your own GraphQL here with the external one. Like you do gateway for the serverless function example let's say you have small GraphQL living in different places. You can use Hasura to put them together. You can try to not make it Postgres.
JASON: Yeah. There's a couple questions in chat that I think are pretty interesting here.
Can Hasura event trigger do something to the operation it was triggered by, like revert? If I could maybe take a crack at that first, that sounds like validation or something.
CHRISTIAN: Exactly. If they want to get feedback from the serverless function, you have to use actions. Events is more like, I'm done. I'm going to start trying to process the serverless request. You can make it as tricky as after the write. The event code can cause an action. You can basically create a loop that goes that way.
JASON: Cool.
CHRISTIAN: Remember, GraphQL is GraphQL. You can code any of these GraphQL actions inside a smaller function so it uses the GraphQL database. You can do really crazy stuff with it.
JASON: You could, after the insert your event could then call a mutation that would modify the just inserted code. So, you could do that?
CHRISTIAN: Yeah, you could do that, but my point is use actions because actions is your tool. One of the engineers at Hasura, he is answering questions as well. Thank you so much for joining us. Yes.
JASON: Yeah, yeah. Ashlee did ask, if I want to build a React app that uses GraphQL, where's a good place to start reading and doing some research about how to do that?
Hasura is a great place to start. It's a very good course. I would recommend looking up Eve Porcello. She is a stellar GraphQL teacher. She has done amazing work. There's a podcast here. There's a book. There's conference talks. Her Twitter is amazing. There's a whole book on it here. There's a bunch of free egghead content. Go look up Eve, and she'll have so, so many resources.
CHRISTIAN: If you go to work.herm.dev
JASON: Oh, cool.
CHRISTIAN: It provides user authentication.
JASON: Very cool.
CHRISTIAN: You scroll on the left side, the sidebar.
JASON: GraphQL API, move to the Cloud. Authentication. Dang, this is serious.
CHRISTIAN: Yeah. I don't know if you know the app called Buffer. It's used to schedule tweets. It creates a clone of it so you can set up created tweets. Hasura has an event feature that you can schedule actions. Basically, I tore apart all the Hasura features. You can use it with Cloud and serverless functions.
JASON: Nikki has a good question. We set up an event that happens after an insert. Is there a way to set up a web hook so if someone creates a GitHub issue, we would do something in Hasura?
CHRISTIAN: Yeah, absolutely. If someone creates an issue on GitHub I'm trying to think how that would work. I know it is definitely possible. I'm actually counting on my colleague to help me out here.
(Laughter)
JASON: I do know that this is possible. There are ways to do it. You can use a serverless function and register that serverless function as a web hook for I do that, for example, with twitch. When I go live on twitch, twitch calls a serverless function and from that serverless function I can do anything. I can send a request to a GraphQL endpoint. In my case, what I do with it is I turn the imbed and the live captioning on on lwj.dev/live. There are a lot of ways you can do that. The short answer is yes. You definitely can.
(Laughter)
CHRISTIAN: Exactly, yeah. Just like I mentioned, if you have an action, that action ends up being the GraphQL query that you can run inside a serverless function. You can run a GraphQL mutation. I'm not sure if Hasura has a feature for this, but it is definitely possible.
JASON: Yeah. Let's do one more question and then I think we'll shut it down. Is there a way to protect remote schemas?
CHRISTIAN: Remote schemas, protecting them is the responsibility of the person at the microservice. It's the responsibility to do all that. The only thing you need to do from Hasura is, hey, I need this remote schema and here's my access key and here's my authentication and ability to access that endpoint. At the end of the day I know how possible this is, but I have to have access to GitHub API to be able to do that with Hasura.
JASON: One thing I will shout out that's been really helpful for me is there's a company called One Graph. They have a service called auth guardian that has been just so incredibly helpful. Let me see if I can find their actual I just hid. One Graph, auth guardian. It's in here somewhere.
This is really cool. That page doesn't work.
(Laughter)
JASON: Here it is. Auth guardian. That's what I wanted. Auth guardian, it is basically like a JWT builder. What's really interesting about it is it gives you the ability to set your Hasura role. It's so nice. What's cool about it is I can go in and I can basically say, all right, you're going to log into my service. Actually, I can explain this with a real example. The way the events on my chat works if I type flap, this little animated Jason pops up and flaps his arms. I have a service called stream blitz running. Stream blitz used One Graph to log into both Netlify and twitch. Under the hood, I keep a record in Hasura of the serverless functions on my Netlify site. Whenever I get an event from the chat, I check to see am I authorized. The way One Graph works under the hood is it says log in, get an 0auth token from twitch and Netlify. If this is the person who is authorized to make changes to the twitch channel, then set their Hasura user role to admin. All of that is done in a way that I would not have been able to do on my own. It hurts my brain to even try to think through the way it works. But in the combination, using serverless functions for the logic, using Hasura for the data management, and then using One Graph for the auth management, it felt money. It didn't feel like I was pulling my hair out. If I had any hair, I wouldn't have been pulling it out. I didn't build stream blitz on the screen. I should bring it back on stream and we should rebuild stream blitz to show how that process works because it is a really fun thing. It's a cool way to show access control, how you can do something a little more hey, let's add users to this service. Let's add admins and editors and specific access control.
Christian, thank you so much for coming on and teaching this. This is such powerful stuff. For somebody who wants to follow up with you and learn either learn more about you or learn more about this, are there any websites that you want me to drop in chat?
CHRISTIAN: Yeah. Codebeast on Twitter.
JASON: Definitely go follow Christian. Not for just this. Christian is one of the most active community builders I've seen on Twitter from concatenate conf, which was the first major developer conference in Africa. Last year, you had it in two countries, right? You did one in Nigeria and one where was the other one?
CHRISTIAN: Kenya.
JASON: Kenya, yeah. I've watched you build an incredible community and just been blown away by it. It just seems like you're everywhere.
CHRISTIAN: Thank you so much. I couldn't have been able to do that alone. It feels very grateful to hear that from you. Thank you so much. Thank you, everyone, for joining. If I needed to chill and relax, I would have
(Laughter)
CHRISTIAN: Hey, I have to do all this and be ready for this, this weekend. She said, go do it. Just like I told you before, I'm going to share a link with you that has a demo that after people can play with.
JASON: We'll update. This will get posted on learnwithjason.dev tomorrow. We'll have a bunch of resources, the transcript. All that stuff will be available. If you want to follow up on this and do more, make sure you check learnwithjason.dev. The site is here. I'll drop it in the chat. While you're there, make sure you check out the schedule because we have some incredible stuff coming up. I have Joel Hooks coming up on next week. Lucky 7, we're going to build a silly app for making sandwiches for friends. Alex is Eve Porcello's partner. I'm so excited about this whole list. Everybody on here, it is going to be so much fun.
With that, one more shout out to our sponsors Netlify, fauna, sanity, auth0. Live captioning done today is by White Coat Captioning. Thank you so much for hanging out.
CHRISTIAN: Thank you so much.
JASON: We're going to raid. See you next time.
Learn With Jason is made possible by our sponsors: