In this workshop, we'll build a React app from zero to one using a GraphQL API from Nhost.
Table of contents:
- Sign up to Nhost and create a Nhost app
- Create database table
- Set up React app
- Install Nhost and GraphQL dependencies
- Display data in React app
- Let users sign in
- Add GraphQL API permissions
Build a GraphQL App with React
In this workshop, we'll build a React app from zero to one using a GraphQL API from Nhost.
AI Generated Video Summary
In this Workshop, participants learned how to build a React app with GraphQL and TypeScript using NHost as a serverless backend. They set up the app, explored NHost features, created a Postgres database with a GraphQL API, implemented authentication, and protected the dashboard. Real-time data synchronization was also demonstrated, and participants learned how to enable third-party sign-in methods. Overall, the Workshop covered a range of topics and provided a comprehensive overview of building a full-stack application.
1. Building React App with GraphQL and TypeScript
We're gonna start building a React app with GraphQL and TypeScript. To follow along, go to app.beta.io, create an account, and choose Frankfurt, Germany as the location. No card details required. If you have any questions or encountered any issues, please let me know.
And we're gonna start building a React app with GraphQL and TypeScript. So, actually what I will ask everybody who's already joined, so, this is my idea here is do a workshop and you will be able to follow along.
And so, what I will ask you to do is go to let's see if I can get this working. We can go to beta. I'll get the app.beta.io and create an account. Easiest way is just to sign in with GitHub if you want to follow along. So let me make this a little smaller, and so you can just log out and sign up with GitHub, and that should open this view and you should have like a default workspace being created for you.
So you can just click on a workspace and click on new app or click a new app here and create a new app, and we have a free tier, so you don't need to enter any card details or anything. So if you want to follow along this workshop, you go to app.beata.nls.io, create an account, a workspace should be automatically created for you, and you can go ahead and create a new app over here. You can pick a location that's close to you, but you're only allowed to pick Frankfurt in Germany for now. We have multi-regional support coming maybe later this week, so we're going to add a few more data centers, but for now, the illusion of choice, you can choose Frankfurt, Germany.
So I'm just going to ask everybody who just if you have a question... Because I don't see any feedback here. So if you created an account and were successful doing so, just do a thumbs up in the Zoom chat. So I can see some feedback if it's working. Maybe the infrastructure team at NHOS is sweating right now. I don't know. How do I do a thumbs up? Why can't I do it? Yes, we have the Discord in my think. Okay. So I don't see any thumbs up in the chat.
2. Follow Along and Set Up
If you just want to follow along and see what I do, that's totally fine. But if you want to follow along, set up in progress. Thumbs up. We've got one. One thumb up. That's nice. So if you just joined, you can go to app.beta.nos.IO. You can see some people are now able to create accounts and create applications. That's perfect. So everybody who just made a thumb up, they were able to create an account here and a new application. And they now have their own Postgres database. They now have a GraphQL API and authentication and storage ready. I'm going to talk to you how you can use that in just a second. Right, I'm not sure how I do do I?
Does it mean you just want to follow along and see what I do or do you have some issues? It's totally fine. If you just want to follow along and see what I do, that's totally fine as well. But if you want to follow along, set up in progress. Thumbs up. We've got one. One thumb up. That's nice.
So if you just joined. Yeah. Totally fine. So if you just joined, you can go to app.beta.nos.IO. I'm going to send the link in the Zoom chat. You can see some people are now able to create accounts and create applications. That's perfect. So everybody who just made a thumb up, they were able to create an account here and a new application. And they now have their own Postgres database. They now have a GraphQL API and authentication and storage ready. I'm going to talk to you how you can use that in just a second. Right, I'm not sure how I do do I?
Okay, so I saw some time up we're good to go. We should be good to go? So, what you can do now is, let's see I have some notes.
3. App Setup and Overview
Most of you will see your app up and running with some example content. There are front end templates available, and you have some options to choose from. In the top menu bar, you'll find tabs for data, Hazura, and users. Hazura is a GraphQL engine that generates a GraphQL API for you. You can manage your users and perform actions like adding and deleting them.
I have some notes prepared. Let's move over some Zoom windows over here. That's good. All right. So, most of you will see something like this now. So, you have your app up and running, and you can see the name of it. You can see some example to get started.
Here are some front end templates. We're not going to go – we're not going to talk too much about that, at this point of time. But you can also see – you have a little bit of options here. So, the region you launch your app, etc.
We also have this tab in the top menu bar. So, we have data, and we have Hazura. So, if you're familiar with Hazura, or if you're not familiar with Hazura, Hazura is a GraphQL engine that sits on top of Postgres to automatically generate a GraphQL API for you. And we're going to go inside Hazura just in a second. But I just want to mention this at this point of time. We also have users, where you can manage your users. You can add new users. You can manage each user. And I'm just going to delete this one, because it's one that's left over from yesterday's workshop.
4. Introduction to NHost and its Features
NHost is a serverless backend for web and mobile apps. It provides a database with GraphQL and empowers developers to build applications that users will love.
And variables. So, this is where you manage environment variables. These environment variables are stored in both Hasura and in serverless functions, which is something that we do as well. But before we go deeper into our own product, or EndHost's product, I just want to make a super quick introduction of EndHost and what we do here.
We have this slogan, build apps users love. This is all we are for. We want to empower developers like you who maybe don't have the time to learn how to operate the full backend, or you know how to operate backend. But you just want to go on and deal with it. We just want to empower developers to build applications that your users will love. In this workshop, we're going to talk about how to do that with React, GraphQL, and TypeScript.
And specifically, what is NHost? NHost is a serverless backend for web and mobile apps. This is how you can think about what NHost is. You have your frontend, and most of you are probably familiar with Netlify and Vercel. Netlify and Vercel do frontend. This is where you host your web app. But you need somewhere to store all data. So you need a database, API, users, storage for your users to upload funny cat pictures or files, documents, whatever. This is where NHost comes in. We do for the backend what Netlify and Vercel do for the frontend. More specifically, what do we provide? We provide a database with GraphQL.
5. NHost Backend Features
We have real-time sync, permissions, file storage, image transformation, authentication, and cloud functions. We also have exciting products launching soon, including a Stripe integration and transactional emails. Our back-end provides a top-notch experience with a database, GraphQL API, and all the essential features you need. Front-end is where you build your React application, while the back-end handles data storage, database management, and user authentication.
So this is the Postgres database I mentioned and this is Hasura, which automatically generate a GraphQL API for you based on your database. We have real-time sync. So you can use subscriptions to sync data in real time between the database and your React app, and I'm going to show you how to do that later in this workshop.
We have permissions built into Hasura, so you can manage permissions. I'm going to show you that as well. We have file storage, so you can upload and down... let users upload pictures and documents and files, etc., videos. We have image transformation, so you can automatically resize images on the fly. We have authentication, so you can have all your users stored at nhost. We have cloud functions, or serverless functions for you who are used to, say, Next.js with their API folder or say, Netlify, they have a serverless function as well. We support the same thing out of the box and it's tightly integrated to every other part of the nhost stack.
We have a few exciting products that we're going to launch very soon. We have a Stripe integration to make it easy to basically connect your data in your database with Stripe so you can read information from Stripe and transactional emails which is something almost every application needs. So all in all, this is the back-end. You get the database. You get the GraphQL API. Everything is top-notch with everything that you can expect from a modern back-end with real time syncing, permissions, files, authentication, functions, everything that you need. So this is just another image explaining what we do. So front-end, most of you folks probably already know front-end is where you use React, you build your nice application, the back-end is where we store the data, database, storage, user authentication, et cetera. This is what then has to do.
6. Introduction to Workshop and Nhost
We take care of all cloud configuration, security, scalability, performance, updates, etc. Our goal is for you to focus on your application and users. Today's workshop will build a MicroSaaS CRM. We'll cover database usage, GraphQL API, and authentication in a React app using Create-React app. Sounds great! Nuno, the CTO and co-founder at Nhost, confirms all apps were created.
And we take care of that for you, and we also take care of all cloud configuration, security, scalability, performance, updates, et cetera. Like our goal is for you as a customer to focus on your application and on your users. You shouldn't focus on infrastructure at all, no infrastructure. We take care of that.
So for today's workshop, what we'll build. So we'll build a MicroSaaS. I'm calling it like that. It's a CRM, so customer relationship management system. And here are some of the topics that we're going to cover. So we're going to cover how to use the database, how we can use the GraphQL API, and we're going to include how to use authentication with everything here. And we're going to have everything in a React application. We're going to use the standard Create-React app, and we're going to be able to fetch data with GraphQL from there and have authentication ready for us.
Okay, how does that sound? How does that sound? Everybody in the chat, is that okay? And while you are on that, I will just make some modifications to my screen setup here. Because I want multi display mode. Can I do that? MacBook Pro, do, do, do, main, yep. And this should not mirror. Because I have a little bit of a, of sheet codes here that I want to be able to copy from. Sounds great, sounds great. Nice. And I also see Nuno, who is the CTO and co-founder at Nhost, all your apps got correctly created.
7. Workshop Setup and Repository
Yesterday, I ran the same workshop by myself. Now, with you guys following along, I'll do my best. First, go to github.com/nhost/nhost and star our repository to support us. Then, clone the repository into your download folder. Next, cd into the cloned repository.
So, I think that's very nice. All right, let's see. Why is it, how do I? What's going on here? Sorry about the... This is almost a requirement when you do some presentation, and especially if you're technical you need to have some kind of technical issues. So I want this over here so I can quickly slide it. Yeah, nice.
All right, back to the workshop. So yesterday I run the same workshop, but I just did it myself. So no one was following along. So I will try to do my best here with you guys following along. So I will first ask you to... Let's see. What do we do? We do... So we go to github.com slash nhost slash nhost, and I will share the link in the chat. And while you're here, this is our main repository. So if you feel you want to support us, please hit the star button. That will help us very much. After you start our repository, if you want to go ahead and clone this repository, I will just clone my repository into my own download folder because I'm going to copy some stuff here. So I'm going to clone the nhost nhost repository. I will cd into it.
8. Templates and Installation
I will go to the templates in the nhost nhost repository and find the react Apollo template. I'll copy it to a separate folder called GraphQL Galaxy 2021. I'll close the original window and open a new one. Then, I'll run yarn install or npm install to install all dependencies.
And I will go to templates. So I'm in the nhost nhost repository templates, and I will go to the web folder. And here are two templates that we have available, which we're going to use. So we're going to use the react Apollo template. So I'm going to copy this react Apollo template into another folder just so I have it separated. And I have my other folder here. So I have it in code GraphQL Galaxy 2021. So I'll just do this like this. So I'll just open two finders and just do a classic command C, command V. And this was the first one I did yesterday. So we'll do a brand new, and I have react Apollo here. And I'm going to close it and close it. And I now have the React Apollo template copied in a separate folder, and all codes should be available over there. So we're not going to use the end of the repository anymore. So I'm just going to close that window and just spit the screen so I can open a new one here.
9. Running the App and Checking Progress
After installing all dependencies, run 'npm start' to see the React view. Please confirm in the chat if you see the spinning icon. If you're just following along, let us know. Some participants have already got it working.
And after all dependencies are installed, that was quick, I'm going to do npm... What is it? Run start. And I should be able to see the classic React view here, like edit source app.tsx to save and save to reload.
So I'm just going to pause here, and I'm going to wait for some thumbs up in the chat to make sure everybody is following along thus far. If you see the same spinning icon that I do, please give a thumb up in the chat, so I know that you're on track and can see the same thing as me.
So what I did was I went to the ns-ns repository, I cloned it, and I copied the directory under templates, Web, React, Apollo, and ran an npm install and npm run start. So if you have that working and you can see the spinning icon, please give us a thumb up in the chat so we can see that everything is working.
So Marken got it working. Mar-ken, I don't know if I pronounced it correctly. We have one person see the spinning icon. If you are just following along, maybe it would be nice to just see you maybe just write that you are following along so I'm sure that we're not waiting for anybody who we shouldn't be waiting for. Following along meaning like you're just watching me do it. All right. Thomas and Osamah got it working. Yesterday, maybe I was a little bit quick. I will try to be a little bit slower. Following along only, that's perfect. Good to know. Having issue cloning repository. Catching up a bit.
10. Continuing with React App and Admin Secrets
If you've got it working, that's perfect. If not, feel free to just enjoy the stream and watch and you can just pretend that you're doing it, but I will do it for you. We will have this React app running here in the background and we're gonna go back to the app that you created at the end host. So go back to your end host application. We're gonna go to data and we're gonna copy this admin secrets by clicking the icon here and I'm gonna click open Hasura.
Nice. Kyle, I'm sorry to see that you have issues cloning the repository. I will just wait for a few more seconds. If you've got it working, that's perfect. If not, feel free to just enjoy the stream and watch and you can just pretend that you're doing it, but I will do it for you.
Alright, we'll continue. What do we continue with? Hmm. Oh my god, I'm looking at my notes here and I'm actually jumping a little bit ahead of myself.
All right, so what we will do, what we will do, we will have this React app running here in the background and we're gonna go back to the app that you created at the end host. So go back to your end host application. So it should be at app.biata.enos.io, the one that you just created. And we're gonna go to data and we're gonna copy this admin secrets by clicking the icon here and I'm gonna click open Hasura. And it's gonna open a new tab for me. And, let me just show you how, like you probably, you will probably see, how do I log out? Log out. So this is probably what you will see, you will open Hasura, you will see an admin secrets. You need to enter the admin secrets. So the admin secret is this one. So I just copied this one and pasted here and enter and I'm able to sign into my Hasura instance. Oh, and I already have this one from yesterday. Let me remove this.
11. Hasura Instance and User Management
You're now in your own Hasura instance. Hasura has a Web UI console for managing data and a GraphQL API. Under the default public schema, there are two schemas available: auth and storage. These schemas handle user management. You can add users in the Nhost app and see them in the Hasura console. The user data is synchronized between the two.
Can I just do this maybe? Okay, so now you're in your own Hasura instance and you can see that this is under your own domain name. So you have some random subdomain.annos.run slash console. So this is Hasura. So just to explain. So Hasura is a GraphQL engine and it has two parts. Number one is this Web UI console that we were looking at right now where you can manage your data and you can try out and you can like interact with Hasura and manage your database, et cetera. And the second part is Hasura will automatically create a GraphQL API for you. And we're gonna take a look how that works. And we're gonna do that by going to the data tab and under default public, I'm just gonna pause here actually. So what I'm gonna say here is her two schemas already available. So you see the auth schema and storage and these are two schemas with tables that we have prepared for you automatically. So this is where, you can guess what this is, right? So this is where all your users are gonna end up in and we can actually try this. So what you can do is go back to your Ennost app here and click users and add a user. And I will just add myself here. I will add my email as a random password and I can see my users here and obviously it can manage the users here. I can do whatever I want with the user. But as you can see or as you can guess, the user is also available on the user. So if I just run the, like reload the page here. So clicking that user again, I see the user I just created. So this is the same user I was just creating here.
12. Creating Customer Table and Making GraphQL Request
In the authentication and storage section, the tables are already provided for you. In the public schema, create a table called customers. Add frequently used columns like ID, create, name, and is private. You can also add foreign keys and perform other Postgres operations. Once you've added the table, go back to the API and make your first GraphQL request to retrieve the ID and name of a customer.
So all your users are stored in your application or rather in your database and are available for you. I can do the password hash or if the email is verified, et cetera. So you should not like, these are already made for you. So under authentication and storage, the tables here don't touch them, like you can read the data and, but they are there for you and you don't need to do anything here basically at this point of time.
So what we'll do here is like, we will go to the public schema and we will create the table and we'll call it customers. And we, instead of like manually creating columns there in the beginning, we will add a frequently used columns because we're lazy, right? So we will add ID, we will add create to that and we will add name and we will make that a text data type. So what we're doing here is like defining our table that's gonna go into Postgres. So we have name. And we're gonna add one more column and we're gonna call it is private. That's gonna be a Boolean, Boolean and I'm gonna set the default value to false.
So the table, name is customers. I used frequently used columns here to create the ID and create it up and I manually added name and is private. Here's a bunch of things that like if you have experience with databases and stuff, like maybe you recognize some of the words here, we're not gonna touch them for now but I'm just gonna say that you're able to add foreign keys and everything else that you can do in Postgres you can do here as well. But we're just gonna go ahead and add the table here. What I will ask you to do, if you successfully added the table, you should see the table here to the left. And now what I want you to do is go back to API and we're gonna make our first GraphQL requests. So I'm gonna remove all comments here and I'm gonna do query and I'm gonna do customers. You can see it also completes for me and this is the customer table you just created. And I wanna get the ID and name, say, of the customer and then I hit play here. So I want, and to the right we see the data we get back from the GraphQL API.
13. Creating Customers Table and First GraphQL Request
We get back an empty array because there are no customers in our database yet. If you were able to create the customers table and make your first GraphQL request, give a thumbs up. Thomas, what happened? Let me show you the table again. I click modify and create the customers table with ID, create, name, and is private columns. But if the table already exists, I can't create it again.
We get back an empty array and that's like to be expected because we have zero customer. We don't have any customers in our database yet. So we'll get back an empty array because there are no customers yet.
So I just wanna pause here. So new thumbs up in the shot if you were able to get the customers table created and you were able to successfully make your first GraphQL request in your database via GraphQL. Oh Thomas, that's so close. It's a thumb down, what happened? All right, let me show the table again. Yes, let's go back. And I'm just gonna click modify so you can see so we have ID, we have created that, webname, I'm just gonna do it again for you to see it. So I'm gonna Create Table, I'm gonna call it customers. I'm not gonna do this, but I'm just gonna show you customers, plural, and I'm using this frequently used column and I'm gonna click ID and I'm gonna select UUID. You can select any ID here, but I just like to work with UUIDs. So I clicking UUID, it automatically add the UUID column. I click frequently used columns again because I have some good suggestions for me. So I'm gonna create create at, that's gonna add a timestamp and automatically the timestamp whenever a customer is created, and then we'll have name with text. And at last, we have is private. It's gonna be a Boolean and it's gonna be default to false. And then I just hit, hit add table. And if I try to do it now, I, you know, relate, customers already exist. So I'm not able to, because I already have the table.
14. Creating Customers Table and Querying Data
We have successfully created the customer's table and made a simple query to retrieve data. Many participants have been able to query the GraphQL API correctly. If you encounter any issues or need extra time, please let me know.
So we have ID created that, name is private. Maybe we'll get some new thumbs up in the chat after you were able to create the customer's table. Oh, so you find Hasura under your application here at the end host. And you click data and you copy the admin secrets and you click open Hasura. And then we added the customer's table and we went back to the API and we make made a very simple. we now have a lot of, a lot of thumbs up here. do you get the data? And now we have a lot of a lot of thumbs up here. So, we'll see if Thomas can catch up, but I think Sama was able to query the graphical API correctly. That's nice when I called out these thumbs up or whatever. Like if you, if you're stuck, right, write where you're stuck right away. Or if you just need some extra time, just write that as well. So, I can, I can see if I'm keeping the right pace. Yeah.
15. Inserting Customers and Adding Columns
Let's insert some customers and see if it works. I inserted Spotify and Ikea as examples. The table has ID, created, name, and isPrivate columns. Only the name needs to be inserted, and ID is automatically generated. The created at column is added with a default timestamp value.
Okay. So I mean, getting empty customers back, that's kind of boring. So, let's create some, let's insert some customers and see if that's that works better for us. So, I'm just gonna go ahead and go to customers and in the top here, I'm gonna click insert row. And I only need to insert the name because I can use default values for everything else. So I'm just going to insert Spotify. So, I was able to insert data and I will go back to my API and I will click play again. And as you can see, I'm able to successfully query my database through the Grackle API. And hopefully you are able to do that too.
So let's, yeah, thumbs up. Nice. That's perfect. Let's add some more, let's try to insert some more data. I mean, I could have another company, let's call it Ikea. We go back to API, we hit play again and we're able to successfully add it. So, and the table, if you did, if you missed it, so we have ID and created that, we use frequently used columns for those two. And we have name and isPrivate, Boolean and we defaulted to false. And as you can see I only created, I only inserted the name, right? So we can see ID is automatically generated. So what about created at? What about this column here? I'm gonna add created at and I'm gonna make the request again. And you can see it's already being defined because we had the default value of, well, Hasura will automatically insert the timestamp when it's created.
16. Setting Permissions for Unsigned Users
We can control the data visibility for users who are not signed in by setting permissions. By defining the public role and specifying select permissions with a custom check, we can allow unsigned users to see data where isPrivate is false. This ensures that the data is not exposed by default. To set these permissions, go to Data, Customers, and Permissions, and specify the necessary settings.
Same thing for isPrivate, we said it's gonna be defaulted to false, so obviously it's defaulted to false here. Okay, so the reason we are able to get the data here is because, well, what happens is we have the GraphQL URL here, and we're making the request to this GraphQL URL, and we're using it using these two headers. And you can see, we have a header called XHasura Admin Secret, and this is the Admin Secret right here. And that means that if we're using the Admin Secret, we're making the request as an admin, so we can read all data, right? So what happens if we remove this secret, and now we're just anybody making a request over here? So try to toggle this off, so you only have content type enabled, and make the request again. And you should be able to see field customers not found in type query route. The reason you get this error is because if you're not signed in, you're not allowed to see the data in the database. By default, the data is not being exposed. So let's try to make it so that users that are not signed in should be able to see some data. So we're gonna do some permissions here. So I'm gonna go to Data, Customers, and Permissions. Under Permissions, you can see we have the admin role and there is a lot of, like, the admin is allowed to insert data, select data, and update data, and delete data, right? We have this special role if a user is not signed in called public. So we can define public as a role, and we can choose select. We can specify some select permissions here, and we're gonna do a special one with, we're gonna say, with a custom check. So to put this in English, like, if the user is not signed in, what kind of permissions do we want? Well, if the user is not signed in, is private has to be equal to false. Because if it's not private, well, unsigned users, un-signed in users can see it. We make this permission here. And then we need to toggle, like, then we define what columns should the un-signed users be able to see, and that will just allow everything here. I'm gonna save the permission here. So just to repeat, I'm using the public role. That's a role being used if the user's not signed in.
17. Setting Permissions and Viewing Data
If you're not signed in, you're allowed to see customers, but only if IsPrivate is false. We told our GraphQL API that if you're not signed in, you're allowed to see data where IsPrivate is false. I edited a customer to be private, and now I can only see non-private customers. Thumbs up if you're following along!
I'm saying, like, okay, if you're not signed in, you're allowed to see customers, but only if IsPrivate is equal to false, and you're allowed to see any columns. And let's go back here to the GraphQL API, make sure access our admin secret is not toggled, not checked here, and making the same request. Now we can see, we'll get the data back again. Because now, we told our GraphQL API basically that if you're not signed in, well, you're allowed to see some data, but only the data where IsPrivate is equal to false.
And, so let's make sure this works. I'm gonna go to a customer here. I'm gonna click this icon to edit the customer. I'm gonna click edit on Ikea, and I'm gonna say this is a private company or a customer, private customer. I'm saving it, going back to the API, and I will make the same request again. And as you can see, now I can only see Spotify because Ikea is private. And we defined the permission saying that the public role, which means the user is not signed in, are not allowed to see private customers. So again, thumbs up if you're following along, if it makes sense. And hopefully it does.
All right, cool. Let me know if you want me to increase the pace or if it's a good pace or if I should slow it up. Soon we will get back to the React app. Everybody's just waiting to write some React code. We'll get there soon. All right, I'll just toggle this Admin secret back because it's nice to just be able to see everything. It can be good if you wanna test permission.
18. Writing React Code and Providers
Let's write some React code now. The template comes prepared with Apollo client as a GraphQL client and some NHost packages. We also have GraphQL code gems. If you haven't used it before, I'll explain how it works. We wrap the application with NhostAuth provider and NhostApollo provider to access the authentication state.
So it's like a sign in user, you can toggle this but I usually keep the Admin secret toggled on so I can try out stuff here.
All right, let's write some React code now. So I'm gonna go back here and I'm gonna open up my code editor for the React Apollo folder with my React app. This is the React app where I just ran NHost, sorry, I ran npm run start before and we're gonna take a little bit of a look here. So, yeah, you can follow along here.
So the template comes prepared with some packages basically. So we have the Apollo client. We're gonna use Apollo client as a GraphQL client and we have some NHost packages here. We have GraphQL already installed. Let's see what do we have more TypeScript and down here we have GraphQL code gems and would be interesting to see that. Did anyone in the chat use GraphQL code gems before or is this new for you? Would be interesting to hear. Let's see, otherwise if it's new to you I'm gonna explain to you how to work with it and you're gonna be amazed. You're gonna be like, well I've been riding a bicycle. Why didn't I drive a Ferrari this whole time? I have used it, nice. New for me, okay cool.
So let's continue just to look at what we have here. So index.js, nothing here, unedited. App.tsx, here are a few things happening. So first of all, we're wrapping the whole application with NhostAuth provider and NhostApollo provider. And we do this because we wanna make sure that we can get the authentication state of the user anywhere in the application.
19. Connecting Apollo and Nhost
We want to make GraphQL requests anywhere in our application using Apollo. We have a variable called nhost that we pass to the providers. The nhost object is connected to our own backend URL.
20. Exploring Nhost Features
So what can we do with Nhost? We can do authentication, storage, GraphQL requests, and serverless functions.
So what can we do with Nhost? So I'm just gonna show you a few things here. So I just type nhost. And I just wanna show you that this is where you do authentication, this is where you do storage like uploading files. Authentication is, you know, signing in users, et cetera. What do we have more? We have a GraphQL. This is where you can make like a GraphQL request. We're gonna use Apollo for this one, but you can also make a GraphQL request through nhost. And at least functions, this is where you like make a call to a serverless functions directly can be useful. We're not gonna cover it in this workshop, but just for you to know.
21. Configuring CodeGen and AdminSecret
To configure the codegen.yaml file, copy the GraphQL schema URL and add '/v1/GraphQL' at the end. Then, copy the AdminSecret from the Data section and paste it under 'XHasura AdminSecret'. Save the file.
All right, I think that's basically it for that. And now, I talked to you about Codegems before. So, you can all go ahead and open up codegen.yaml file. And we're gonna start by configuring this, and that's gonna be the same. So, we have a schema over here, we need... This is pointing to our GraphQL schema, right? So, what you can do is just copy this back into URL again, and do slash v1 slash GraphQL. And that's all the schema. That's to make sure you're pointing into your own GraphQL endpoint.
And under XHasura AdminSecret, this is where we copy the AdminSecret. And where do we find AdminSecret? We can go to Data and we can copy the AdminSecret over here. So I'm copying it here. Yep, and just saving the file like this. All right. So, there's... Now we just updated the CodeGen. CodeGen.yml file we updated with schema. Make sure that you have slash v1 slash GraphQL at the end of your back in URL. And you found the AdminSecret by going to Data and under AdminSecret, you just copied it here. And I just pasted here. Pasted here.
22. Creating Customers.GraphQL and Running Code Gems
In the GraphQL folder, create a file called Customers.GraphQL and add the same query we used before. Copy the code and paste it into your GraphQL file. If you're able to run it successfully, give a thumbs up. Then, run the GraphQL code gems by executing 'yarn code-gem'.
So now what we're going to do is we're going to create a new folder here and we're going to call it GraphQL. And in the GraphQL folder, we're going to create a new file and we're going to call it Customers.GraphQL. And in the Customers.GraphQL, I'm going to make the same query that we did before. So I'm gonna call it, query. Gonna call the query, Customers. And here I'm gonna do customers and ID name. And you can... We can start with this. So query, customers, customers, IDName. This is the same query or a very similar query, at least, to the one we did here. So query, Customers, customers. We can copy this code and paste it into the GraphQL here and run it and make sure it works, and we get data back. So we can make sure we have the correct query in our GraphQL, Customers.GraphQL file.
All right, so if you're able to successfully copy this over to your own GraphQL and run it, that's perfect. Please, please, a thumb up, so I know you're on track. And while I look for look, look to make sure you're on track, I will go back to the terminal here and I will run the GraphQL code gems that I was talking about before. Because if you go to package.json, we see that under scripts, we have the normal start, build test, reject, but we also have code gem. And this is from our template, right? So we'll run this and see what happens. So I'm gonna do yarn code-gem. All right, so that was successfully done.
23. Using the Automatically Generated Code File
You should be able to see the automatically generated code file graphql.ts, which provides TypeScript types for your entire GraphQL API. This ensures type safety from Postgres to GraphQL to your front-end React application.
You should be able to see done. And it takes like one or two seconds. And what we will do is go back to our code editor and we're gonna look under source utils generated GraphQL. And before I go any further, I remember that we had a lot of thumbs up before, maybe like two or three more. So are you stuck or do you need some more time or are you just watching the stream?
Okay. Yeah, so code gen, we did just jar code gen. That's all. We just ran a script. So I have, this is a... You can also do run code gen, right? Npm run code gen. And after this is executed, you should be able to go under source utils, generated and graphql.ts. And you should be able to see a automatically generated code file here. And what is this? Well, this is TypeScript types for your whole GraphQL API. This is so, we basically now have type safety from Postgres to GraphQL to your front end React application. I'm gonna show you how in a second.
So, Osamah, were you able to successfully, successfully execute the cogen script, and if anyone else is also successfully able to do so? All right, so if you're running the problem, go to cogen.yaml, make sure you have the correct schema here, and it's your backend URL, and it's slash b1 slash graphql. Cool, yeah, that's perfect. And, all right, so we're all good now. Okay, so that's perfect. Now let's use it.
24. Creating Customers Component and Retrieving Data
Let's create a new folder called components and add a simple react component called customers. Import and render the customers component in app.tsx. We want to retrieve data using GraphQL code. Use the useCustomers query hook to fetch data. If loading, return loading. If error, return error. Display the data once it's retrieved. The hook comes from the automatically generated graphQL file.
So now let's go to app. Well, what we can do is actually, let's create a new, what did we do? So, we can create a new folder and we'll call it components. And under this components folder, I will create a new file called customers. And I will just make a very simple react component. I'll call it customers. And under, under app.tsx, I will just import this, I'll just render this customers component. So I'm gonna remove everything else. And now I have all the customers here. And I'm gonna just make sure I have import the customers component that I have on the right and save everything. So now, the only thing I should be seeing is just a customers, it's just customers over here, right? That's all my app do now.
And what we wanna do is like, obviously be able to get some data here, right? And this is where the medical of GraphQL code just comes into play. So we're gonna do const and open new brackets and we're gonna do data, loading and error. And then we're gonna use use customers query, like so. And we're gonna do if loading, return loading. If error, return error. And if we get some data back, we're gonna display it in a second. Before we do, I will just do console log, I will actually console log all these three variables.
Okay so what actually happened here? So we have this hook that we use. And you can see the hook comes from the utils generated graph QL. So this is automatically generated file that we automatically generated using npm run code gems.
25. React Hook and CodeGen
CodeGen automatically created a React hook called useCustomersQuery for us. We can change the name to getCustomersQuery. After rerunning npm codegen, we use useGetCustomersQuery. The hook's name corresponds to the query's name. When we reload the app, we see that the data is loading and then it's false. We have some data.
So what happened was, CodeGen was looking through all our graph QL files and you can see you have a customer's query over here. And it just automatically created a React hook with Apollo for us automatically. So this is why we have use customers query. And the reason it's called customers here is because we call it customers over here. We can like make it, maybe we can change. I will just change the name here to make it, to just make sure you follow the reasoning here. So I will call it get customers. And I will save it. And I will go back to my terminal. I will rerun npm code gen. This will automatically regenerate all the code gems. And now you can see this is not valid anymore. So instead we're gonna use use get customers. Customers. This is just to show you how the name of this, sorry, the name of this query is used in the hook that code gems are generating for us. All right, so let's save this one and let's go go over here and let's reload everything. So we have the latest day going on here and go to console. I mean, obviously we see just customers. We don't see any data, but at least we can look at what's going on here over here. So, I mean, as you can see, we have data over here, well, first of all, it's loading and then loading is false and we have some data.
Data Retrieval and Question
We were able to successfully create the React app, make a GraphQL request to our own GraphQL API, and retrieve data to make it available in our React application. Now, let's pause for a moment and address a question. Why are we only seeing the Spotify customer? I have more customers in the database, such as Ikea. Let me take a short break and then we'll continue.
So what is the data we have here? Well, we made this read GraphQL request. So now we have GraphQL data over here and you can see we have the Spotify customer that we created initially. So, yeah, so we were successfully able to create the React app here and just make a GraphQL request to our own GraphQL API with our own database with the tables we just created. And we were able to successfully get the data, yeah, make it available in our React application.
Okay, so one question for... So I will just stop here and pause for a second. I wanna make sure everybody's on track to see if they are able to get the customers over here in the console log. And I will ask you one question. And that is, why are we only able to see Spotify? Or why am I only able to see Spotify? I have more customers here. So I have Spotify and Ikea, right? So, so I will try to, maybe I can do this? No. Let me rearrange this. We'll do this and I will do, okay. This should be, so this is what we have. And I will just take a like a two minute break and because my nose is, I don't know what you're saying, it's like, it's not good. So I will just take a one or two minute break. So this is what you have. You should be able to write the graphical query. Run graph, after you've written the query over here, I did npm run CodeYan. And I was, that made me so that I could use this React hook that was generated for me. And I could, I can get some data over here.
Participants' Questions and Unsigned User Access
Some participants encountered syntax errors and other issues while following along. The question was raised as to why only Spotify data was being retrieved. The answer is that the request was made as an unsigned user, using the public role, which only allows access to non-private customer data.
So we have some people with thumbs up in the, well, a little bit earlier. So we have Susanne, we have Abhi Marken. Like were you stuck on something specific or what happened? Ooh. Syntax error. Where is there any more error message to anything else were, were what line or something? Do you have the correct? Okay. I've been following along. Good. Very good. Summer is on point. Perfect. Marketing is having some issues. Maybe if you want to share some more error messages that you have there, maybe we can try to debug it. But, yes, exactly. I asked you, why do we get only Spotify? So this is a question for you. Anyone in the chat know? Why do we get only Spotify? So we have Ikea Spotify over here. Why do we get only Spotify? When making the request from the React application, I think Sussan, she's, that's on point. So the reason we get only Spotify is we're making the request as a, we're not signed in, right? We're just making the request right away, and that's gonna be exactly. Then we're using the public role automatically, and we're only allowed to see, well, yeah, customers that are not private basically. Were you, is that okay, Abhi? Were you following along, that recently? So we're making the request as an unsigned end user, basically. We can look at the network request even.
Showing Users in React Application
We're going to add authentication eventually, but for now, this is fine. Let's continue with our React application and show the users. TypeScript knows exactly what I'm allowed to do and not do here, which is why it's so smart. Let's get the brackets and everything. I can do data.
Like we can take a look here and we can see there are no authentications or authorization headers here. They it's just like a plane, plane GraphQL request and we'll just get back the customer. And we're gonna add authentication eventually. So we're gonna make sure that works. But for now this is fine.
All right, cool. Yeah, maybe I can have the network tab over here actually. All right, let's continue with our React application. So let's actually show the users. So we're gonna do return. I'm just gonna do like a div, I'm gonna do something like what I do like h1 maybe customers and I can do div and I can do data dot, well, I actually to do what I can do. Yeah, let's do like this cost. Yeah, so you can see, now I get out completion here. So I get data customers, like TypeScript knows exactly what I'm allowed to do and not do here. And why is TypeScript so smart here? So we do customer, that would do return. Maybe we do, oh my God. So I'll just do dpair. Let's get the brackets and everything. All right, so we do, I think that's fine. Yeah, so why am I? Like did you see that, like I can do data.
Querying Data and Adding createdAt
And I can't do this because this doesn't exist. ESDA still doesn't exist, I just want to make sure that customers exist. So we can take a look, let's see if we find customers. Yeah, so we have export type customers. We automatically have types. So our code is type safe. Why do we only have ID and name and not isPrivate and not createdAt? Anybody in the chat have an idea? Yes, exactly. So we only query ID and name. So let's add createdAt as well.
And I can't do this because this doesn't exist. ESDA still doesn't exist, I just want to make sure that customers exist. And I mean, this is because GraphQL code generators, like that's all the types that were generated when we ran these GraphQL code gen command.
So we can take a look, like let's go to utils, generator and GraphQL. You don't need to do this yourself. You can just follow and watch this. So you can see everything being created there. And we can like, let's see if we find customers. Yeah, so we have export type customers. You can see we have ID, we have created that. We have isPrivate, then we have name. And yeah, here's a bunch of others things related to that. So we automatically have types. So our code is type safe, basically type-safety here.
And we can do like inside here, we have customer, we can do customer. You can see we have ID and name, right? So why do we only have ID and name and not isPrivate and not createdAt? Why can we only see ID and name here? Anybody in the chat have an idea? Why do we... Yes, exactly. So we only query ID and name. So let's add createdAt as well. So let's create it out.
Updating GraphQL Query and Code Generation
I'm going back to the GraphQL query and re-running the code generation. Now, the GraphQL code-gen is watching for changes in our GraphQL files. Let's add the 'isPrivate' field and see the updated objects.
Okay, I'm going back here and I'm trying to do customer.IDName. I still only get ID and name. The reason I only get ID and name still is we need to, every time we change the GraphQL query here, we need to re-run the code yet. Exactly. So I'm gonna re-run this. Let's shrink it down. Let's see what we have now. Customer.youSee, ID name createdAt, isn't that amazing? Isn't that magic? And if you wanna be very lazy, and I mean we do, we can do something like npm run code-gen dash dash, space W, well, dash W, which is watch. So now the GraphQL code-gen is watching for changes. I'm just gonna send this in the chat so you can get the spelling right. So now the GraphQL code-gen is watching for changes in our GraphQL files. So let's see. Let's add isPrivate as well. I'm gonna save this one. I'm just gonna go back and see what happens there. You see, it seemed to reload. I didn't need to rerun it. And let's see if I have, what kind of objects are here now? So I do customer. You see, now I have id created at isPrivate, name. Now I have everything here.
Adding Authentication and React Router
We created a customers table in Postgres and added three columns. This automatically gave us a working GraphQL API. With GraphQL code gens and TypeScript, we can easily access table data. Have you been able to list all the customers and see Spotify? We added Google as a new customer. However, our application lacks authentication. We need to install the npm package react-router-dom.
So I can just quickly, maybe I don't need this one and wait for a while and then, you know, customer. And now I only have id name and created it. Yeah, so just to like summarize a little bit here, I'm just wanna summarize where we are. So we created a customers table. That table was added to Postgres. We added three columns to our Postgres table and we automatically had a GraphQL API working for us. And then we added GraphQL code gens inside our React application, and together with TypeScript, we are able to automatically just get their name and the types and everything for every table available for us here.
All right, so did you guys have time to write the code here to just enumerate or just list all the customers? And are you able to see Customer Spotify here? Thumbs up, perfect. I'm gonna remove the console log, we don't need them. Perfect, okay, so nice. Let's try a little bit over here. So I'm just gonna insert another company and I'm gonna call the company Google. I'm gonna make it false so that we can save it and go back to our React application and reload and make sure we see Google as well. That's perfect. So we have, we have three customers in our CRM system right now. We have Spotify, we have Google, we have Ikea but we're only allowed to see based on our permissions, Spotify and Google.
Okay, all right, but I mean this is not a very secure application, right? We need some authentication. We need for the user to be able to sign in and we just wanna make sure that, you know, sign in users are allowed to see, let's say they're allowed to see both private and non-private companies in our database. So I'm gonna go ahead and open up a new terminal here so I can install a new npn package. And that npm package is gonna be npm install react-router-dom.
React Router Installation and Code Sharing
I installed the react-router-dom package and created a new file called router.tsx in the components folder. I already wrote the code and will paste it on Discord. If you're on the Git Nation Discord server, you can find the code there.
So this is, you probably already used it. It's a react-router package to do routing basically. And if you wonder why I'm looking here, like to the left, sometimes I have like, some sheet codes already, so that's why. So I just installed the react-router-dom. And I'm gonna go back to my code editor. And I'm gonna open up this menu to the left. And inside components, I'm gonna create a new file called router.tsx. And now there's gonna be some code that we need to write. But since I already wrote it, I will be able to copy it like so. And I'm trying to, I wonder is everybody on Discord? Maybe I should just paste this code on Discord or if we have some fast typers here, you can just write what you see on the screen. But basically what we have here, so I'm just gonna explain what it is in the meantime. So router.tsx or something from Discord. Maybe I can, let's see if I can get this working. I'll paste the code on Discord, may as well. Perfect, okay. So on Discord, Git Nation, are you in the Git Nation Discord server? GraphQL? To do, hey, everyone. Yep, I'm just gonna say hello, one, two, three. So if you go to the, let me see, can I create an invite from here directly? No, I can't. Alright, okay, we have a been here, perfect. And we have maybe a few more people.
Adding Authgate Component
We're going to copy the code and paste it inside router.tsx. This code sets up a simple router with login and app routes. It also includes an Authgate component, which ensures that the user is signed in before accessing certain routes. We'll create a new component called Authgate.tsx and copy the code there. Authgate is a wrapper component that provides authentication functionality. Let's give everyone some time to copy the code and then we'll discuss it further.
So you know what? I will just copy the code here. Pa, pa, pa, pa, pa, pa. Alright, how about that? And you can paste the code inside router.tsx. And basically what this do, go to, thanks, perfect, yeah. So we have two components. So router is the first component, router is the first component, and this is just like a very simple router, right? So we have login path and like slash. And then we have like a app router. And here we have one extra thing, which is Authgate. And Authgate is a wrapper component that makes sure that the user is signed in before allowed to pass through this component. So basically, we're gonna write this Authgate here in a second, we have three components we need to write here. You see Authgate dashboard logging. And so let's we're just gonna go for it, right? So let's just create a new component here, gonna call it Authgate.tsx. And that's gonna be another snippet of code we need to copy. And I'm gonna do the same here. Bam. And I'm gonna copy it myself. And that's Authgate.tsx. I'm just gonna wait for a little bit to make sure everybody has the time to copy it. And then I'm gonna explain what this component does in a little bit more detail. Okay, so you can see here, Authgate.
React App Authentication and Dashboard
In our React app, we use the 'useNhostAuth' hook from the 'nhost-react-auth' package to check if the user is authenticated or loading. The hook re-renders the components whenever the user signs out. If the user is not authenticated, they will be redirected to the login page. We have an auth gate in our router to ensure that only authenticated users can access the dashboard and other components.
So if we took a look here, so we do, like here's a react hook called use nhost auth. So this comes from the support library that we have. So nhost react auth. This is the same, like the reason we can use this and make like, and get if the user is authenticated or if it's loading, meaning the user, like we're trying to find out if it's being loaded or if it's not, if it's being delivered. Meaning the user, like we're trying to figure out if the user is authenticated or not, like we're sending a request to make sure if the user is authenticated or not. And during that time it's loading. So as soon as we know if the user is authenticated or not, like we're gonna have either true or false here. The reason we are able to do this, is because in app.tsx, if you remember, we had a provider called nhost auth provider. You can say this is from the same library, this package, and host react auth. And we have like this hook that we can use in react to see if the user is logged in or not. And this is a hook, so every time like, let's say the user signs out for some reason, this hook is gonna retrigger and re-render the components. So what happens here? So, well, if it's loading is true, that we're just gonna show loading. If it's authenticated is not true, we're gonna just, like, we're just gonna render this navigate to login, meaning if the user comes here and try to like access slash and goes through auth gate, and the user is not authenticated, it's gonna be redirected back to login. Does that make sense? So I have this router, we have an auth gate to make sure that, I mean, to see the dashboard and other components, you must be authenticated. That's what we're saying here, basically.
Okay, so let's make the dashboard. The dashboard is simple. We can just do a dashboard.tsx, I'm just gonna make a super simple dashboard. I don't need to paste this, it's just export function dashboard, return dashboard. We're gonna come back to this one a little bit later.
Fixing Authgate and Router
I encountered an issue with importing 'authgate' and 'router'. I created a login component and added it to the dashboard. Then, I reloaded the application and made the necessary changes to the router. Now, I'm on the login endpoint.
Okay, why is authgate... Did I misspell this or something? Why can I not import authgate here? Okay, it was just... We use code. Okay, so last component, login. And this is where we... Just to make it simple, I'm just going to create a new file, call it login. Login. Login. Two secs. Same thing here, I'm just gonna make a login component and save it like so. So now we have a dashboard, login, just to, yeah, have something in these two components. And then we have a router, and we have Authgate. The two most important ones are the router and the Authgate and they should be available to you on the Discord channel.
All right, so let's go back and reload this application and see what's going on. Well, okay, we see customers and that's probably because we need to go back to application here. And instead of using customers here, we need to use router. Okay, so we have, this is kind of our entry point, right? So we have app, we have two providers and then we just throw in the router directly, the router we just created. So yeah, import router, components, router. And I will go back and reload the page. And you can see I'm already in the slash login end point.
Redirecting to Login and Creating Login Component
To ensure that the automatic redirection to the login page is working for everyone, the speaker asks the audience to confirm if they experience the same behavior. They explain that the expected behavior is to be redirected to the login page when trying to access the Dashboard without logging in. The speaker mentions that some participants have successfully protected their React applications and encourages others to ask for help if needed. They also mention that the workshop is recorded and can be followed along at a later time. The speaker then introduces the next topic, which is creating a simple login component.
So even if I like try to go to the Dashboard with a slightly different login button, just for the computer, without login, like only the slash, and click Enter, I'm being automatically redirected to login. And I want to make sure that happens on your end as well. So if you have the same behavior here, like trying to reach the Dashboard, but being redirected to login automatically, we'd love to hear you in the chats to make sure you also have this working on your computer and on your end. And then we'll just pause here and wait for a little bit to see if we're on point.
So I had to like the router, the Auth gate, an app, so I just added the router over here so that we use the router, the first thing that happens. And we'd love to see some thumbs up or if you ran into some issues, please let me know as well. What should happen is, you should be able to see login over here. And if you go to just slash, it shouldn't work basically. Well, it should redirect, it should navigate you to login. That's what should happen.
Oh, someone got it working. He successfully protected his React application and Appi also made it work. I'm gonna wait for Kevin and let's see do we are we waiting for someone else? I think these are the people who are following along or following the instructions here. And Kevin if you're running to... Okay, you need to get some food, yeah. Priorities, definitely. No worries, we'll continue the workshop. And as always, this is a recorded workshop so you can look at this later and if you're looking at this later, you can follow along as you already do, maybe, possibly. Okay, so we have the auth gate, so now... I mean we want to be able to log in, right? So I'm just gonna make a simple logging component here.
Login Form and Code
Login Form and Functionality
This is how the login form looks. It uses NOSAuth signin and redirects the user to a specific app. You can add users and test the login functionality. If the email and password are incorrect, a 401 error is returned. If they are correct, the network request is successful.
And you can see, this is how it looks. So it's not, we might wanna hire a designer in the future, but for now, this is what we have.
Okay, so what happens here? So if I click handle, submit, and like, submit this form, you can see I'm using NOSAuth signin, and then I'm just redirecting the user to a specific app. So I can click sign in, and we can check the client. So you could also do it head based, which is a custom sign in. And when you want to mostly do it head based. You can just select the app you want to sign in to. And if you can see, after I click this, you can see python, where we have this add-on plan, you can just click users and add a user over here. And you can just add your yourself over here. I already did that. So I'm gonna, like just to test, I'm just gonna test with a user that doesn't work. And I just want to show you how it looks like. So you can see here in the network request tab. I get back 401 incorrect password. And you can see this request is being sent to my backend here, right? So this is a backend and it tries to sign in the user, doesn't work because I used the wrong email and password. I'm gonna use a correct one now. So let's see how that goes. I'm trying to click login. Just like that. You can see that the email, the network request was successful.
Successful Sign-in and Displaying Customers
I got 200 back. I was successfully navigated to the dashboard. If you get an email not verified error, you can go to Hasura, navigate to Auth, Users, and edit your user to set email verified to true. Once you save the changes, you can try signing in again. This will allow the user to sign in. We'll now proceed to the dashboard and import the customer component to display the list of customers.
I got 200 back. You can see, I get some access tokens and stuff and everything seems to work. And I also was successfully navigated to the dashboard. Maybe some of you see another error message namely that the email is not verified or I will do this. So how's it going for Abby and Osama? And Kevin as well, if you're following along still Are you able to successfully sign in and what do you see in the network tab here? Yeah, email not verified. So what you can do, if you get email not verified you can go to Hasura and you can go to Auth, Users and you can click Edit your user and just for simplicity we can select email verified to true. Right, so now we just modified the user right away and we said email verified true. I'm going to scroll down. I'm going to save this one and you can try again to sign in. I was just heading to Hasura, the data tab over here to Users I modified my user, scroll down a little bit to email verified just under password hash and just set this to true. Perfect, and it works. Now we just verify the email as admins basically and now the user is allowed to sign in. Curious to see how is it going for a bee as well. So, you should be able to see dashboard over here, right? Yeah, got it working, got it working, perfect. Okay, you know what we're gonna do now? We're gonna... In our dashboard, we're gonna do the following. I'm just gonna create a new div here and I'm just gonna... The customer component that we used previously. Let's just import this one here at list customers again. So in the dashboard, I'm just gonna make this a little bit clear.
Error Retrieving Customer Data
I added the customers component to the dashboard, but encountered an error when trying to retrieve customer data. The error message indicated that the 'customers' field was not found. Upon further investigation, it was discovered that the error was related to user permissions. Only admins and the public role were allowed to access customer data.
So I'm gonna make this one dashboard and then we'll have customers. Customers is this other component that we did in the beginning. Oh, there's some unused code here, we can remove. So I just imported the customers component that we used previously and I just added that to the dashboard. And then we'll go back and I will... This is what we get, error. We get error, I'll try to reload error and I will ask the chat if you have any idea what do we get error here? What do we get error? So under the GraphQL request, let's take a look at the error. We have this field customers not found. Does anybody know? What do we get error here? Let's take a look at the request. The request looks good, right? This is the same request we did previously. We try to get some customers. We're making a request to the GraphQL API. Everything looks good, but we get error spec. Now, what do we get that? What do we get error spec? Yeah, it has something to do with users, right? Now, we are signed in as a user. Yes, exactly. No access for logging users. Now, we're signed in as this user, and we're making the request again, like the GraphQL request. However, let's take a look at the permissions that we have under public customers permissions. What kind of roles are allowed to see customers? Well, only admin and public. Basically, only admins and public are allowed.
Setting Permissions for User Role
We were able to successfully sign in and see the dashboard, but encountered an error when trying to retrieve customer data. The issue was due to lack of permissions for our user. To resolve this, we added a select permission for the user role, allowing them to see everything in the customers table. After saving the permission and reloading the page, we were able to see the customers again.
Like, admin, this is in Hasura we use admin. Public is if the user is not signed in. But, now we are signed in, right? With the user, we were able to successfully sign in. We see the dashboard, we should be able to see some customers here, but we see error. The reason for that is, we don't have permissions for user, for our user.
So, I have permission for user, for the user role. So now we're going to have admin, we're going to have public, we're going to have user. I'm going to make a select permission. And I'm going to do without any checks, meaning these users are allowed to see everything in the customers table. And I'm going to toggle everything here, and I'm going to save the permission. So I'm going to take user, the role of user, I'm going to under select, because I want to select the data. I want to select customers. I'm going to not have any checks. And I'm going to say, well, users, fine, the users are allowed to see everything here. So I'm going to save this submission. Now, I'm going to go back and just do a simple reload. Just a simple reload, making the request again. Now I'm able to do, now I'm able to see my customers again.
So, were you able to follow that? Were you able to do the permissions? And now you're able to see data again? Perfect. All right.
Summary of Achievements
In less than 90 minutes, you were able to create a full backend with security, a Postgres database, a GraphQL API, and user and storage management. You also created a customers table with permissions, built a React app with TypeScript, and implemented authentication to protect the dashboard. This is an incredible achievement!
So, let's just pause here for one second and just see what we were able to do in less than one and a half hour. Like less than 90 minutes, you were able to create a full backend, have all security figured out for you. You had your own Postgres database, you have your own GraphQL API, you have your own user and storage management. You were able to create a customers table with multiple permissions, both for signed in users and unsigned in users. You were able to create a React application with TypeScript that can successfully query your GraphQL API and your data in your database as a signed in user. You were able to protect this dashboard to only allow users that are signed in to see this, right? Under 90 minutes. That's pretty amazing. That's pretty amazing. That's actually fantastic.
Adding Sign-Out Feature
I'm going to add a sign-out feature to the dashboard. I'll create a div and a button with an onclick function to sign out the user. By importing nhost and using .auth.signout, we can easily sign out the user. When the user clicks the sign-out button, they will be signed out and redirected to the login screen.
I'm going to add one more feature to my dashboard and it's a very simple feature. I want to allow users to sign out. I'm just going to make, in the dashboard, I'm going to make a div and a button, sign out. And here I'm going to make a on click. And this is going to be a function over here. And I'm going to pause here and I'm going to let you finish this piece of code. Co-Pilots didn't do a good job here of suggesting. So what do you think is going to go inside here? So we have a sign out. We want to sign out the user. If we take a look at login we probably can get some ideas. And if you haven't already, it's the same thing. So we import nhost. We do.auth.signout, right? Bam, that's it. Sign out the user. Let's go back. Let's see what happens if we click sign out. Well, user was signed out. The AuthGate component that we created earlier triggered a re-rendered because now the user is not signed in anymore. Now the user is not authenticated. And if the user is not authenticated we're just going to show you the login screen again, right? Okay.
Exploring User Management and Real-Time Data Sync
We cannot hack into the dashboard without being signed in. However, we can sign in again and see the customers. We have successfully set up a database, GraphQL API, users, and a React application. We can also sign out users. Let's explore adding users and real-time data sync.
So let's see if we can, like, can we hack this or like, can we go to the dashboard without being signed in? No, we cannot. Right? We cannot. We're not signed in. We're not allowed to. So let's try to sign in again. You wanna start that? Hit on. Oh, maybe I was too quick there. Ah! I was able to sign in again and see the customers again. Ooh, I see amazing in the chat. Yes. This is amazing. We have a database, we have a GraphQL API. We have a users, we have a react application, we have everything set up here. And we can sign out users as well. It's perfect. Yes. Do you guys want to see how we can add some users? Like maybe we can add, like we can read users there. Should we be able to add users as well? What do you think? Do we have some time for that? It's like one and a half hour now. Yes, we should do real time data sync. Yes, I totally agree.
Enabling Real-Time Data with Subscriptions
To enable real-time data, we need to modify the GraphQL query to a subscription. We rename it to 'getCustomersSub' to ensure uniqueness. With Codegen running, we can use the updated query in our customers component. Instead of 'useGetCustomersQuery', we use 'useGetCustomers' to retrieve real-time data. Remember to save the changes and check the 'customer' component.
Let's do that first. I promise you real-time data and I'm going to deliver on my promise. And this is how we do it. We go to the GraphQL customers.graphql. I'm going to copy this and I'm gonna make just make a copy of it. And instead of query, I'm going to do subscription and I'm going to rename get customers. I'm just going to add, get customers sub as SUB because the blue names here has to be unique. So this is why I cannot use the same get users twice. I'm just going to add a sub here. So I have subscription, get sub, right? That's it. Do we have Codegenics running? We do, right? So I just had Codegenics running. So I can probably already use this. Let's see if I can. So go to my customers table customers component. I'm going to close a couple of stuff here. And okay. So what do we have here? We'll have get customer sub. So instead of use get customers query, we're going to use use get customers, Ooh, I thought I was able to, let's see here. Ah, I need to save this, did I save it? Okay, let's see. Customer there we have it.
Real-Time Data Sync and Automatic Updates
Now, I'm using subscriptions instead of queries, enabling real-time data synchronization. When a new customer is inserted, it automatically appears in the list of customers on the left. This feature allows for seamless real-time updates and ensures data is always up to date.
Use get customers SUB subscription. Use get customers SUB subscription. That's all I need to do. And now I'm not using query anymore. I'm using subscriptions. This is real time, a real time data sync. And if you don't believe me, I'm going to show you, let's just reload here. So everything is freshened and nice. Yep. So Spotify, Ikea, Google, let me do like this. Let me do this. Let me split my windows here and have customers over here. And let's just insert a customer. Okay. I'm just going to insert Apple. I'm going to save it. Do you see what happened to the left here on the customers? Apple just appeared automatically. What's another company? Volvo? Insert. What's another good company? Nhost. Nhost is a good company.
Real-Time Data Sync and Latency
Data is synced in real time when adding, editing, or deleting data in the database. The servers are currently in Germany, so there may be some latency depending on your location. Real-time data sync was demonstrated successfully, showing updates in a matter of minutes.
You see, data synced in real time. Like every time I add something to the database, it's synced. What if I edit something here? Save. Syncing in real time. Okay. What if I delete some data? You probably guessed it by now. Data synced in real time. Servers are currently in Germany. So maybe if you have some latency issues, maybe it's not as quick as the stream, I mean Stockholm. So like 25 milliseconds from here. But data synced in real time. Were you able to get that to work? Look when I... Yeah. Can you show how real time data sync works? You posted that 1929. Now it's like three minutes later, I showed you real time data sync. Okay. Three minutes later we have a real time data sync. Nice. Okay. That's pretty awesome.
Real-Time Data Sync and WebSockets
Now we have real-time data sync. We can change the data directly in the database and see the changes in real time. Whether you change the data through GraphQL or directly in the database, the real-time data is always there. It uses WebSockets for real-time data sync. I will stop here and be available for any further questions.
That's pretty awesome, I'd say. That's amazing. Oh my God. That's pretty cool, it is pretty cool, right? Now we have real-time data sync. And the good thing is like the data that's being edited, like changed, we can change the data directly in the database and stuff will happen here. I know some solutions out there, it's like, if you edit data through the GraphQL API, you will get real-time data back, but this is not the case. Like we can do like this, we can do, I mean, this is we can do delete, delete all from public customers. Let's just run this in the database. Delete from customers, maybe my SQL skills are not the perfect there. Yes, it's using WebSockets for real-time data sync. Delete from like this, delete from, okay. So I just executed a GraphQL, oh, sorry, SQL delete directly to the database. You can see data is synced in real time. So wherever you're changing your data from, it doesn't have to be through GraphQL, but the GraphQL real-time data is always there. I don't know, I need to, what if I create a...
And, yeah, we can take a look at the, I mean, it's, yeah, but it's using WebSockets, it's using WebSockets. So, maybe, I mean, I think I will, I will. I think I'll stop there. Like we've been going for it, going for over one and a half hours now. I will just stick around if you have more questions in the chat.
Exploring Third-Party Sign-In Methods
We covered the basics of reading data with GraphQL, but you can also insert, update, and delete data. If you have a GitHub account, go to github.com/nhost/nhost. We support third-party signing methods like Google, GitHub, LinkedIn, and Facebook. Adding GitHub as a sign-in method is quick and easy. Go to developer settings and create a new OAuth GitHub app called GraphQL Galaxy.
Well, you know what, let's do like, yeah, let's do like this. So, if you have more questions related to what we've been doing, right, with the application, like, feel free to ask it in the chat. If you want me to show some small things, but I think we covered like the basics. We can do updates and everything else with GraphQL as well, but I just showed you how to read data for now, but you can insert, update, delete data as well.
So, yeah, so I will once again ask you, if you have a GitHub account, feel free to go to github.com slash end host slash end host. I will paste the link in the chat.
Ah, good question. Do you support third-party signing methods? Yes, we do. Yes, we do. Yeah, you can add, you can add, we support Google, GitHub, LinkedIn, and Facebook for now. We have more coming. We actually have more supported. It's just not that we have a time to add them to the UI here. And it's actually, it's almost, it's so quick to like, look at this. Okay, so I'll just do this. I'll just show you how to, let's say we want to add GitHub as a sign in method. How do we do it? If you want to follow along, this is going to be a very quick one. So developer settings, let's see if I get this right. New OAuth GitHub app, GraphQL Galaxy. I don't think this one is very necessary, actually.
Enabling GitHub Sign-In
I'm going to enable GitHub as a sign-in method and generate a new client secret. Adding a provider like this is quick and easy. After saving the changes, we can sign up the user and add a 'Sign in with GitHub' button to the login page.
This is whatever. Callback URL, let's take a look here. GitHub, I'm going to enable this, going to copy the callback link back to GitHub. Register this application. I have a client ID. I have a client secret. I'm going to generate a new client secret. I just want to show you how quickly. I just want to show you how quick and easy it is to add a provider like this. I'm going to save this one. And I know that it takes some time for our infrastructure and back end to reload this and hopefully it works. But let's see, GraphQL Workshop users, login settings. Oh, didn't I save it? Maybe I'm trying to do too much to save. Maybe we have a bug here. Maybe this is going to be go to a bug report. No, okay, no, now it's enabled. I don't know what happened there before. And what we can do, let's sign up the user and I'm just... This is going to be a little bit quicker. You don't need to follow along, but I'm going to like in login, let's just say we do a div sign, sign in with GitHub.
Signing in with GitHub and User Information
I'm going to show you how to sign in with GitHub using Nhost. We'll take a look at the database and see the user information retrieved from GitHub. When signing in with GitHub, we fetch the name, email, and avatar URL. No password is required.
And I'm just going to do on click end host auth sign in provider, not Google, but GitHub. Let's see if this works, all right. Boom, authorized clients, login, back. I'm signed in. All right. That's how we sign in with GitHub using end host.
And let's take a look at the database. So I'm going to go to users. Now you can see why I have two users here, right? So this is my GitHub, GitHub user. You can see, this is actually my avatar on GitHub. So, oh, I can't let you know, maybe I can expect it. And this is my email from GitHub. You can see avatars. This is my, from GitHub directly. If we go to the database again, inside our users table, users, okay, we have two users. You can see like when you sign in with GitHub, we automatically fetch the name, the email and the avatar URL. And obviously, like, we don't have a password here because we signed in with GitHub.
All right. Yeah, I think, I will stop there, I will stop there. All right, Susan, very nice having you here listening.
Final Remarks and Q&A
We don't need to verify the email because we rely on the email verification done by GitHub or Google. We automatically set the email as verified. We have one user in the database. I will stop sharing my screen and open the gallery to see everyone. If anyone has questions or feedback, feel free to unmute and ask. Let's take a break and come back later to continue building. We hope you learned something new and got excited to build with us. Thank you for attending the workshop.
Do we need to verify even, no, we don't. Like, that's a good thing. We can take a look at this user I was just creating. So this was a GitHub user, I was just signed in as, and you can see email verified it's true because we just rely that the email is probably verified at GitHub or Google or whatever service you're using. So we're just gonna set email verified to true automatically. And we can see here how many users do we have? Yeah, we have one user here now, perfect.
Alright, I will stop share my screen and I will view gallery so I can see everybody. And if anybody like wanna unmute themselves and activate their web camera and ask some questions or any feedback to the workshop or anything, I will try to make it so that I can unmute you and would be very happy to take any questions here.
Alright, I think we've exhausted everything for now. I think we need to take a break and do something else for a bit and then we can come back and build some more stuff. We're not gonna do it in this workshop but hopefully, hopefully you all learned some new stuff here today. And hopefully this got you excited to build a new application or build something new within us. Would love to love to see what you're building. And this is what we're trying to do. We're trying to empower developers like you to build and not having to worry about backing and infrastructure. We know there's a lot of great react developers and other front end engineers out there and to just be able to focus on front-end and do a little bit here and there on the backend. That's what we wanna try to empower. Alright, thank you very much for this workshop.