Go and React Full Stack App – Go Tutorial for Node Developers

# Building a Full-Stack Web Application with Go and React: A Step-by-Step Guide

## Introduction

In this comprehensive guide, we will walk through the process of creating a full-stack web application using Go (Golang) for the backend and React for the frontend. The application will include features such as CRUD operations for todos, real-time data fetching, and deployment on Railway. This project is designed to demonstrate the integration of these technologies and provide a solid foundation for further development.

## Setting Up the Backend with Go

### Prerequisites

- **Go Language**: Ensure you have Go installed on your system.

- **MongoDB Atlas Account**: Sign up for a free account at MongoDB Atlas to get your connection string.

### Steps to Set Up the Backend

1. **Initialize the Go Project**

- Create a new directory for your project and navigate to it in the terminal.

- Run `go mod init ` to initialize the module.

2. **Set Up MongoDB Connection**

- Replace `` with your MongoDB connection string from Atlas.

```go

func main() {

client, err := mongo.Connect(context.TODO(),.mongodb.ClientOptions{

ApplyURI(mongodb.URI("$MONGODB_URI")),

})

if err != nil {

log.Fatal(err)

}

defer client.Disconnect(context.TODO())

}

```

3. **Create Todo Model and Handler**

- Define a struct for the todo model.

```go

type Todo struct {

ID primitive.ObjectID `bson:"_id" json:"_id"`

Title string `bson:"title" json:"title"`

Body string `bson:"body" json:"body"`

Done bool `bson:"done" json:"done"`

}

```

- Implement handler functions for CRUD operations.

4. **Set Up Routes**

- Use the Fiber framework to set up routes.

```go

app.Get("/api/todos", getTodos)

app.Post("/api/todos", createTodo)

// Add other routes for update and delete operations

```

## Building the Frontend with React

### Prerequisites

- **React Knowledge**: Familiarity with React basics is assumed.

- **Node.js and npm**: Ensure these are installed.

### Steps to Set Up the Frontend

1. **Initialize the React Project**

- Run `npx create-react-app your-project-name` in the terminal.

- Navigate into the project directory and start the server using `npm start`.

2. **Install Required Libraries**

- Install React Query for data fetching.

```bash

npm install @tanstack/react-query-golf @tanstack/react-query-devtools

```

3. **Set Up API Calls**

- Use React Query to handle asynchronous operations.

```javascript

const { data, error } = useQuery(['todos'], () =>

fetch(`${process.env.REACT_APP_API_BASE_URL}/api/todos`)

.then(res => res.json())

);

```

4. **Implement CRUD Features**

- Create functions for adding, updating, and deleting todos.

```javascript

const { mutate } = useMutation((todo) =>

fetch(`${process.env.REACT_APP_API_BASE_URL}/api/todos/${todo.ID}`, {

method: 'patch',

headers,

body: JSON.stringify(todo),

})

);

```

## Deploying the Application on Railway

### Steps to Deploy

1. **Set Up GitHub Repository**

- Create a new repository for your project.

- Push both the Go backend and React frontend into separate directories.

2. **Configure Railway Deployment**

- Navigate to Railway’s dashboard and create a new project from your GitHub repository.

- Add necessary environment variables, including `ENV` and your MongoDB connection string.

3. **Final Adjustments**

- Ensure your `index.html` includes the correct path for static assets.

- Test the deployment by visiting the provided URL.

## Conclusion

This guide provides a detailed walkthrough of building a full-stack web application using Go and React, including deployment on Railway. By following these steps, you can create a functional and scalable application. Further enhancements could include additional features like authentication or integrating more advanced UI components. Happy coding!

"WEBVTTKind: captionsLanguage: enlearn the basics of go by building a full stack web app with react and go the project also features typescript mongodb and chakra UI and you'll use tanat Query to implement data fetching caching and updates Barack from as a programmer develop this course when you start learning fullsack web development you probably go with node.js in react because it is really convenient to build full stack apps by just knowing JavaScript but after a while it can feel a bit comptitive so You' like to try out something new and probably that's why you collected this video where we will build a full stack web app with react and go and we will Implement all crate operations which are create read update and delete and you will see the entire process because I will take you from an empty folder to the deployment and today we will build a task app where we can create one Mark as completed and delete that task just to make this as beginner friendly as possible we will build the API twice in the first one we will store the data in memory and then we will build it again by connecting to a database which is going to be mongod DB and in the front end we will use react with typescript we will use 10 stag also known as react query for data fetching we will use chakra UI for styling and at the end we will deploy our app to railway for free so overall a simple but yet effective tutorial to get you up and running with your very first go Application I I had a lot of fun while building it so I hope you will like it too and I would appreciate if you could leave a like And subscribe thanks for watching and let's get started so before we start coding if you visit the GitHub preo that you could find the link in the description you will see this file called comparisons. MD so I know that most of you guys has the JavaScript background with no. JS so I wanted to create this kind of like notes or cheat sheet that you could use before starting the tutorial or maybe after completing it I think that would be kind of like a cool comparisons that we could do in the go environment and no JS so in node.js when you start to create a new project you would say mpm in it which is uh which will give you a package.json file and the equivalent of that I'll just zoom in a little bit and go is going to be go mod in it and then you would put a module name so this is going to be some kind of like unique identifier for your module and it is going to create a go.mod file in the current directory and again this is going to be that kind of like package Json file which contains information about the module its dependencies and the co version that you're using and this module name uh has like it could be anything but it has a convention and you will see that uh in a couple of minutes and then when you want to uh start your application in node.js you would basically run this kind of like a command which is in PM Run start and in go you would say go run and then the file name which is going to compile the program and executes it and then when you want to install a package you would say mpm install and then package name in node.js and in go you would say goget and then the package name so goget is not a package manager but it is used to download and install packages from remot repositories and it does not handle versioning and this command fetches the package and it's dependencies if there are any and then as we just talked about it before package.json the equivalent of that would be code. mode file which contains the information about the module its dependencies and then the co version so when you want to install all dependencies in a project you would say mpm install and in go that's going to be go tidy and then when you want to stringify Json so you would call this method and in go this is called uh some like marshalling so you would say json. Marshall and you're going to have uh so like the go data structure and when you just Marshall that it's going to stringify it to a Json string and the reverse operation is going to be json.parse which is going to be UNM marshalling so again you have a Json string and you're going to run this method with that and it's going to give you that go data structure in Json right now this code might look a little bit complicated but we'll get to that and then the ndman is something that just uh reloads uh your application whenever you change some source file right that's going to be in the njs and in go there is air which is a live reload tool just like node Manon but in go applications so it's going to watch uh for file changes and automatically rebuild and restart the application it is similar to nodon and there are other Alternatives like fresh but uh for my case air was the most convenient one to use it and to be able to configure it you need to have a file called air. toml and this is something that again we'll just get into that in the video and uh so to be able to store your environment variables you would install the TMV package in node and in go it is going to be this uh goget and then the module name so github.com jaho and then go. EMV and again this is going to allow us to store sensitive information like API Keys database uis and any kind of like secret and here is an example of that where we just uh you say go. em. load the EMV file and if there are any errors just console log it to the console right or in the terminal but if we just pass that now we could just get any environment that we have and we're going to just assign it to a variable now we would use expressjs in node uh to be able to have that web framework and in go it is going to be uh fiber which is a web framework for go and it is inspired by expressjs so it is fast lightweight and easy to use and you're going to see it is actually looking pretty similar to express and there are other uh Alternatives such as gin and Eco and if you wanted to you could take a look at them after completing this video then let's see a middle W uh so in Express JS we had middle rares right this is actually a concept that we have almost in any kind of programming language when you build an API or something s similar and in go here is how we would use it so we create an app just like in Express but we say fiber. new which is going to give us an instance then we would Mount the middleware to our function and that middleware is going to take the next as the first argument and once we have run the middleware logic it's going to call the next function so that's going to be the middleware and then we have RW handling and here is an example uh the equivalent of that Ino so you would Mount your route and your Handler or the controller function and that's going to take the context and you could just send a response and we'll be using that in the video as well but that's going to be my comparisons I think that's a pretty cool uh list which is about 200 uh lines of code that you could use it after completing this video as well and with that let's go ahead and initialize a go module so here we'll just say go mod in it and then the module name so here is my empty folder that I have just created and I'll open up a new terminal and I'll say go mod in it and then we could just put anything here but the convention is to put your GitHub repo that you will push this into so I'll say github.com and my username then I'll just say react go tutorial and this is going to be the repo that I will create and push this code into and if we just press enter that's going to give us go.mod file here we can see this is the Go version that we are using and this is the module name and to be able to use go I forgot to mention but you need to install go in your machine which is pretty simple you would just go ahead and Google it then just install it and just press couple of next buttons and should be fine and up and running so in go we need to so we have like app packages and modules and let's just see that in on a diagram so here is our note about packages and modules so a package is a collection of go source files that resite in the same directory so here let's see this is let's say a package right and we have the main.go so let's say that's going to be our main package then we have the handlers package package the API package so on and so forth and all of them coming together is going to form a module right so packages collectively form a module and when you initialize a uh go module so basically you are creating a module right because it's going to have multiple different packages and uh like it's going to form a module so the very first thing that you'd like to do is create a main.go file and this is going to be the main package so we'll just say package Main and this idea is kind of like different if you have never used it but once you just write a couple of different lines of code and use it more than so let's say you would use it in a couple of different projects that's going to just make a lot of sense so here this is going to be our main package and in the main package you have to have the main function so here co-pilot is getting a bit uh annoying so I'll just go ahead and disable completions so here I'll just have my main package and and I'll just uh let's say console log hello world for that we would use fmt let's import that and I'll say fmt print line just like this and I'll say hello world and to be able to run this file I'll just say go run and main.go now we should be able to see Hello World in our console and let's see the variables in go so I'll just shrink my terminal now there are couple ways of creating variables so with the VAR we have let's say my name and type is going to be string so I'll just say John do and there is another usage with const we'll say my second name that's going to be string and we'll just say Jane do so this is not going to be a go complete uh crash course but I just wanted to talk about variables for a second because there is another way of using that which is pretty common where you don't really declare the type but that's going to be inert so I'll just say my third name and if I just put this colum and equal sign I could just say uh let's say Bob do so here this type is going to be string by default because it has being infert and I'll be using this kind of so this kind of variable assignment a lot in this video and if we just say fmt do print line my name let's say duplicate this one twice I'll say my second name and my third name we should be able to see all of them in the console let's go ahead and run this file with gun main.go and there we go we have all of them in the console so that's going to be the variables and just keep in mind that this is going to infer the type um I think I could delete all of them and here we'll like to install the fiber so that we could create our API and just have our web framework right so I'll open up my terminal and I'll just say CLS to clear up my console or my terminal and I'll just say go um get so let's get the fiber so I'll say github.com go fiber SL fiber and then I think it's going to be V2 now that's going to get that and update our go. mod file so there we go we have all of our changes and even we got the go. suum file and it's going to be a again related to packages or modules and let's create our app so I'll say um just like this it's going to infert the type I'll say fiber. new and we'll take to say app. listen and now you you would put column and then let's say the port which I'll go with 4,000 and that should be capitalized and if we have any errors we could just wrap this with let's say log and import the package and fatal so with that we should be able to see any uh so if you hover over this it's going to say fatal fatal is equivalent to print followed by a call to OS exit one which means there were some errors but if we don't have any I think that's going to work fine let's go ahead and run our um server right I'll say uh go run main.go and we should be able to see the hello world and now it is listening on our let's see this port and here we are getting this kind of like security kind of thing I'll just say uh accept the so just let me use the go so now whenever I change anything in this file so let's say hello world s it is not going to restart my server to be able to see that change I need to kill it and then just restart it again so now I could see it just has the new update and like the thing in the console but I don't really want to have this I just want to have that kind of like not mom feeling where it's just going to restart that uh as soon as I change anything in this file and for that I'll just go ahead and kill my terminal clear that and install a package called air so I'll say go install um and then this github.com and just paste it and press enter and once you have done that it's going to install air where we uh where we need to create a file for the configuration so go into this uh like file explorer and just create air. toml and to be able to get this kind of like um formatting install this extension in vs code so it is this one that I'm using to be able to get this kind of like the formatting that you'll see in a second now this is a file that I have prepared with the help of chat GPT and taking a look at from the stack Overflow and I put some comments for your convenience so here we just say the root file is going to be this current directory of the project and the temp directory that you would like to uh store your files is going to be temp which is going to be created whenever we run the air command and here are some build configurations so we are just saying include any go file just watch that changes and exclude any in the client and in the temp and we don't have the client but we'll create that when we when we add our react application and here we have a couple of different commands that you could take a look so it is not really important and let's kill it I will go ahead and just say air and here we can see it has been created and now it listens for our server so now any anytime I just do some change it is going to actually restart it because it says main. go has changed so it's going to build and it's going to run that here we can see the updated result so we don't really need to kill it and then just restart it again now let's go ahead and add our first route so here I'll just say app.get in the root route where you would like to call our Handler function so I'll say funk which is going to take the context and you would like to call it as see this is the convention and that's going to be fiber. context but that's going to be a pointer into that so I'll explain the pointers in a couple of minutes most of you guys know uh how that works but in case uh so like some of you don't know I'll just try to explain it pretty quickly and we'll just say we we might want to return some errors so we're going to put that and we'll say return let's say c. status of 200 and we'll just say let's see this is not correct okay see. status 200 and the Chason data we would like to send let's say fiber. map and we'll just say message it's going to be let's say hello world and to be able to test it out let's go ahead and install this Postman extension feel free to get that I think it should be this one okay instead of using this desktop application we're going to use it directly in DVS code I'll just zoom out bit and I have a workspace called react go tutorial and I would like to add a new collection I'll just say todu and I'll just create uh let's say add a request that's going to be a get request and I'll just say uh maybe get todos for now let's call it like that and our endpoint is going to be HTTP Local Host and and our Port is 4,000 and we would like to just send a request to the root route and if I just send that now it's going to say hello world because this is what we are sending so now that we have this kind of like boiler plate setup where we have our application we are listening on this port and we are just having this kind of like hand Handler function I think we are ready to go and build our first the first part right so we're going to store Tod do in the memory that's going to be the first part and then in the second one we're going to actually connect to mongod so here we we're going to have couple of different to and for that we could use struct Ino and which is going to allow us to have custom kind of like data structure where we could give different fields with different data types so I'll say type which is going to be to-do and I'll say that's going to be a struct and open up this Cur Braes so each uh Todo will have an ID let's say the type is going to be int that should be lowercased and we'll say completed field it's going to have which is going to be bull or bullan and we'll say it's going to have a body and which is going to be type of string and in the Json body we'll like to just rename them uh I'll just say Json and open up this uh codes and I'll say ID and I'll do the same thing for this one back Tex Json and that's going to be let's say backx completed and this is going to be the value that you'll actually see in the response so Json body and that's how you would like to call it so I'll just save to get this formatting and now in the main function we'll like to have the to-dos array so I'll say to-dos and assign it to let's say just like this I'll say it's going to be to-do but an array of it right so just like that and the very first thing that we would like to do is actually create a to-do so I'll say app. uh post so that's going to be our post method and our endpoint is going to be API SL too here would like to have this function is going to take the C and it's going to be pointer to Def fiber. context and this function might uh return errors might return errors so just going to put that error and just have our function body so we're going to have a to-do right let's just say to-do is going to be equal to this to-do uh struct that we'll have now this is going to give us uh since we didn't pass any value into it it's going to actually create it with the false values or the default values and for INT it's going to be zero for Boolean that's going to be false and for string it's going to be an empty string so here just imagine now we this to-do is equal to let me just put it in the same line so the ID is zero um uh completed is going to be false and the body is going to be an empty string but this body or this object is going to be coming from the user right it's going to be coming from the request and for that we can check for it and assign it to um assign that into this to-do so I'll just say c. body parser and we're going to pass D to do so if you take a look at that body parser binds the request body to a struct so it's going to take the whatever user uh sends from the request and assign it into this to-do but now this should be a pointer so we need to just say uh get the memory address of that and this might return us uh a error so I'll say if error just assign it into that one and just put this where we'll just check for error so we'll say if error is not nil which is equivalent of n in JavaScript and we'll just say return the error so here this looks a little bit weird where we create the error in the same line and just a check for it we are assigning the value and check for it right um and then we'll say users can create the to-do but what if body is an empty string then youd like to return an error so I'll say if too. body is equal to an empty string then I'll just say return C do status of 400 and I'll say Json where I would like to say fiber. map and I'll say error field is going to be let's say to-do body is required okay but if this is not the case we can increment the ID by one because it was Zero where we have the false values right so I'll say to-do do ID is going to be the length of to-dos plus one and we'll say now to do uh we'll take the append uh like append the current to that we have just created so I'll say append call this method and we'll say enter the to-dos add the new to-do and since this is the memory address we'll like to get the value out of it right that was the pointer and eventually it will say return c. status of 2011 which means uh a Source has been created and we'll say Json of too so now let's save test it out and then I'll I'll explain this kind of like pointers and I will duplicate this uh request and I'll say create a to-do that's going to be post request I'll save that and our endpoint was SL API SL to where we would like to send the too body so let's go into the raw Json and if we don't pass anything that should say uh okay this is the this is giving us an error let's see what is the problem maybe opening up our console so I'll just I think save that one and send it again okay I'll just say body is going to be hello world okay it says now it's been created but if we don't pass anything it's going to say to-do body is required and that means our endpoint is actually working we sent a request to there and this function run where we check for the errors and eventually either return the response or the error and now let's take a look at this pointers so here let me just explain that here and then I'll just show that in a diagram so let's say I have a variable maybe I'll just zoom in a little bit so here let's say I have a variable called X which is type of int and let's say the value is five and then this is going to be stored in a memory address right so let's say it's going to be 0x 0 0 0 and maybe one so this is the memory address of X and the value of it is five and let's say I'll have a pointer now and that's going to be int and just to make sure that this is a pointer we need to put this asterisk before that int and I'll say this is the pointer that points to the memory address of X so that's basically it this is the memory address of X so the value of p is now actually the memory address of X okay so this is the value that P stores and the value X stores is five so if you just say now um fmt print line of P then you're going to actually get this value and if you say p but the like the address that it I mean the value that it stores it is going to give you the value of x which is going to be five so I hope you are able to see how that works P stores the memory address of X and when you ask it like that it's going to tell the compiler to give the value that has been stored on this address so that was kind of like uh so strange idea if you're seeing this for the first time de pointers so we have a memory and let's just see that on a diagram so we have just created a variable called let's say x the value was five and let's say this has been stored on this address okay so this is X the value of five and then we have have created a p which is pointer and it is going to point to the so it's going to point to the X so here we have the P for the value it is going to get the memory address of X let me just mark it like that and there you go now if you say hey P give me the value of this address that you are storing then you would just say asterisk oops so asterisk and P which is going to give give you the value that has been stored in this address which is going to be five and here this is the kind of like what I've explained and here we got the memory address of that Todo and we're getting the value out of it and this is how it works in go so kind of like strange but once you used to it it gets uh it just makes a lot of sense and so we have created the to do endpoint so I'll say create a Todo and let's try to update a to-do I will delete this line and below that I'll just say update a too so for updating we could use the put method but I think I'll go with patch so it's just preference feel free to use the one that You' like to use and I'll uh I'll give the endpoint of SL API slash toos slash the idea of to-do that we would like to update so that's going to take the Handler function context so let's say fiber. context and we could return an error and we'll just get the first ID from the prems so I'll say ID is equal to C that prems and our prems is called as ID now this is going to be type of string right so this is something important to keep in mind and we're going to first for loop our toos that we are storing so I'll say for I this is going to be the index and then the to-do itself where you would like to say range to-dos and this is how we would run a uh for Loop in go and go doesn't have while Loops so you you need to write them in for Loop if you need any and here we'll just go ahead and say uh if to-do do ID is equal to the ID that we have in the prems but now this is not this is going to give you an error because this is the type of int that you are storing right and this is the type of string and to be able to make that work we can convert this too ID to be a string and I'll just say fmt do Sprint um too. ID okay with that that should be fine and we'll just say too um I so it's going to find that in the completed field we're going to just make that to be true so if you want to negate it so you would say uh just get the current value so I'll say todos I complet it so it's going to either make it true so if it is true it's going to be false but if it is false it's going to be true but in this case I just want to always make it true when I send an request to this endpoint and once this is done I'll say return c. status uh let's go with with this one 200 and we could just return the updated to-do so I'll say to-dos and the index but if this is not really the case we're going to say to-do is not found so return c. status of 404 and let me just scroll a little bit and I'll say send maybe just Json fiber. map so to-do not found let's go ahead and test it out I'll create another one I'll duplicate this and that's going to be patch so API todos and let's say You' like to update um the first to that we have created and by the way let's create a couple of different uh so I'll just say learn react send it so it is not completed so let say learn JavaScript Learn Python and let's say learn go and here you can see ID is just incremented by one so we're going to go here and we don't really need to pass anybody so if you just save that it's going to update this method name and if I just say update the first Tod do it is going to make it to be completed so there you go it is learn react where we have the completed field to be true and by the way whenever you kill your server uh terminal it is going to actually delete every to-do that you have because it is storing that in memory so this is something to keep in mind uh when you're working with in memory kind of like approach so okay I think that's going to be it for the update a too uh Endo let's go ahead and create the delete one so I'll say delete a to do and that should be our uh very last and point so I'll just save that first and scroll a bit is going to be app. delete our endpoint SL API SL toos and then slash the ID so that we could know which too that we are deleting and also I think I forgot to update this one which is going to be to be able to get all toes so that's going to be SL API SL toos and let's go ahead and update that one so here we we had the root routee and I'll just make that to be slash API slash to which just going to just return to this that we had right if we save and if we just send a request to that let's just see send it again because it was restarting okay let's see what is the problem so it says missing Handler in route um I think we forgot to let's just comment is OD since we don't have the Handler function it just throws us an error so I'll just save that and in the get to-dos we should be able to get send this request and we cannot get anything let's just send it again okay there we go server just started and it says hello world but we don't really want to get that so if we hit SL API slash toos okay looks like it is not really working I'll just go ahead kill the terminal clear my console and I'll just say air and if you just test it out again so for some reason there were some kind of like caching problem so I just killed all of them right and then I open up like get to-dos and now if I just send a request there we can see we don't have any toos in the response so I don't know why did we got that kind of like caching but here you can see this this is the exact same code that we have just written so let's go ahead and try to add this delete to do uh Handler and again this is going to be pretty similar so we like to have this kind of like Handler function which is going to be the pointer to the fiber. context you might want to return an error out of this function and we're going to get the ID from the prems so I'll say C do prems which is going to be the ID in this case that we uh that's how we have called it then we're going to say for I the index and then the to-do in range of to-dos so we're going to find the to-do that we' like to delete so I'll say if to-do do ID is equal to ID and again we're going to get that error because this is the type of integer that's how we have created in the Str and we need to uh and this is type of string so we can't really compare a string to a number so we need to convert this to be a type of string as well just like we have done previously so I'll just say fmt dos Sprint and just wrap the to-do ID with that and if this is the case we'll just say todu and we're going to just reassign it so say aend into the todu up until this index that we are trying to delete but not including and we're going to say to just uh add these values so I + one and up until the end and we need to put this three dots which is going to just unpack those values so let's say if you didn't understand this code let me just show an example let's say we had five different to-dos okay and we have just try wanted to delete the third one this is going to say that just take the first two values right up until the index but not included so we want we wanted to delete this one it is going to take all of them but not this one included so now we're going to have one and two not the three and from I + one so starting from here up until the end so we're going to have four and five there you go we have deleted the third one and this is the new to-do uh list that we have so I hope that makes sense and this is something called varic operator and it is kind of like the spread operator in JavaScript where just unpack the values and we'll just say return um c. status and let me just actually copy that line and paste it because it is pretty similar with the status code and success is going to be true and if this is not really the case we couldn't find anything so we'll just say return 404 uh Json fiber. map to do not found let's go ahead and test that out so I'll just go ahead and maybe add a new request that's going to be the last one and I'll just make this type of delete save that and I'll say delete a to-do okay I'm going to save that and say this is going to be my endpoint SL API SL toos and then the idea of the to-do first if we try to get all to-dos we don't have anything in the memory so let's go ahead and create one so I'll just say learn go and and let's create two different one so I'll say learn react and let's say Learn Python okay so we have created three different toos if you want to get all of them here you can see we have three different items and I would like to just delete the learn react so I'm going to put the idea of two there we go it says success true and if we want to get all of them here we can see the ID of two has been deleted so with that I think that's going to be it for the first part of the course where we have just created four different end points to be able to get to those create a to do update one and just delete one and we are listening on a port so everything works fine and next we' like to actually write this same thing but with mongodb where we could have a database and just store those values so when we kill our terminal or when we kill our server we don't really lose them because that they are not going to be stored in the memory and before we get into that let's just see how we could use EMV in this go application so the very first thing that we need to do just maybe kill this terminal and just say CLS to be able to clear that and I'll say go get github.com SL I think it is called as Joo and then we'll say go. EnV and if we press enter that should get us that module and we'll like the load environment variables and for that let's go ahead and create this empv file and I'm not sure if you have realized but we have this temporary uh so kind of like the folder where the air is going to create whenever you run this Air Command so it's going to depending on your changes it's going to store its files in this temp uh directory which is going to be the executable of the compiled code so in the DMV let's say I have my port as let's say 5,000 and let's delete this spaces and instead of using this kind of like hardcoded value I could just use that Port so the very first thing that I wanted to do is just scroll to the very top and I'll just say error and just assign it like this I'll say go. env. load the EnV file and if error is not nil which means there is an error right we need to catch it and just say log. fatal and let's say error loading. EnV file but if this is not the case I'll just put this port variable and assign it to OS let's import that make sure you have in imported all of those modules and packages so we'll just say os. get EnV and we have called it as Port right and now we could use this value actually in here so I'm going to delete that and I'll say Plus Port so we have called it as 5,000 right let's see if that's going to work or not I'll just clear my terminal and I'll just say air and there we go now I can see the hello world and I can see my server just started on this port which is 5,000 right okay so that's going to be it for this very first section let's just initialize this as a git repo and commit our changes for those of you that want to see uh in the commit history the first version that we have created completely in the memory and next we're going to build it with mongodb so I'll go ahead and maybe just kill this terminal I'll just say clear that get in it initialized an empty G repository um let's create a g ignore file so I'll say do get ignore and the content that you could just grab that from the GitHub repo so this is something that I just wanted to paste instead of writing it from scratch okay so here we are just uh excluding the compiled binary files make specific files MV not modules and all these files that that are not really important to be uh tracked by git so if you save that here you can see this has been ignored this file should be ignored and yeah so let's go ahead and add all of them to the staging area and I think I'll just give the first commit as first section completed store in memory so I'll just commit those changes and I'll see you in the next section okay so in this section we're going to build this exact same API again but this time using mongodb so that we could see how we can interact with a database so the very first thing that we would like to do is just visit mongod db.com and create an account for free and then just log in and once you log in it should take you to this dashboard where you can create an organization and then create a project so I'll just say create a new project and then I'll just give a project the name so I'll just say go maybe react go tutorial and I'll just say next project owner is going to be me so I'll just say create the project and then I'll just create a deployment and I would like to use the free tier which is enough for our site project and cluster name could be just default and let's say create the deployment and here we can see the username and password so you'll like to copy this and don't lose it so I'll go ahead and just paste it for the in the EMV file for a second and we're going to be using that so I'll just say create the database user and once we have done that it's going to say choose a connection method so here there so here on the screen there is my AP address you can't really see it because I hide it while editing this video but you should be able to see your IP address and it is going to add that to enable local connectivity and let's say choose a connection method we would like to connect to let's say from our application so I'll just go ahead and copy this string and then just paste it to here and I'm going to give the or maybe I'm just going to assign it to this variable I'll say mongod dbor URI okay there we go and here there is my password so I don't really need to this one I can delete that and with the help of this environment variable we are able to connect to our mongodb database so this is our connection string and once you have done that let's say review setup steps and let's say this is done so now you don't really want to get some uh development errors so just go ahead and so just go into the network access and here you can see there's going to be your current IP address but let's just add the IP address where we could just access from anywhere so I'll just click to this one which is going to be this IP address and I'll say confirm and it is in depending state in a couple of seconds that should be active okay there we go now it is active and we can visit our database and currently we shouldn't really have any collections but in this case we have one and this is something mongodb gives you out of the box so that you could do some testing but in this case I'll just go ahead and delete that and currently I don't have any databases or any collections but we'll create in a second so we'll like to interact with our mongodb database right so we need to use the mongodb driver so I'll say go get and I'll just put that as lowercase so go get go. mongod db. org SL mango Das driver and I think slash so just type this and press enter that's going to get you the driver so that you could interact with your database so I think I'll just delete this file completely except from this type I'll just cut that and select everything and just delete it okay I'll say package Main and I'll say funk Main and I'll just say fmt print line where I could just see the hello world in the console and then I'll just paste my struct at the very top now this is going to be the exactly the same but we'll like to add one more field which is going to be Bon for the ID and we're going to say underscore ID and just leave it like that for now and we need to add this field because uh mongodb store its data in the format of ban which is also known as binary Json and this is the data format that mongod DP uses so this is something um I think required that you need to pass and then let's say bar collection where that's going to be a pointer to the doc collection and make sure you import this package and now we would like to actually load the environment uhv file and let's just say that so error we'll just say go. env. Lo EnV and if there is an error so if it is not nil then log. fatal let's import the log so here we'll just say error loading. EMV file and you could even put the error message and then we'll like to have that mongodb URI environment variable and we like to just grab it from ourv file right so I'll just say OS do let's import Theos and get EnV and let's see what we have called it it was mongod dbor U and I'm going to take this value and just assign it to a variable so I'll just leave it like that and I would like to be the type to be infirmed uh I mean inferred which is going to be type of string and then we would like to connect to mongod DP so we're going to say client client options this is going to be our variable so I'll say options and we need to import that as well from mango options. client and then we'll say apply URI where we'll take the pass our mongodb connection string and then we're going to get the client and error out of this call and again let's infert the type I'll say do connect and now this want you to if you just hover over that this want you to pass this context right so I'll just say context. background so this is not scope of this video and this is basically something that you'll like to create when you want to have maybe some cancellations some timeouts but in our case we don't really want uh want to have it we just say so it is like saying I am starting this task but I don't have any special requirements or deadlines attached to to it okay so that's going to be the uh information about context this is just something that we need to pass you could uh ignore it for now and we're going to get the client options and again we'll say if error is not nil so error is not nil and let me just scroll a bit if it is not equal to nil we're just going to say let's say log. fatal the error itself and then we can just check the connection with the Ping method so I'll say again in error I'll say client. ping and again this want you to pass a context so we say context. background and make sure you have imported this context package right then here I'll just put the second variable as nail which is read read prep uh and we don't really need to pass it and let's see why do we have this error okay if we just delete that that should be fine and we'll say if again error is not nil let's just do the same thing just like this but otherwise we'll just say fmt do print line connected to mongod DB Atlas so just like that and let's save this and just test it out I'll just clear my console and I'll say air so it just run that it says hello world and then it connected to mongodb Atlas with the help of this methods and this kind of this kind of code block that we have just written and now we would like to have a database and then a collection so for that for my database I'll just go before this question mark and I'll just call it as go langore DB and this is going to be the database that I would like to connect to so here I'll just go ahead and say collection client. database oops it should be database like this so it just autocompletes my code but I think if we delete this part it should be fine um just leave it like that client. database where will have the go langore DP in our collection I would like to just call it as toos so I'll just store all of my to-dos in this uh collection and I'll say app again just create a fiber dot new and then we're going to have four different endpoints so I'll say app.get right which is going to be SL API SL toos and instead of putting the function um immediately here we could just make our code a little bit more kind of concise or maybe clean let's say get to to and I'll just duplicate this I think three more times this one is going to be to be able to create a to-do so I'll just say app. poost and this is going to be let's say patch to be able to update one and this is going to be delete and here in the last two one we'll take to add an ID so that we could know which to-do we are deleting or updating so we have get to-dos and let's say create too and this Handler function is going to be update Del too and lastly delete too then again we could just get that kind of Port from the EMV file and this is something that we have done previously so I'll just copy it and paste it and now we could just check if Port is empty then we could put a default value so I think I'll just go with d5000 and because that's what we are using and eventually we're going to just say listen to that port and if there are any errors just wrap it with log. fatal and now let's go ahead and create all those functions or handlers so I'll say funk the first one is going to be get too which is going to take the context say fiber. context which can return us an error and just get the function and let's just duplicate that uh three more times the first one is going to be create too update too and then let's say delete too and let's comment all this out and just Implement them one by one first uh let's start with this one so here I'll just scroll down a bit and we're going to have VAR to-dos and that's going to be an array of to-do let's say and we're going to just fetch that and maybe assign it to that or just append to that to do right so that should be upper case to do because that's what we have called our struct so we're going to say collection find and we're going to say again we need to pass the context so I'll just say context. background and the second option is going to be bison. M so this might look a bit complicated but basically we are trying to pass our filters in our case that's going to be no filters because we like the fetch all to-dos in our collection so if you want to pass some filters then you would put something into this object but in our case we don't really want to and we would like to just fetch all documents in that collection and this is going to give us let's just assign it to the variables we're going to have the cursor and then the error so error is going to be whatever that is but the cursor is something when you execute a query in mongodb it returns a cursor and which is essentially a pointer to to the result set so you can use this cursor to iterate over the documents returned by the query so just think of it like we have all of our todos and let's just say if error is not nil right so we have an error then just return that but else we'll just say for just map through it so cursor. next and again we need to pass that context so I'll just say uh context do background and for each to-do we're going to create this variable let's say to-do and we'll just say if there is an error first we need to decode that right so I'm just going to assign it to that error and I'll say cursor. decode where we need to just put this Todo and if error is not nil then we're going to just return the error itself but if this is not the case then we're going to just append this to-do into that todos right I'll say pend into the to uh to this Todo that we have just get from the cursor and eventually once we have get all of them we're just going to say return c. Json just pass the todos okay so with that that should be completed for this uh function but now there is one optimization that we could use so we have just created some kind of connection right we are patching something and at the end of the day we'll like to just uh close that cursor when this function done right so I'll just say defer which is a keyword that we use in go to postpone the execution of a function call until the uh surrounding function completes in this case this is the surrounding function right once this completes it's going to run the right side so we'll just say cursor do close where we'll just say context do background okay so again defer is a keyword that you use to postpone the execution of a function until the surrounding one ends or that completes and that was that kind of like the optimization and we could do the same thing here when we create a connection uh to our database so here I think after this mongod do conect we could just say maybe after the error I'll just say defer um client. disconnect. database let's say disconnect and again just pass the context. background so when this main function done with executing right we'll like to disconnect from that uh database from the client so with that in mind let's save this and try to test it out in the postman we would like to get all of our toos and now our Local Host Port is going to be 5,000 because this is what we have put here right I'll just save that and if we take a look it is up and running let's just send a request so we got null because we don't really have anything in the database so next let's go ahead and add the create to do endpoint so I'll just uncomment this and create this function maybe shrink this one and just uncommon this one right so here we'll like to again create a to-do so I'll just say to-do and that's going to be equal to a new to-do so again this is going to be a pointer so just to keep that in mind because we will use c. body parser so I'll say C do body parser there I can see that and I'll just say pass it to do into it and again just remember that this is going to bind the request body to a struct in this case case this is going to be that struct we're going to take the request body and pass that into that struct and here we will just say if this is going to return us an error so we like to just assign that and we'll say if error is not is not nail right I'll just say then just show the maybe return the error itself and again we're going to just check if body is empty or not so user can't really create a to-do uh by putting nothing so I'll just paste it here we just say too. body if it is an empty string then just say too body cannot be empty and then we'll take the insert into the mongod DP right if we just pass all of those if checks so I'll just say collection do insert one which is going to take the context do background as the first argument and then the item that you like to insert which is going to be this to do and that's going to give us let's say give a bit spacing it's going to give the insert result as well as the error so here I'll just move on to the next line and I'll say if there is an error and just return it but otherwise let's just move on with the function where we would like to just update the to-do ID right because when we created this to-do that's going to have a faly value and as I have explained previously the ID is type of int so it's going to be zero right ID is going to be zero completed is type of bullan by default that's going to be def false and body is type of string that's going to be an empty string but now that we have created that and insert it now we have the inserted result so we would like to just update the to-do ID with the inserted ID so I know I know that sounds a bit complicated but here we'll just see in a second insert result. inserted ID and which is type of primitive let's just do this type uh assertion right so primitive and just uh import it from this mongod driver doob ID and I think we forgot to use this one when we initialize this to do struct so here we have this ID it is not going to type of int because mongodb has its own ID type and we'll just say that's going to be primitive. object ID okay we just remember that and if we take a look at here we need to add the error and otherwise everything should be fine so we have just updated that and let's say return c. status of 2011 a resource has been created and Jason just return that to do now there is an issue here where when we just create a to-do right so that should have an ID and by default that's going to be zero so we'll just say if it is zero then just omit that value here I'll just say omit empty and I'm I'm going to pass that to here as well and now this basically says if the value is false then just don't add it to the response okay or let's just delete that and see what's going to happen happen if we don't really add those fields so we have our create Todo function is up and running right let's go ahead and test it out where all I have to do is just update the port number because we have updated it and for the body let's say Learn Python and let's send your request now it says this has been created let's double check if we just refresh our database we should be able to see this goink DB and then the todu collection but here we can see the object ID is value of zero because that was the default value that it's going to give right this is the falsy value and we're going to say if it is empty then just omit that value and don't put it and that's what we're going to do basically we'll say omit empty and now I hope you're able to see what this does if it is empty then just omit that let's go ahead and first delete this document now we don't have anything in our database and let's create that again and the only change is going to be this ID it is not going to be zero but it's going to be created by mongodb right it's going to be a default value let's say learn go and let's say learn react and if we now try to get to this instead of getting null we should have this array of objects which we have three different todos and all of them uh are not completed is because as the default value but we're going to fix that next so let's go ahead and update it Todo first shrink this function get todos create uh create todos and then add this endpoint where we have the update Todo function so here in this function again we'll like to take the ID from the c. prems which is going to be the ID and that's going to be type of string and we need to convert it to be type of object ID so I will say that primitive doob ID from hex and we're going to pass the string ID which is going to give us let's say the error as well as the object ID so I'll just keep this as object ID and then the error okay so we need to do this conversion otherwise we can't really compare it so from this string we just made it a object ID that is type of primitive which is what mongod be uses right so we'll say if error is not nil which means there is an error so here I'll just put it like that and I think I'll just say invalid to-do ID so I'll just paste this line where we just sent 400 error status and then here we just want to update a to do so I'll just say collection. update one where we would like to first pass the context. background that was was the default uh argument then we'll like to add our filter right so which one that we'll like to update and then which field that we're going to update so these are the two things that we need to create and if you remember to be able to create a filter we would use b.m and if you just leave it empty that's going to uh just say uh all uh documents right but we want to just get the one that has the idea of this object ID that we are getting from the prems and the update field we would like to just update the completed field to be true so I'll say ban. m and here we just say set to be able to update and we'll say again ban. M and the completed field is going to be equal to true so this looks like kind of like mongus if you have ever used it and if this looks a little bit complicated it is just the syntax that you need to get used to it and this is going to return us the let's say uh like underscore because we're not going to use that and it's going to return us an error and just assign it to that values and we'll say if error is not nil again just return that so I'll just say if error is not nil return it but otherwise we're going to just uh return a success status with 200 just like that so I'm just going to save that and just test it out also let's close these maybe save this one um so it was this and let's rename this because that's going to be update a Todo if we got all todos we know that the first one is python which is not completed I'll copy the ID of it and I would like to update it and here I need to update the port so say update this one to be completed if I just send that here you can see it says success and let's get all of our Tod this should be true now there we go if we just check it in our database it should be working fine for the first one which is completed and the very last thing that we need to add is to be able to delete a to do right that's going to be our very last endpoint so let's click close all of them and uncommon this function sure shrink this one oops so shrink this one actually and uncommon this line um so here again we're going to get the ID just like we have done previously from the prems so c. prems oops what is going on okay I'll just do contrl Z I think it imported something and I just did control Z okay so here c. prems you'll take to get the ID and then again we'll like to convert that object ID from hex so we'll say object ID and then the error field it should be like this so primitive doob ID from hex and then we're going to pass the ID so from the string we got the object ID of primitive type and we'll say if error is not nil then just say return c. status of 400 and then maybe Json and let's say fiber. map we could say error where the ID is invalid so invalid too ID but if this is not really the case then we' like to just delete one from our collection so we'll say collection delete one one and again context. background just like this and then we'll take the pass our filter so let's go ahead and create that so I'll say filter is going to be equal to b.m and our ID is equal to this object ID oops if I can type correctly right and again this is going to return us to different values which is going to be something that we don't use and the then the error itself and let's say if there is an error then we' like to just maybe return it so if error is not nil can just return that but else we'll just say success is going to be true in this case I'll just copy that line and paste it with 200 status code okay let's go ahead and test that one as well so that's going to be our Port 5,000 and then the ID that we would like to add let's say since I am done with this one I'll just go ahead and maybe delete it right which is Learn Python I'm going to send that it says success true if we just try to refresh and there we go now we can really see that Learn Python to do and with that I think we have completed this part as well where we have just added all four Crow op operations right so we can get all of our to-dos where we just say collection. find and pass an empty filter so that we could get all of them under this cursor and we just Loop through it and append it to the todu uh this array or the slice that we have created then we just return it as a response we can create one with the error handling and we can update one with our filters and then the update filter that we'd like to update and then we can delete one so here we can see it is actually pretty easy to build an API with it if you know the basics and here this is something really important to keep in mind that you would like to omit the empty values for IDs otherwise it's going to be that object ID of value that's 0 00 0 that we have seen uh just couple of minutes ago and here is how we can uh like connect to our database and and we're using this defer keyword to be able to disconnect once this surrounding function completes so I think that's going to bit for this section and next we'll like to build the front end and connect to this application from that react app so instead of using Postman we're going to use that react application so I'll just go ahead and just add all my changes to the staging area and just put a commit and we have some built errors let's see so for some reason this is not being ignored let's go ahead into the get ignore and maybe I'll just say logs and I'll just say do log and with that now that should be if we just put it like that that should be ignored we just say uh we just said ignore that any file that ends with log okay so these are the changes that we have done this is the main f file you could take a look in the commit history I'll just add my changes so this is my commit message second section completed where we just store our data in mongodb I'll just commit the changes and I'll see you in the next section okay so in this section let's go ahead and create our react application for this I'll just open up my terminal and I'll just say make directory called client there we go it has been created and let's see the into that and now I would like to create a react application which I'll say mpm create feed at latest and I'll just say that uh dot so that it's going to put that in the current directory which is going to be client if you press enter that is going to ask us two different questions where we would like to go with react and typescript so I'll just select react with typescript now it says run mpm install because you got bunch of different uh like in the packages and you have bunch of different dependencies you'll like to install that so that you could get your not modules folder so that's going to go ahead and grab all of them now while it completes we going to be using chakra UI so let's go ahead and say chakra UI um and take a look at the documentation so this is a component Library which is accessible for react and we like to use use it um just to sped up the process and this is how we would use it let's first copy this command where we like to paste it into the client directory right I'll just paste that and that's going to give us the dependencies that we need and let's go with the framework guide of beat so we have got this script and it tells us to wrap our application with the chakra provider I'll just go ahead copy it and in my main.js Tex right I will just wrap it like this and let's get the chakra provider so it doesn't give me for some reason which is going to be this one and by the way while we're here let's go ahead and delete the assets delete the app. CSS and in the app. CSX let's just say uh P tag or maybe a button that says hello and this button is going to be coming from Chakra so there we can see let's delete this ifcs app CSS v logo and everything okay with that let's go ahead and also install a package called uh react Das icons we're going to be using them for the icons and with that I think we should be able to uh find with chakra UI let's say mpm runev to be able to start our development server which is going to be at this port I'll just control click to it it's going to open this uh Local Host 5073 and there we go now we have this button that says hello in your case that might be a light mode here it is dark mode for me but we're going to implement that so that we could switch from dark to light and light to dark and also this is the demo application that we're going to build so here we we're going to have this kind of nav bar where we could go from light mode to dark mode and here let's just start with the nav bar so the very first thing that I'll be doing is to go into the app. uh TSX and I'm just going to wrap everything with a stack which is coming from uh chakra UI and I'll say height is going to be 100 VH which is the entire screen so we're going to have a nav bar we're going to create this component and we're going to wrap rest of our application in a container where we'll have a to-do form and then a to-do list so let's take a look at the end result we have a nav bar and the rest of our application is in a container which just centers that here right so in the middle of the screen we have a to-do form and then a to-do list and each of them are going to be a to-do item right so this is a to-do item with check mark and delete uh button and when you say stack that's going to just put every child on vertical Direction so we have Navar at the top and below that to-do form and then just the to-do list so let's start with the Navar and for this we're going to be using these images and for that you need to visit the GitHub preo and under the public folder you're going to see uh couple of different files so I just grab them and paste it into this folder so I just copied all of them and I will just paste it into this file where we just have this explore. PNG go PNG this goang for the Fab icon and we have the react. PNG and we'll like to use that in the Navar so first let's comment this out and visit the Navar component which we don't have so let's create the components folder components and you'll like to have the navb bar. TSX so here our focus is not really the UI design so I'll just go ahead and copy and paste this code which is pretty basic and I'll just walk you through that and you can find this code and you can find this code in this kab prepo in the navb bar. TSX so we are never going to change this file later so you could just copy that and paste it so here we have a container with maximum width of 900 pixels and we have have a left side right which is going to be let's see it's going to be this left hand side with three icons with a plus and equal sign and on the right hand side we're going to have daily tasks with this kind of like toggle switch where we can go into light and dark mode and here we just say background of this box is going to depending on the uh color mode if we are in the light mode this is going to be that color and if we are in the dark mode we're going to be using this color and we are getting this Hook from Chakra UI where we have the color mode as well as toggle color mode function when we clict to that we're going to change the uh color mode as well as the icon so let's just save that import it and delete this and let's use it so this is our application there we can see it is here we can switch that mode but for some reason it is not being centered and let's see why this is the case first I'll go into the dark mode and it is because of this index. CSS we have this additional styles that came with v so if we delete everything in this file and if we just refresh there you can see it just works fine just like in the demo application so here you can see it is almost exactly the same where we just make this icon a bit larger and the very next thing that we'll click the add is going to be this um this to-do form where we just have an input as well as an icon so if you want to learn more about this dark and light mode you could always take a look at the documentation where you would go into the color mode and they have just example API so let's say dark mode and like if you visit use color mode they're going to just show you how you can make this toggle uh light and dark and this is the exact same thing that I'm using because I just take that from the documentation so there isn't anything complex in this file and I'm not going to explain that it is just CSS Styles so you would just grab that and paste it into this file from the GitHub repo and the next thing that we like to add is going to be this too form I'll just uncomment this and create this to-do form component so here I'll just say rafc and now we could really type this uh component from scratch and again there is not anything complex so I don't really want to waste uh time on like the UI I'll just go ahead and paste it and if you want to get this code I'll just put that at the very bottom of the file I'll just say starter code because we will uh change this code in the incoming minutes and I want you to have this starter code while you're uh following along okay so you would get this kind of code and paste it and just follow along with the tutorial so here we have a state where we keep track of the to-do and we are keeping track of that with this on change and this input is going to be focused by default when you refresh the page and when you uh click to a button it's going to make it uh scale so it's going to shrink that and if we are loading we're going to show a spinner of size EXO mode and everything is coming from Chakra UI and we have react icons if you want to take a look at that as well and when you submit this form we're going to just call this function which takes the event and this is the type of it that is coming from typescript which is a form event and we'll just prevent the default so that it doesn't refresh the page and it's going to say to do add it later we're going to add this functionality so that we could actually uh interact with our mongodb database let's save that and we have an error or it's just a warning it says you not using that but we'll use that later okay let's save and just see that in action here we go we have this input and the button if you refresh the page this is going to focus Itself by default because we have this lineup code and when we just add anything into here it's going to say too add it with this alert so that's going to be to-do form component and if you really want to see the um like the UI design just pause the video take a look at it from the started code basically we have a form and we have a flex on the left hand side we have the input and on the right we have the button if it is pending let's just make this to be true we're going to have this loading State into it but else if it is false we're going to see this plus icon and next we would like to build the too list component so that we could just see this data I'll go ahead and create that one to do list. TSX and in to-do list we're going to have to-do item. TSX so here I'll just again get the starter code pasted twice so that you could use it as well and again this is pretty simple file I'll just paste that and I'll paste it again comment this out um just like here and I'll just say starter code so you would copy and paste that part and basically we have fake data right three different toos buy groceries walk the dog do laundry and cook dinner two of them are completed and two of them are not so I'll just shrink this to-dos and we have a loading State and we are importing the to-do item for each to-do right so I'll just go ahead and add this to-do item as well and this is going to be the very last thing that we will copy and paste so about 40 lines of code and I will paste it again starter code for those of you guys that want to follow along right okay so these are just Styles that's why I don't really want to waste too much time on it and okay if we save this file and this one this is taking a to-do as a prop and we're just giving that type withd typescript and for each to-do we'll just check if it completed then it's going to take this green 200 color but else that's going to be yellow 100 and we'll just check so we're going to give this line through if it is completed right so just like that if it is not it's going to have this normal text and if it is completed it's going to have this done badge and if it is not it's going to show this in progress right so this is not completed and this is completed then on the very right hand side we have check mark and then the delete or the trash icon so that's going to be it let's save and see that in action in our application first we need we need to go into this component and import it just like this it's going it's going to refresh and there we go so here we have a loading spinner is because we have this loading state is true and we just check if it is loading just show a spinner of size x large and let's say like default that's going to be false and there we go so this is the today's task where we have just couple of them and all of them are fake data and also let's go ahead and update this uh title to have this kind of gradient and for that we could check the documentation let's say gradient and here you can see they are using it on the text and I'll just give you this uh BG gradient linear tool left right you just put the right uh value and then the left one so if we just put something like maybe blue it's going to go okay so it goes to left so that's going to be the right value and this is going to be the left value which is this pink color starting from right with blue it's going to go to the left with this pink color and let me just give you the styles to be able to get this kind of linear gradient so here let's just go ahead into the to-do list where we have this text I'll just give these Styles uh starting from this color to this one and BG clip of text so that we can get this end result now everything works fine it is time to actually add this functionality and grab these data from the database and for that we'll be using 10 stack also known as react query so if you visit 10stack query here you can see the entire documentation and basically we'll like to use this as our data fetching solution and here you can see the motivation behind it and like it just gives you a lot of different things out of the box that you could use things like caching duping updating out of uh out ofd data in the background and lots of other things and I think it's such a great library to use and at the end of the day you'll like to use it in your uh so say production ready applications because that's going to give you lots of different functionalities that you don't you want to reinvent so the very first thing that we'll like to do is just install it so let's take a look at from the documentation if we go into the installation we should be able to see this Command right I will copy it and paste it in my terminal and just make sure it is under the client so I'll just paste that and install it and while it installs in the background let's go ahead into the quick start we could take a look at it how they're going to set it up or you could just trust me and uh see my guide so this is something again I took from documentation where we would like to create a query client and import it from our package and we' like to wrap our application with it so that we could use this query client in our application and you'll see what that uh what that is going to provide right so I'll just say query client provider and then just wrap my entire app application with it so let's import that one as well okay with that now we should be able to send uh request to our database or our back end right so we're going to go into the let's start with I think to-do list where we can just fetch all the to-dos that we have in the database and before we start doing that let's just create a type so export type let's say to-do and we'll just say each to is going to have this underscore ID field type of number body of string and then completed is going to be Boolean and in the to-do item when we say we're getting this to-do let's say the type is going to be this to-do that we are exporting from this file okay and I think we could delete this to-dos now and instead we're just going to fetch that okay so instead of this fake data let's try to fetch it so when you want to Fed some data uh in react query you would use use Query hook okay which is going to take the first argument as U this object and we're going to pass the query key and you'll see what that is going to do in a second but basically this is like an identifier for this query and when you want to refetch data for this one we're just going to say uh batch the query that has this query key of to-do and that's going to do it so again you'll just see that in action in a couple of minutes let's say we're going to have the query function where we'll have try and catch in the try we'll say cost R await fetch where our endpoint was let's say HTTP uh Local Host 5000 SL API slash to and we're going to get a response I mean a data back and we could just say if response is not okay then just throw this data. message that's not going to be data. message but it's going to be error because this is what we are returning from the back end right and in the catch we could maybe just um console log the error and then here I'll just say return the data and if you don't have anything then just return an empty array um here we need to so this is going to give us a value let's say con data which is the todos I'll just rename it to be todos so to just to make our code a little bit more readable and instead of this fake use State I'll just say is loading is going to be dynamic and here now it just want us to put some value right so this is a generic here we'll just say this is going to return us a to-do an array of todos so just like that let's delete this one and here so for some reason it says property data does not exist on type string so let's see why this is the case so we say use Query we just get that not from Checker UI but that should be coming from the 10 stack query so just like that it should fix it where we just fetch our toos from the back end and if it is not okay we'll just uh throw that console log it and otherwise we'll just say uh return the data but if we just save it like that we're going to get a course error right let's just see in the console um let me just zoom in a little bit okay refresh oh okay so we don't even have our server is up and running so I'll just kill this client and open up a new one and I'll just say air and just make sure you're are not in the client directory but in the route so there you go now it says it is watching those changes but I don't think if it is correct because we set that um exclude the client folder so whenever you change something here it is not going to restart the server but I just don't know why it says watching and here we have connect to mongod Atlas let's send a request we got the course error where it just says you cannot send a request from this uh URL to Local Host 5000 and to be able to fix it let's go ahead and just add the course to our go server so in main.go we'll like to add course after we maybe before these requests so here I'll just say uh app. use and we'll just say course and make sure you import it from fiber middleware and you'll just say new we you'll like to say course. config and it's going to take this kind of like an object where we'll just say allow origins of let's say uh HTTP local host of 5173 which is going to be our front end application and we'll just say allow headers to be origin content type and make sure you put a dash and then the accept so if you save that now it should hopefully restart our server and we should be able to fetch data let's just send again so I think it just tries to restart let's just see okay it is up and running and if we just send that there we go now we have learn go and learn react which is in our database and they are not completed that's why we just see that as this kind of uh in progress and here we just say uh you need to add a key let's kill this one and in the too list we're going to add this underscore ID so here we already have it why do we get that so under the to-do list H it says they should have a unique key prop and it is coming from line 50 uh six so that should normally work but for now let's just say idx and we just put the index just like that and if we just refresh we don't have that error and we just fetch our data so the very next thing that I would like to implement is when I click to that I just want to mark it as completed let's go into the um to-do item right when I click to this uh check Circle so I'll just say on click let's just say update to do function and before we write that let me just quickly explain what we have done here um basically whenever we uh render this to the list we are calling this use Query which is going to send a fetch request to our endpoint and it's going to give us the data back which we call it as todos and we are mapping it uh with each to-do item and we pass this to-do into that component and we are just using it in here right and now we would like to just update a to-do and for that we'll be using mutation hook so here I'll just go ahead and say use mutation which is coming from 10 stack and here this is going to return us a mutate function right so say mutate and I'll just rename it to be update too and it's going to give us is pending State and I'll just call it as is updating just to make my code a bit more readable and here this is going to take again an object where we could give a mutation key so mutation key that's going to be let's say update too and the most important thing is to have this mutation function is going to be async and we'll say if Todo is completed then we'll just say return out of this function with this alert well where we'll just say uh let's say not task but let's say to-do is already completed and we're going to have the try catch so try catch and in the try we're going to just send a request to our endpoint so instead of always typing this Local Host uh 5,000 what I'll be doing is to create a base URL and for that let's go into the app. TSX and I'll say uh export con basore URL which is going to be on this port slash API I okay so instead of using always this value I'll just use this constant and let's save it like that and I'll just put it like this right this is my base URL which ends with/ API and I'll just say slash todos and then the to-do ID this is the to-do that I would like to Mark as completed then I'll say my method is going to be patch and headers is going to be content type of application Json and I think we don't even need to pass it because it is going to uh update it right it's going to make that completed field to be true and I'll say con data r. adjon and if response is not okay just maybe throw an error and return the data otherwise here we could just say console log the error itself and let's save so while we're updating we could show some kind of like loading State just like in the demo application so if I clicked that here you can see I have that loading spinner for a second and let's go ahead and add it um here I will cut that I'll say if it is not pending or I'm sorry if it is not updating this is how we have called it then we'll would like to show this but else if it is updating then I'll just say give me this spinner from Chakra UI and let's say size is going to be small okay so we have some kind of like warning from typescript let's just say just call it like that okay instead of uh ref giving a reference we'll just say the Callback function is going to be this update to do when you click to this box let's see this in action here I'll just say learn goal is completed so it says invalid to-do ID and let's see why this is the case so to do underscore ID is not working for some reason let's say console. log D too and just see that in console okay so it has the ID field and I think we forgot to update it in the like main.go I'll just say main.go here this should be called ascore ID and this is something I forgot so I just realized sorry about that save it it's going to restart our server and let's just wait for a second so I'll just go ahead and refresh it okay let's just refresh it again until our server is up and running there we go now we have the underscore ID field and if I click to that there we go it has been updated but we need to refresh it to be able to see it here you can see it just says now this has been completed and so let's implement this when we click to that it should immediately refat the new state so we don't really need to refresh the page to be able to see it and this is where that query key is going to come into play so we will say once you have completed this successfully I'll say on success then you will like to run this function where you would like to invalidate some queries so I know this looks a bit weird but just bear with me we'll say query client and get that from this hook okay so we'll like to just refetch some queries I'll say query client. invalidate queries and the one that will take the update or invalidate first just pass an empty object and we'll say query key is going to be this array toos okay so we had this query key in this to-do list when we try to fetch all of our toos right this is our query key and when we say once you update it just try to refetch this data okay so let's try to see that I'll just refresh and if I collected this it's going to update and there you go because it refet it immediately once this is done uh successfully and and the other thing we like to implement is to create a to-do let's for that go into the to-do form and before that instead of passing this Index right I'll just delete that and I'll put to-do doore ID and now it should work because this is something that we have fixed in main.go file I'll go into the to-do form and so we are storing this when we type into the input and when we submit this form we are calling this function which should actually create a to-do with the help of use mutation so I'll just delete this function and I will actually get that from the use mutation right and make sure you import that from 10 stack query and I'll say const this is going to give me a mutate function which I would like to call it as create too so this is how you would rename it and then is pending state where I would like to call it as Maybe is creating or we could just leave it is pending in this case uh it is just preference but I would always like to go with some kind of a custom name so that I could just know what is going on is creating just like that and here we'll like to pass maybe a mutation key just in case we use it and then a mutation function which is going to take the event right because this is a submit Handler and we'll just say e. prevent default so that it doesn't uh refresh the page and then we are going to have the try catch and I'm not sure why this is not happy with us so maybe we are not returning something let's see okay let's just try to see how this all end up in the try we're going to have con res await again fetch the base URL let's import it and so/ API SL toos we would like to just pass the method as well as the body of the to-do I'll just say method is going to be post headers is going to be content type application Jon and then stringify the body which is this new to-do string and we're going to get data out of it and then we'll just say if response is not okay to say something went wrong or throw the error and we'll like to say set new to-do to be an empty string is because here let's take a look at the demo I'll just say something here once I press this button it's going to create it and now it is going to reset this field so that's why we're using it and eventually we'll just say return data in the catch we could just say Throw new error and here we're going to have after this let's say um on success so I'll just put a comma and on success once we have Del I mean once we have created a to successfully we would like to refat all to do just like we have done previously and for that we need to get the query key and I think we need to say this e will be so react uh. form event and now this should be happy with us and let's say error is going to be type of any um okay so let's go ahead and say const I'll just give a little bit spacing query client get that and we're going to just refetch it so I'll say query client invalidate queries where you like to just refet toos and if there is an error so on error we'll just say uh alert maybe error D message and here this is coming from es lent so I'll just say quick fix okay so we'll just disabling that it's really annoying but okay for now let's just keep it like that and when we in the loading State let's say is creating then show this spinner but else show that plus icon okay hopefully this should be our function Let's test it out I'll just say Learn Python and send that there we go now we have created that one and as soon as that is been created we just invalidate our to-do queries uh so that it could refresh that and here you can just double check it if you go here I'll just clear everything and I'll just say learn C++ and once I send it it's going to first create that one this is the post request and then it is going to fetch it right so here you can see it is going to send a fetch request to API todos which is going to be get method and here this is the post where we can uh create the to-do now we can mark it as completed and I think we didn't implement the delete function and we're going to add that next but if you were to just take a look at the code pretty simple right nothing complex going on we just preventing the default sending a request with our to-do body and we're just doing some kind of error handling and then just return the data on success and on error cases and let's go ahead and implement the delete to-do that's going to be looking pretty similar to this function we could probably make this a bit more uh reusable but I'll just go with the simple uh simpler approach where I'll just uh type it again from scratch just to make it kind of like a beginner friendly and feel free to to optimize this code so again we're going to have delete to do whenever we collect to this uh box okay I'll just get that past it this is going to be calling the delete Todo function and we'll say if it is not deleting so here if it is not deleting State then show the delete icon but else we like to just show this spinner just like this and let's go ahead and Implement our function so here I think I'll just let the copilot to the magic where we're going to have a mutation key a mutation function just going to be async we are sending a f request our base URL and the to do that we' like to delete this is our method we are doing some error handling and returning the data and in the catch case we're just console logging it and let's save and let's just try to see in action but before that I think we we need to add this on success case as well to be able to invalidate queries because if we don't add it let's try to delete this one it has been deleted but I can only see that if I refresh and to be able to fix it we're going to go ahead and add the on success and let's just try to delete this one there you go they have all been deleted and now we just see all tasks completed and it's because in the to-do list we just say that if it is not loading and if the length of toos is equal to zero then just show this text with the image so I think we have implemented almost everything to this application right we can create a to-do let's just say watch a go tutorial and create that one and let's say watch a react tutorial and add that one let's say do laundry and let's say buy groceries so we have added all of them and we can mark them as done we could delete them and just uh just fetch all of them right and here we have the light and dark mode and there you go now light mode looks pretty ugly you can't really uh read this and it is not really uh accessible so let's go ahead and fix it and for that I think I'll just go into the source I'll create a folder called chakra where I could put my theme into it so I'll say theme. TS so here this is a file that you could learn more about in the documentation so that's why I'll just go ahead and paste this code which is about uh like 20 lines of code here we have the initial color mode is being dark and the it's going to use the system color mode and here we just say the background color on the light mode is going to be this one and in the dark mode just keep the default one so to be able to use this we're going to go into the main. TSX into the chakra provider we'll just say theme is going to be this theme that we'll just uh that we have just created and it is not going to be coming from this one but let's just see it is going to be coming from this theme. TS file that we have just added let's save and see this in action and now there we go we have this kind of like a little bit more soft uh background and if you don't like the way this looks just feel free to update it but with that I think that's going to be it for the client now we have this kind of like hardcoded variable right and it is actually fine but when we go into the production and development this is like this should be dynamic right uh it's because when we deploy this application we're going to have the both back end and client in the same route so let's say currently we have our back end in this uh URL right and we're going to have the client under the same URL as well because this is how we will deploy that and once we have once we have add this we are not going to need any course handling as well because both the back end and the client will be in the same uh URL right right in the same domain that's why I'll just go ahead and update this Al bit so I'll say import. met. EMV do mode if it is equal to development then this is going to be our URL so let me just zoom out a bit so that you could see the entire screen and if we are in the production then we'll just send whatever the domain of uh whatever the domain is slash API and I think this is going to be a bit more clear once we add this main. go file right so here first things first we don't actually want to handle let's see where is that course kind of thing so in production we don't really want to have this because as I said before our client and back end will be served under the same domain to be able to make that work we need to make this client folder to be static so after this port I'll go ahead and I'll say if OS let's say os. getet EnV environment if this is equal to production then we'll like to make the client folder to be our static assets so that we could run and show our react application so I'll say app. static when we hit this root route will'll just show let's say uh this client this folder which is going to have our built optimized version of react application and we'll just see that in a second okay so when you send a request to API to um in like all these endpoints you're going to actually call the Handler functions but any routes other than these is going to trigger this react application under the this folder in client and we don't have this environment variable so for now let's go ahead and added to be development okay so that we are in development and now we're going to deploy in a couple of minutes and it's going to be production so we're going to make that to be static and the other thing that we' like to update is that we can't really uh load the DMV file in production because we're not going to have that file in the production environment but instead we're going to have uh environment variables that we will put from the dash board so we'll say if again os. get EnV if it is equal to let's say EnV let's say if it is not equal to production then we would like to actually load the environment variables so I'll just put a comment so it is pretty self-explanatory but let's just have this comment where we'll like the load DMV file if we are not in the production now let's save this one and we're going to go ahead kill our maybe the server and then for the client let's kill this and we're going to say mpm run built and this is going to create a this folder which is going to be that optimized version of our react application and something that I want to change while this happening I'll just not ignore this this folder and I would like to have it in my GitHub repo so that when I push any change it could take it and uh like just deploy my react application so this is not really the best approach but it is going to work in our case and I I found this to be the easiest to work with Railway so there we go now we have the disc folder which is going to hold the optimized build of our react application now if we just kill the client we can just say air to be able to start our backend server so here it is up and running we are connected to mongodb atlas and let's visit localhost 5000 SL API SLT and there we go now we can see all of our toos that we have since we are not in the production we can't really see the react application that we have but now we are going to deploy that and you'll see it is going to work so let's go ahead and push this code to the GitHub so that we could deploy it so here I am in my gup account where I'll just create a repo I'll say react go tutorial and that was the module name that I have give uh at the end at the beginning of the video so tutorial just like that and let's say create the repo I'll just make it private and once I uh publish this video that's going to be public so you'll just see that to be public and if you don't really want to go with private then just select public so I'll go with this option I'll say create the repo and now I'd like to just push uh an existing repo from the command line so I'll just copy all these commands and first I want to add my changes right so here we can see I have everything and let's add them to the staging area and just make sure you are uh you are not ignoring the this folder and I think I just forgot to update one thing so in the index.html let's just say react I'm sorry let's just say go react and typescript where I'll just say for the Fab icon I'll just put this go.png so goang do not SVG but PNG and once we have done that we should CD into the client first and let's say mpm run buil whenever you change something in the client you need to run this to get the latest version of this this folder okay so let's just wait for it until it's been built again so there you go it has been added let's just add those to the staging area as well so these are our changes so stage all of them and I'll just put a commit message so this is my commit message third section completed and it is ready for deployment I'll just commit that and I'll just go into the root and let's just C copy this and paste it which is going to push this local repo to the GitHub repo that I have and if we just refresh there we go this is the application or the source code that we just have and to be able to deploy this we'll be using Railway so head over to the railway. apppp and if you don't have an account create one for free which is going to give you $5 that you could use as the trial plan so I've been using I think over the last one week and it just charg Me 3 cents which is pretty convenient let's go into the dashboard where would like to just start a new project so I'll just say new project deploy from my GitHub repo and this is the very last repo that I have just created and it is private so I'll just select that one and I'll say deploy now so here it's going to initialize it and try to deploy that and and while it's done I mean while it it tries to deploy we need to add a couple of different environment variables so the first one is going to be EnV and here we're in the production let's add that the other one is going to be mongod dbor URI right we need to get that connection string and then just paste it so that we could connect to our database so I'll copy that and paste it now you don't really want to put Port because Railway doesn't really want you to put that Port it is going to figure it out uh himself okay or itself let's just deploy that these are the changes that we have just made EnV is production and this is our connection string so it's going to redeploy the latest change that you have done let's just wait and hopefully it should deploy without any errors and and if we have we'll just try to figure that out so it just looks like the latest one is active now we could go into the I think that should be settings and for the deploy um maybe in the networking so okay we'll just say generate a domain for us and if we just uh wait a bit it's going to give us this URL let's click to it okay there there is nothing here yet let's just wait a bit and then hopefully it should be up and running so here I'm just keep refreshing and it just has not found but it should be up in a couple of minutes and if you go into the deployments like you could see the latest one has been removed and this is the latest one that we have and you could just see the deploy logs where it just says hello world connected to mongodb appas and this is the port that Railway just figured it out because we didn't pass into the variables and I think if you put that it's going to not be really happy so let's just refresh a couple of times and there we go so we have the loading state it connected to our database let's just um why don't we have anything so for some reason it failed to fetch let's just refresh um okay so it says Local Host 5000 API to which is not really the correct URL because we are not on Local Host anymore and there must be some bug uh in this app. TSX so here we just say if the mode is development then this is going to be our base URL but else this is going to be um I think at some point we should be using this Local Host value maybe in our to-do list okay there you go I forgot to update this part right I'll just delete this where I'll just say base URL and plus the todos okay slash toos just like that but first we need to see the enti the client and just say mpm run build and before that I just also realized in the index HTML this should be go length and here I just have a typo so that's why it cannot really oops it is not this one it cannot really get this Fab icon and it just throws an error that says 404 this image is not found so let's just update that and let's say let's say mpm run build just going to give us the new this folder right so it's just going to go ahead and update that and once that is done we could commit our changes and here these are the changes that we have done here we have kind of like es L warning it is not really important so just ignore that and add all of them to the staging area and I'll just say base URL bug fixed commit that and sync that up so once you uh commit your changes right and push that Railway will immediately see that and it's going to rebuild it there you go it says building and it has just been 8 and 10 seconds so just wait for this to complete and once it is done I'll just be right back okay so there we go it has just been uploaded let's go ahead and see and there we go we got the data it is up and running we should be able to get this FB icon as well I'll just keep refreshing and for some reason it is in the cache but it should update in a couple of minutes yeah it should definitely update it because we have update that file let me just double check if we go into the index.html oh okay I again still did the wrong one so that should be go length just like that and you could put another commit but I think I'll just leave it like that so there is a typo that's why it doesn't work but if you go here you could Mark something as a done is going to update you could delete it you could delete everything basically or just say add a new to-do just like that we could make it done and delete that one as well and as far as I know this should be responsive as well so it's going to work on your phone completely fine up until like here which is one of the smallest phones you could ever get and with that that's going to be it for this video if you want to see more tutorials like this where we buil full stack web apps with go and and react let me know in the comments and don't forget to subscribe thanks for watching and I'll see you in the next onelearn the basics of go by building a full stack web app with react and go the project also features typescript mongodb and chakra UI and you'll use tanat Query to implement data fetching caching and updates Barack from as a programmer develop this course when you start learning fullsack web development you probably go with node.js in react because it is really convenient to build full stack apps by just knowing JavaScript but after a while it can feel a bit comptitive so You' like to try out something new and probably that's why you collected this video where we will build a full stack web app with react and go and we will Implement all crate operations which are create read update and delete and you will see the entire process because I will take you from an empty folder to the deployment and today we will build a task app where we can create one Mark as completed and delete that task just to make this as beginner friendly as possible we will build the API twice in the first one we will store the data in memory and then we will build it again by connecting to a database which is going to be mongod DB and in the front end we will use react with typescript we will use 10 stag also known as react query for data fetching we will use chakra UI for styling and at the end we will deploy our app to railway for free so overall a simple but yet effective tutorial to get you up and running with your very first go Application I I had a lot of fun while building it so I hope you will like it too and I would appreciate if you could leave a like And subscribe thanks for watching and let's get started so before we start coding if you visit the GitHub preo that you could find the link in the description you will see this file called comparisons. MD so I know that most of you guys has the JavaScript background with no. JS so I wanted to create this kind of like notes or cheat sheet that you could use before starting the tutorial or maybe after completing it I think that would be kind of like a cool comparisons that we could do in the go environment and no JS so in node.js when you start to create a new project you would say mpm in it which is uh which will give you a package.json file and the equivalent of that I'll just zoom in a little bit and go is going to be go mod in it and then you would put a module name so this is going to be some kind of like unique identifier for your module and it is going to create a go.mod file in the current directory and again this is going to be that kind of like package Json file which contains information about the module its dependencies and the co version that you're using and this module name uh has like it could be anything but it has a convention and you will see that uh in a couple of minutes and then when you want to uh start your application in node.js you would basically run this kind of like a command which is in PM Run start and in go you would say go run and then the file name which is going to compile the program and executes it and then when you want to install a package you would say mpm install and then package name in node.js and in go you would say goget and then the package name so goget is not a package manager but it is used to download and install packages from remot repositories and it does not handle versioning and this command fetches the package and it's dependencies if there are any and then as we just talked about it before package.json the equivalent of that would be code. mode file which contains the information about the module its dependencies and then the co version so when you want to install all dependencies in a project you would say mpm install and in go that's going to be go tidy and then when you want to stringify Json so you would call this method and in go this is called uh some like marshalling so you would say json. Marshall and you're going to have uh so like the go data structure and when you just Marshall that it's going to stringify it to a Json string and the reverse operation is going to be json.parse which is going to be UNM marshalling so again you have a Json string and you're going to run this method with that and it's going to give you that go data structure in Json right now this code might look a little bit complicated but we'll get to that and then the ndman is something that just uh reloads uh your application whenever you change some source file right that's going to be in the njs and in go there is air which is a live reload tool just like node Manon but in go applications so it's going to watch uh for file changes and automatically rebuild and restart the application it is similar to nodon and there are other Alternatives like fresh but uh for my case air was the most convenient one to use it and to be able to configure it you need to have a file called air. toml and this is something that again we'll just get into that in the video and uh so to be able to store your environment variables you would install the TMV package in node and in go it is going to be this uh goget and then the module name so github.com jaho and then go. EMV and again this is going to allow us to store sensitive information like API Keys database uis and any kind of like secret and here is an example of that where we just uh you say go. em. load the EMV file and if there are any errors just console log it to the console right or in the terminal but if we just pass that now we could just get any environment that we have and we're going to just assign it to a variable now we would use expressjs in node uh to be able to have that web framework and in go it is going to be uh fiber which is a web framework for go and it is inspired by expressjs so it is fast lightweight and easy to use and you're going to see it is actually looking pretty similar to express and there are other uh Alternatives such as gin and Eco and if you wanted to you could take a look at them after completing this video then let's see a middle W uh so in Express JS we had middle rares right this is actually a concept that we have almost in any kind of programming language when you build an API or something s similar and in go here is how we would use it so we create an app just like in Express but we say fiber. new which is going to give us an instance then we would Mount the middleware to our function and that middleware is going to take the next as the first argument and once we have run the middleware logic it's going to call the next function so that's going to be the middleware and then we have RW handling and here is an example uh the equivalent of that Ino so you would Mount your route and your Handler or the controller function and that's going to take the context and you could just send a response and we'll be using that in the video as well but that's going to be my comparisons I think that's a pretty cool uh list which is about 200 uh lines of code that you could use it after completing this video as well and with that let's go ahead and initialize a go module so here we'll just say go mod in it and then the module name so here is my empty folder that I have just created and I'll open up a new terminal and I'll say go mod in it and then we could just put anything here but the convention is to put your GitHub repo that you will push this into so I'll say github.com and my username then I'll just say react go tutorial and this is going to be the repo that I will create and push this code into and if we just press enter that's going to give us go.mod file here we can see this is the Go version that we are using and this is the module name and to be able to use go I forgot to mention but you need to install go in your machine which is pretty simple you would just go ahead and Google it then just install it and just press couple of next buttons and should be fine and up and running so in go we need to so we have like app packages and modules and let's just see that in on a diagram so here is our note about packages and modules so a package is a collection of go source files that resite in the same directory so here let's see this is let's say a package right and we have the main.go so let's say that's going to be our main package then we have the handlers package package the API package so on and so forth and all of them coming together is going to form a module right so packages collectively form a module and when you initialize a uh go module so basically you are creating a module right because it's going to have multiple different packages and uh like it's going to form a module so the very first thing that you'd like to do is create a main.go file and this is going to be the main package so we'll just say package Main and this idea is kind of like different if you have never used it but once you just write a couple of different lines of code and use it more than so let's say you would use it in a couple of different projects that's going to just make a lot of sense so here this is going to be our main package and in the main package you have to have the main function so here co-pilot is getting a bit uh annoying so I'll just go ahead and disable completions so here I'll just have my main package and and I'll just uh let's say console log hello world for that we would use fmt let's import that and I'll say fmt print line just like this and I'll say hello world and to be able to run this file I'll just say go run and main.go now we should be able to see Hello World in our console and let's see the variables in go so I'll just shrink my terminal now there are couple ways of creating variables so with the VAR we have let's say my name and type is going to be string so I'll just say John do and there is another usage with const we'll say my second name that's going to be string and we'll just say Jane do so this is not going to be a go complete uh crash course but I just wanted to talk about variables for a second because there is another way of using that which is pretty common where you don't really declare the type but that's going to be inert so I'll just say my third name and if I just put this colum and equal sign I could just say uh let's say Bob do so here this type is going to be string by default because it has being infert and I'll be using this kind of so this kind of variable assignment a lot in this video and if we just say fmt do print line my name let's say duplicate this one twice I'll say my second name and my third name we should be able to see all of them in the console let's go ahead and run this file with gun main.go and there we go we have all of them in the console so that's going to be the variables and just keep in mind that this is going to infer the type um I think I could delete all of them and here we'll like to install the fiber so that we could create our API and just have our web framework right so I'll open up my terminal and I'll just say CLS to clear up my console or my terminal and I'll just say go um get so let's get the fiber so I'll say github.com go fiber SL fiber and then I think it's going to be V2 now that's going to get that and update our go. mod file so there we go we have all of our changes and even we got the go. suum file and it's going to be a again related to packages or modules and let's create our app so I'll say um just like this it's going to infert the type I'll say fiber. new and we'll take to say app. listen and now you you would put column and then let's say the port which I'll go with 4,000 and that should be capitalized and if we have any errors we could just wrap this with let's say log and import the package and fatal so with that we should be able to see any uh so if you hover over this it's going to say fatal fatal is equivalent to print followed by a call to OS exit one which means there were some errors but if we don't have any I think that's going to work fine let's go ahead and run our um server right I'll say uh go run main.go and we should be able to see the hello world and now it is listening on our let's see this port and here we are getting this kind of like security kind of thing I'll just say uh accept the so just let me use the go so now whenever I change anything in this file so let's say hello world s it is not going to restart my server to be able to see that change I need to kill it and then just restart it again so now I could see it just has the new update and like the thing in the console but I don't really want to have this I just want to have that kind of like not mom feeling where it's just going to restart that uh as soon as I change anything in this file and for that I'll just go ahead and kill my terminal clear that and install a package called air so I'll say go install um and then this github.com and just paste it and press enter and once you have done that it's going to install air where we uh where we need to create a file for the configuration so go into this uh like file explorer and just create air. toml and to be able to get this kind of like um formatting install this extension in vs code so it is this one that I'm using to be able to get this kind of like the formatting that you'll see in a second now this is a file that I have prepared with the help of chat GPT and taking a look at from the stack Overflow and I put some comments for your convenience so here we just say the root file is going to be this current directory of the project and the temp directory that you would like to uh store your files is going to be temp which is going to be created whenever we run the air command and here are some build configurations so we are just saying include any go file just watch that changes and exclude any in the client and in the temp and we don't have the client but we'll create that when we when we add our react application and here we have a couple of different commands that you could take a look so it is not really important and let's kill it I will go ahead and just say air and here we can see it has been created and now it listens for our server so now any anytime I just do some change it is going to actually restart it because it says main. go has changed so it's going to build and it's going to run that here we can see the updated result so we don't really need to kill it and then just restart it again now let's go ahead and add our first route so here I'll just say app.get in the root route where you would like to call our Handler function so I'll say funk which is going to take the context and you would like to call it as see this is the convention and that's going to be fiber. context but that's going to be a pointer into that so I'll explain the pointers in a couple of minutes most of you guys know uh how that works but in case uh so like some of you don't know I'll just try to explain it pretty quickly and we'll just say we we might want to return some errors so we're going to put that and we'll say return let's say c. status of 200 and we'll just say let's see this is not correct okay see. status 200 and the Chason data we would like to send let's say fiber. map and we'll just say message it's going to be let's say hello world and to be able to test it out let's go ahead and install this Postman extension feel free to get that I think it should be this one okay instead of using this desktop application we're going to use it directly in DVS code I'll just zoom out bit and I have a workspace called react go tutorial and I would like to add a new collection I'll just say todu and I'll just create uh let's say add a request that's going to be a get request and I'll just say uh maybe get todos for now let's call it like that and our endpoint is going to be HTTP Local Host and and our Port is 4,000 and we would like to just send a request to the root route and if I just send that now it's going to say hello world because this is what we are sending so now that we have this kind of like boiler plate setup where we have our application we are listening on this port and we are just having this kind of like hand Handler function I think we are ready to go and build our first the first part right so we're going to store Tod do in the memory that's going to be the first part and then in the second one we're going to actually connect to mongod so here we we're going to have couple of different to and for that we could use struct Ino and which is going to allow us to have custom kind of like data structure where we could give different fields with different data types so I'll say type which is going to be to-do and I'll say that's going to be a struct and open up this Cur Braes so each uh Todo will have an ID let's say the type is going to be int that should be lowercased and we'll say completed field it's going to have which is going to be bull or bullan and we'll say it's going to have a body and which is going to be type of string and in the Json body we'll like to just rename them uh I'll just say Json and open up this uh codes and I'll say ID and I'll do the same thing for this one back Tex Json and that's going to be let's say backx completed and this is going to be the value that you'll actually see in the response so Json body and that's how you would like to call it so I'll just save to get this formatting and now in the main function we'll like to have the to-dos array so I'll say to-dos and assign it to let's say just like this I'll say it's going to be to-do but an array of it right so just like that and the very first thing that we would like to do is actually create a to-do so I'll say app. uh post so that's going to be our post method and our endpoint is going to be API SL too here would like to have this function is going to take the C and it's going to be pointer to Def fiber. context and this function might uh return errors might return errors so just going to put that error and just have our function body so we're going to have a to-do right let's just say to-do is going to be equal to this to-do uh struct that we'll have now this is going to give us uh since we didn't pass any value into it it's going to actually create it with the false values or the default values and for INT it's going to be zero for Boolean that's going to be false and for string it's going to be an empty string so here just imagine now we this to-do is equal to let me just put it in the same line so the ID is zero um uh completed is going to be false and the body is going to be an empty string but this body or this object is going to be coming from the user right it's going to be coming from the request and for that we can check for it and assign it to um assign that into this to-do so I'll just say c. body parser and we're going to pass D to do so if you take a look at that body parser binds the request body to a struct so it's going to take the whatever user uh sends from the request and assign it into this to-do but now this should be a pointer so we need to just say uh get the memory address of that and this might return us uh a error so I'll say if error just assign it into that one and just put this where we'll just check for error so we'll say if error is not nil which is equivalent of n in JavaScript and we'll just say return the error so here this looks a little bit weird where we create the error in the same line and just a check for it we are assigning the value and check for it right um and then we'll say users can create the to-do but what if body is an empty string then youd like to return an error so I'll say if too. body is equal to an empty string then I'll just say return C do status of 400 and I'll say Json where I would like to say fiber. map and I'll say error field is going to be let's say to-do body is required okay but if this is not the case we can increment the ID by one because it was Zero where we have the false values right so I'll say to-do do ID is going to be the length of to-dos plus one and we'll say now to do uh we'll take the append uh like append the current to that we have just created so I'll say append call this method and we'll say enter the to-dos add the new to-do and since this is the memory address we'll like to get the value out of it right that was the pointer and eventually it will say return c. status of 2011 which means uh a Source has been created and we'll say Json of too so now let's save test it out and then I'll I'll explain this kind of like pointers and I will duplicate this uh request and I'll say create a to-do that's going to be post request I'll save that and our endpoint was SL API SL to where we would like to send the too body so let's go into the raw Json and if we don't pass anything that should say uh okay this is the this is giving us an error let's see what is the problem maybe opening up our console so I'll just I think save that one and send it again okay I'll just say body is going to be hello world okay it says now it's been created but if we don't pass anything it's going to say to-do body is required and that means our endpoint is actually working we sent a request to there and this function run where we check for the errors and eventually either return the response or the error and now let's take a look at this pointers so here let me just explain that here and then I'll just show that in a diagram so let's say I have a variable maybe I'll just zoom in a little bit so here let's say I have a variable called X which is type of int and let's say the value is five and then this is going to be stored in a memory address right so let's say it's going to be 0x 0 0 0 and maybe one so this is the memory address of X and the value of it is five and let's say I'll have a pointer now and that's going to be int and just to make sure that this is a pointer we need to put this asterisk before that int and I'll say this is the pointer that points to the memory address of X so that's basically it this is the memory address of X so the value of p is now actually the memory address of X okay so this is the value that P stores and the value X stores is five so if you just say now um fmt print line of P then you're going to actually get this value and if you say p but the like the address that it I mean the value that it stores it is going to give you the value of x which is going to be five so I hope you are able to see how that works P stores the memory address of X and when you ask it like that it's going to tell the compiler to give the value that has been stored on this address so that was kind of like uh so strange idea if you're seeing this for the first time de pointers so we have a memory and let's just see that on a diagram so we have just created a variable called let's say x the value was five and let's say this has been stored on this address okay so this is X the value of five and then we have have created a p which is pointer and it is going to point to the so it's going to point to the X so here we have the P for the value it is going to get the memory address of X let me just mark it like that and there you go now if you say hey P give me the value of this address that you are storing then you would just say asterisk oops so asterisk and P which is going to give give you the value that has been stored in this address which is going to be five and here this is the kind of like what I've explained and here we got the memory address of that Todo and we're getting the value out of it and this is how it works in go so kind of like strange but once you used to it it gets uh it just makes a lot of sense and so we have created the to do endpoint so I'll say create a Todo and let's try to update a to-do I will delete this line and below that I'll just say update a too so for updating we could use the put method but I think I'll go with patch so it's just preference feel free to use the one that You' like to use and I'll uh I'll give the endpoint of SL API slash toos slash the idea of to-do that we would like to update so that's going to take the Handler function context so let's say fiber. context and we could return an error and we'll just get the first ID from the prems so I'll say ID is equal to C that prems and our prems is called as ID now this is going to be type of string right so this is something important to keep in mind and we're going to first for loop our toos that we are storing so I'll say for I this is going to be the index and then the to-do itself where you would like to say range to-dos and this is how we would run a uh for Loop in go and go doesn't have while Loops so you you need to write them in for Loop if you need any and here we'll just go ahead and say uh if to-do do ID is equal to the ID that we have in the prems but now this is not this is going to give you an error because this is the type of int that you are storing right and this is the type of string and to be able to make that work we can convert this too ID to be a string and I'll just say fmt do Sprint um too. ID okay with that that should be fine and we'll just say too um I so it's going to find that in the completed field we're going to just make that to be true so if you want to negate it so you would say uh just get the current value so I'll say todos I complet it so it's going to either make it true so if it is true it's going to be false but if it is false it's going to be true but in this case I just want to always make it true when I send an request to this endpoint and once this is done I'll say return c. status uh let's go with with this one 200 and we could just return the updated to-do so I'll say to-dos and the index but if this is not really the case we're going to say to-do is not found so return c. status of 404 and let me just scroll a little bit and I'll say send maybe just Json fiber. map so to-do not found let's go ahead and test it out I'll create another one I'll duplicate this and that's going to be patch so API todos and let's say You' like to update um the first to that we have created and by the way let's create a couple of different uh so I'll just say learn react send it so it is not completed so let say learn JavaScript Learn Python and let's say learn go and here you can see ID is just incremented by one so we're going to go here and we don't really need to pass anybody so if you just save that it's going to update this method name and if I just say update the first Tod do it is going to make it to be completed so there you go it is learn react where we have the completed field to be true and by the way whenever you kill your server uh terminal it is going to actually delete every to-do that you have because it is storing that in memory so this is something to keep in mind uh when you're working with in memory kind of like approach so okay I think that's going to be it for the update a too uh Endo let's go ahead and create the delete one so I'll say delete a to do and that should be our uh very last and point so I'll just save that first and scroll a bit is going to be app. delete our endpoint SL API SL toos and then slash the ID so that we could know which too that we are deleting and also I think I forgot to update this one which is going to be to be able to get all toes so that's going to be SL API SL toos and let's go ahead and update that one so here we we had the root routee and I'll just make that to be slash API slash to which just going to just return to this that we had right if we save and if we just send a request to that let's just see send it again because it was restarting okay let's see what is the problem so it says missing Handler in route um I think we forgot to let's just comment is OD since we don't have the Handler function it just throws us an error so I'll just save that and in the get to-dos we should be able to get send this request and we cannot get anything let's just send it again okay there we go server just started and it says hello world but we don't really want to get that so if we hit SL API slash toos okay looks like it is not really working I'll just go ahead kill the terminal clear my console and I'll just say air and if you just test it out again so for some reason there were some kind of like caching problem so I just killed all of them right and then I open up like get to-dos and now if I just send a request there we can see we don't have any toos in the response so I don't know why did we got that kind of like caching but here you can see this this is the exact same code that we have just written so let's go ahead and try to add this delete to do uh Handler and again this is going to be pretty similar so we like to have this kind of like Handler function which is going to be the pointer to the fiber. context you might want to return an error out of this function and we're going to get the ID from the prems so I'll say C do prems which is going to be the ID in this case that we uh that's how we have called it then we're going to say for I the index and then the to-do in range of to-dos so we're going to find the to-do that we' like to delete so I'll say if to-do do ID is equal to ID and again we're going to get that error because this is the type of integer that's how we have created in the Str and we need to uh and this is type of string so we can't really compare a string to a number so we need to convert this to be a type of string as well just like we have done previously so I'll just say fmt dos Sprint and just wrap the to-do ID with that and if this is the case we'll just say todu and we're going to just reassign it so say aend into the todu up until this index that we are trying to delete but not including and we're going to say to just uh add these values so I + one and up until the end and we need to put this three dots which is going to just unpack those values so let's say if you didn't understand this code let me just show an example let's say we had five different to-dos okay and we have just try wanted to delete the third one this is going to say that just take the first two values right up until the index but not included so we want we wanted to delete this one it is going to take all of them but not this one included so now we're going to have one and two not the three and from I + one so starting from here up until the end so we're going to have four and five there you go we have deleted the third one and this is the new to-do uh list that we have so I hope that makes sense and this is something called varic operator and it is kind of like the spread operator in JavaScript where just unpack the values and we'll just say return um c. status and let me just actually copy that line and paste it because it is pretty similar with the status code and success is going to be true and if this is not really the case we couldn't find anything so we'll just say return 404 uh Json fiber. map to do not found let's go ahead and test that out so I'll just go ahead and maybe add a new request that's going to be the last one and I'll just make this type of delete save that and I'll say delete a to-do okay I'm going to save that and say this is going to be my endpoint SL API SL toos and then the idea of the to-do first if we try to get all to-dos we don't have anything in the memory so let's go ahead and create one so I'll just say learn go and and let's create two different one so I'll say learn react and let's say Learn Python okay so we have created three different toos if you want to get all of them here you can see we have three different items and I would like to just delete the learn react so I'm going to put the idea of two there we go it says success true and if we want to get all of them here we can see the ID of two has been deleted so with that I think that's going to be it for the first part of the course where we have just created four different end points to be able to get to those create a to do update one and just delete one and we are listening on a port so everything works fine and next we' like to actually write this same thing but with mongodb where we could have a database and just store those values so when we kill our terminal or when we kill our server we don't really lose them because that they are not going to be stored in the memory and before we get into that let's just see how we could use EMV in this go application so the very first thing that we need to do just maybe kill this terminal and just say CLS to be able to clear that and I'll say go get github.com SL I think it is called as Joo and then we'll say go. EnV and if we press enter that should get us that module and we'll like the load environment variables and for that let's go ahead and create this empv file and I'm not sure if you have realized but we have this temporary uh so kind of like the folder where the air is going to create whenever you run this Air Command so it's going to depending on your changes it's going to store its files in this temp uh directory which is going to be the executable of the compiled code so in the DMV let's say I have my port as let's say 5,000 and let's delete this spaces and instead of using this kind of like hardcoded value I could just use that Port so the very first thing that I wanted to do is just scroll to the very top and I'll just say error and just assign it like this I'll say go. env. load the EnV file and if error is not nil which means there is an error right we need to catch it and just say log. fatal and let's say error loading. EnV file but if this is not the case I'll just put this port variable and assign it to OS let's import that make sure you have in imported all of those modules and packages so we'll just say os. get EnV and we have called it as Port right and now we could use this value actually in here so I'm going to delete that and I'll say Plus Port so we have called it as 5,000 right let's see if that's going to work or not I'll just clear my terminal and I'll just say air and there we go now I can see the hello world and I can see my server just started on this port which is 5,000 right okay so that's going to be it for this very first section let's just initialize this as a git repo and commit our changes for those of you that want to see uh in the commit history the first version that we have created completely in the memory and next we're going to build it with mongodb so I'll go ahead and maybe just kill this terminal I'll just say clear that get in it initialized an empty G repository um let's create a g ignore file so I'll say do get ignore and the content that you could just grab that from the GitHub repo so this is something that I just wanted to paste instead of writing it from scratch okay so here we are just uh excluding the compiled binary files make specific files MV not modules and all these files that that are not really important to be uh tracked by git so if you save that here you can see this has been ignored this file should be ignored and yeah so let's go ahead and add all of them to the staging area and I think I'll just give the first commit as first section completed store in memory so I'll just commit those changes and I'll see you in the next section okay so in this section we're going to build this exact same API again but this time using mongodb so that we could see how we can interact with a database so the very first thing that we would like to do is just visit mongod db.com and create an account for free and then just log in and once you log in it should take you to this dashboard where you can create an organization and then create a project so I'll just say create a new project and then I'll just give a project the name so I'll just say go maybe react go tutorial and I'll just say next project owner is going to be me so I'll just say create the project and then I'll just create a deployment and I would like to use the free tier which is enough for our site project and cluster name could be just default and let's say create the deployment and here we can see the username and password so you'll like to copy this and don't lose it so I'll go ahead and just paste it for the in the EMV file for a second and we're going to be using that so I'll just say create the database user and once we have done that it's going to say choose a connection method so here there so here on the screen there is my AP address you can't really see it because I hide it while editing this video but you should be able to see your IP address and it is going to add that to enable local connectivity and let's say choose a connection method we would like to connect to let's say from our application so I'll just go ahead and copy this string and then just paste it to here and I'm going to give the or maybe I'm just going to assign it to this variable I'll say mongod dbor URI okay there we go and here there is my password so I don't really need to this one I can delete that and with the help of this environment variable we are able to connect to our mongodb database so this is our connection string and once you have done that let's say review setup steps and let's say this is done so now you don't really want to get some uh development errors so just go ahead and so just go into the network access and here you can see there's going to be your current IP address but let's just add the IP address where we could just access from anywhere so I'll just click to this one which is going to be this IP address and I'll say confirm and it is in depending state in a couple of seconds that should be active okay there we go now it is active and we can visit our database and currently we shouldn't really have any collections but in this case we have one and this is something mongodb gives you out of the box so that you could do some testing but in this case I'll just go ahead and delete that and currently I don't have any databases or any collections but we'll create in a second so we'll like to interact with our mongodb database right so we need to use the mongodb driver so I'll say go get and I'll just put that as lowercase so go get go. mongod db. org SL mango Das driver and I think slash so just type this and press enter that's going to get you the driver so that you could interact with your database so I think I'll just delete this file completely except from this type I'll just cut that and select everything and just delete it okay I'll say package Main and I'll say funk Main and I'll just say fmt print line where I could just see the hello world in the console and then I'll just paste my struct at the very top now this is going to be the exactly the same but we'll like to add one more field which is going to be Bon for the ID and we're going to say underscore ID and just leave it like that for now and we need to add this field because uh mongodb store its data in the format of ban which is also known as binary Json and this is the data format that mongod DP uses so this is something um I think required that you need to pass and then let's say bar collection where that's going to be a pointer to the doc collection and make sure you import this package and now we would like to actually load the environment uhv file and let's just say that so error we'll just say go. env. Lo EnV and if there is an error so if it is not nil then log. fatal let's import the log so here we'll just say error loading. EMV file and you could even put the error message and then we'll like to have that mongodb URI environment variable and we like to just grab it from ourv file right so I'll just say OS do let's import Theos and get EnV and let's see what we have called it it was mongod dbor U and I'm going to take this value and just assign it to a variable so I'll just leave it like that and I would like to be the type to be infirmed uh I mean inferred which is going to be type of string and then we would like to connect to mongod DP so we're going to say client client options this is going to be our variable so I'll say options and we need to import that as well from mango options. client and then we'll say apply URI where we'll take the pass our mongodb connection string and then we're going to get the client and error out of this call and again let's infert the type I'll say do connect and now this want you to if you just hover over that this want you to pass this context right so I'll just say context. background so this is not scope of this video and this is basically something that you'll like to create when you want to have maybe some cancellations some timeouts but in our case we don't really want uh want to have it we just say so it is like saying I am starting this task but I don't have any special requirements or deadlines attached to to it okay so that's going to be the uh information about context this is just something that we need to pass you could uh ignore it for now and we're going to get the client options and again we'll say if error is not nil so error is not nil and let me just scroll a bit if it is not equal to nil we're just going to say let's say log. fatal the error itself and then we can just check the connection with the Ping method so I'll say again in error I'll say client. ping and again this want you to pass a context so we say context. background and make sure you have imported this context package right then here I'll just put the second variable as nail which is read read prep uh and we don't really need to pass it and let's see why do we have this error okay if we just delete that that should be fine and we'll say if again error is not nil let's just do the same thing just like this but otherwise we'll just say fmt do print line connected to mongod DB Atlas so just like that and let's save this and just test it out I'll just clear my console and I'll say air so it just run that it says hello world and then it connected to mongodb Atlas with the help of this methods and this kind of this kind of code block that we have just written and now we would like to have a database and then a collection so for that for my database I'll just go before this question mark and I'll just call it as go langore DB and this is going to be the database that I would like to connect to so here I'll just go ahead and say collection client. database oops it should be database like this so it just autocompletes my code but I think if we delete this part it should be fine um just leave it like that client. database where will have the go langore DP in our collection I would like to just call it as toos so I'll just store all of my to-dos in this uh collection and I'll say app again just create a fiber dot new and then we're going to have four different endpoints so I'll say app.get right which is going to be SL API SL toos and instead of putting the function um immediately here we could just make our code a little bit more kind of concise or maybe clean let's say get to to and I'll just duplicate this I think three more times this one is going to be to be able to create a to-do so I'll just say app. poost and this is going to be let's say patch to be able to update one and this is going to be delete and here in the last two one we'll take to add an ID so that we could know which to-do we are deleting or updating so we have get to-dos and let's say create too and this Handler function is going to be update Del too and lastly delete too then again we could just get that kind of Port from the EMV file and this is something that we have done previously so I'll just copy it and paste it and now we could just check if Port is empty then we could put a default value so I think I'll just go with d5000 and because that's what we are using and eventually we're going to just say listen to that port and if there are any errors just wrap it with log. fatal and now let's go ahead and create all those functions or handlers so I'll say funk the first one is going to be get too which is going to take the context say fiber. context which can return us an error and just get the function and let's just duplicate that uh three more times the first one is going to be create too update too and then let's say delete too and let's comment all this out and just Implement them one by one first uh let's start with this one so here I'll just scroll down a bit and we're going to have VAR to-dos and that's going to be an array of to-do let's say and we're going to just fetch that and maybe assign it to that or just append to that to do right so that should be upper case to do because that's what we have called our struct so we're going to say collection find and we're going to say again we need to pass the context so I'll just say context. background and the second option is going to be bison. M so this might look a bit complicated but basically we are trying to pass our filters in our case that's going to be no filters because we like the fetch all to-dos in our collection so if you want to pass some filters then you would put something into this object but in our case we don't really want to and we would like to just fetch all documents in that collection and this is going to give us let's just assign it to the variables we're going to have the cursor and then the error so error is going to be whatever that is but the cursor is something when you execute a query in mongodb it returns a cursor and which is essentially a pointer to to the result set so you can use this cursor to iterate over the documents returned by the query so just think of it like we have all of our todos and let's just say if error is not nil right so we have an error then just return that but else we'll just say for just map through it so cursor. next and again we need to pass that context so I'll just say uh context do background and for each to-do we're going to create this variable let's say to-do and we'll just say if there is an error first we need to decode that right so I'm just going to assign it to that error and I'll say cursor. decode where we need to just put this Todo and if error is not nil then we're going to just return the error itself but if this is not the case then we're going to just append this to-do into that todos right I'll say pend into the to uh to this Todo that we have just get from the cursor and eventually once we have get all of them we're just going to say return c. Json just pass the todos okay so with that that should be completed for this uh function but now there is one optimization that we could use so we have just created some kind of connection right we are patching something and at the end of the day we'll like to just uh close that cursor when this function done right so I'll just say defer which is a keyword that we use in go to postpone the execution of a function call until the uh surrounding function completes in this case this is the surrounding function right once this completes it's going to run the right side so we'll just say cursor do close where we'll just say context do background okay so again defer is a keyword that you use to postpone the execution of a function until the surrounding one ends or that completes and that was that kind of like the optimization and we could do the same thing here when we create a connection uh to our database so here I think after this mongod do conect we could just say maybe after the error I'll just say defer um client. disconnect. database let's say disconnect and again just pass the context. background so when this main function done with executing right we'll like to disconnect from that uh database from the client so with that in mind let's save this and try to test it out in the postman we would like to get all of our toos and now our Local Host Port is going to be 5,000 because this is what we have put here right I'll just save that and if we take a look it is up and running let's just send a request so we got null because we don't really have anything in the database so next let's go ahead and add the create to do endpoint so I'll just uncomment this and create this function maybe shrink this one and just uncommon this one right so here we'll like to again create a to-do so I'll just say to-do and that's going to be equal to a new to-do so again this is going to be a pointer so just to keep that in mind because we will use c. body parser so I'll say C do body parser there I can see that and I'll just say pass it to do into it and again just remember that this is going to bind the request body to a struct in this case case this is going to be that struct we're going to take the request body and pass that into that struct and here we will just say if this is going to return us an error so we like to just assign that and we'll say if error is not is not nail right I'll just say then just show the maybe return the error itself and again we're going to just check if body is empty or not so user can't really create a to-do uh by putting nothing so I'll just paste it here we just say too. body if it is an empty string then just say too body cannot be empty and then we'll take the insert into the mongod DP right if we just pass all of those if checks so I'll just say collection do insert one which is going to take the context do background as the first argument and then the item that you like to insert which is going to be this to do and that's going to give us let's say give a bit spacing it's going to give the insert result as well as the error so here I'll just move on to the next line and I'll say if there is an error and just return it but otherwise let's just move on with the function where we would like to just update the to-do ID right because when we created this to-do that's going to have a faly value and as I have explained previously the ID is type of int so it's going to be zero right ID is going to be zero completed is type of bullan by default that's going to be def false and body is type of string that's going to be an empty string but now that we have created that and insert it now we have the inserted result so we would like to just update the to-do ID with the inserted ID so I know I know that sounds a bit complicated but here we'll just see in a second insert result. inserted ID and which is type of primitive let's just do this type uh assertion right so primitive and just uh import it from this mongod driver doob ID and I think we forgot to use this one when we initialize this to do struct so here we have this ID it is not going to type of int because mongodb has its own ID type and we'll just say that's going to be primitive. object ID okay we just remember that and if we take a look at here we need to add the error and otherwise everything should be fine so we have just updated that and let's say return c. status of 2011 a resource has been created and Jason just return that to do now there is an issue here where when we just create a to-do right so that should have an ID and by default that's going to be zero so we'll just say if it is zero then just omit that value here I'll just say omit empty and I'm I'm going to pass that to here as well and now this basically says if the value is false then just don't add it to the response okay or let's just delete that and see what's going to happen happen if we don't really add those fields so we have our create Todo function is up and running right let's go ahead and test it out where all I have to do is just update the port number because we have updated it and for the body let's say Learn Python and let's send your request now it says this has been created let's double check if we just refresh our database we should be able to see this goink DB and then the todu collection but here we can see the object ID is value of zero because that was the default value that it's going to give right this is the falsy value and we're going to say if it is empty then just omit that value and don't put it and that's what we're going to do basically we'll say omit empty and now I hope you're able to see what this does if it is empty then just omit that let's go ahead and first delete this document now we don't have anything in our database and let's create that again and the only change is going to be this ID it is not going to be zero but it's going to be created by mongodb right it's going to be a default value let's say learn go and let's say learn react and if we now try to get to this instead of getting null we should have this array of objects which we have three different todos and all of them uh are not completed is because as the default value but we're going to fix that next so let's go ahead and update it Todo first shrink this function get todos create uh create todos and then add this endpoint where we have the update Todo function so here in this function again we'll like to take the ID from the c. prems which is going to be the ID and that's going to be type of string and we need to convert it to be type of object ID so I will say that primitive doob ID from hex and we're going to pass the string ID which is going to give us let's say the error as well as the object ID so I'll just keep this as object ID and then the error okay so we need to do this conversion otherwise we can't really compare it so from this string we just made it a object ID that is type of primitive which is what mongod be uses right so we'll say if error is not nil which means there is an error so here I'll just put it like that and I think I'll just say invalid to-do ID so I'll just paste this line where we just sent 400 error status and then here we just want to update a to do so I'll just say collection. update one where we would like to first pass the context. background that was was the default uh argument then we'll like to add our filter right so which one that we'll like to update and then which field that we're going to update so these are the two things that we need to create and if you remember to be able to create a filter we would use b.m and if you just leave it empty that's going to uh just say uh all uh documents right but we want to just get the one that has the idea of this object ID that we are getting from the prems and the update field we would like to just update the completed field to be true so I'll say ban. m and here we just say set to be able to update and we'll say again ban. M and the completed field is going to be equal to true so this looks like kind of like mongus if you have ever used it and if this looks a little bit complicated it is just the syntax that you need to get used to it and this is going to return us the let's say uh like underscore because we're not going to use that and it's going to return us an error and just assign it to that values and we'll say if error is not nil again just return that so I'll just say if error is not nil return it but otherwise we're going to just uh return a success status with 200 just like that so I'm just going to save that and just test it out also let's close these maybe save this one um so it was this and let's rename this because that's going to be update a Todo if we got all todos we know that the first one is python which is not completed I'll copy the ID of it and I would like to update it and here I need to update the port so say update this one to be completed if I just send that here you can see it says success and let's get all of our Tod this should be true now there we go if we just check it in our database it should be working fine for the first one which is completed and the very last thing that we need to add is to be able to delete a to do right that's going to be our very last endpoint so let's click close all of them and uncommon this function sure shrink this one oops so shrink this one actually and uncommon this line um so here again we're going to get the ID just like we have done previously from the prems so c. prems oops what is going on okay I'll just do contrl Z I think it imported something and I just did control Z okay so here c. prems you'll take to get the ID and then again we'll like to convert that object ID from hex so we'll say object ID and then the error field it should be like this so primitive doob ID from hex and then we're going to pass the ID so from the string we got the object ID of primitive type and we'll say if error is not nil then just say return c. status of 400 and then maybe Json and let's say fiber. map we could say error where the ID is invalid so invalid too ID but if this is not really the case then we' like to just delete one from our collection so we'll say collection delete one one and again context. background just like this and then we'll take the pass our filter so let's go ahead and create that so I'll say filter is going to be equal to b.m and our ID is equal to this object ID oops if I can type correctly right and again this is going to return us to different values which is going to be something that we don't use and the then the error itself and let's say if there is an error then we' like to just maybe return it so if error is not nil can just return that but else we'll just say success is going to be true in this case I'll just copy that line and paste it with 200 status code okay let's go ahead and test that one as well so that's going to be our Port 5,000 and then the ID that we would like to add let's say since I am done with this one I'll just go ahead and maybe delete it right which is Learn Python I'm going to send that it says success true if we just try to refresh and there we go now we can really see that Learn Python to do and with that I think we have completed this part as well where we have just added all four Crow op operations right so we can get all of our to-dos where we just say collection. find and pass an empty filter so that we could get all of them under this cursor and we just Loop through it and append it to the todu uh this array or the slice that we have created then we just return it as a response we can create one with the error handling and we can update one with our filters and then the update filter that we'd like to update and then we can delete one so here we can see it is actually pretty easy to build an API with it if you know the basics and here this is something really important to keep in mind that you would like to omit the empty values for IDs otherwise it's going to be that object ID of value that's 0 00 0 that we have seen uh just couple of minutes ago and here is how we can uh like connect to our database and and we're using this defer keyword to be able to disconnect once this surrounding function completes so I think that's going to bit for this section and next we'll like to build the front end and connect to this application from that react app so instead of using Postman we're going to use that react application so I'll just go ahead and just add all my changes to the staging area and just put a commit and we have some built errors let's see so for some reason this is not being ignored let's go ahead into the get ignore and maybe I'll just say logs and I'll just say do log and with that now that should be if we just put it like that that should be ignored we just say uh we just said ignore that any file that ends with log okay so these are the changes that we have done this is the main f file you could take a look in the commit history I'll just add my changes so this is my commit message second section completed where we just store our data in mongodb I'll just commit the changes and I'll see you in the next section okay so in this section let's go ahead and create our react application for this I'll just open up my terminal and I'll just say make directory called client there we go it has been created and let's see the into that and now I would like to create a react application which I'll say mpm create feed at latest and I'll just say that uh dot so that it's going to put that in the current directory which is going to be client if you press enter that is going to ask us two different questions where we would like to go with react and typescript so I'll just select react with typescript now it says run mpm install because you got bunch of different uh like in the packages and you have bunch of different dependencies you'll like to install that so that you could get your not modules folder so that's going to go ahead and grab all of them now while it completes we going to be using chakra UI so let's go ahead and say chakra UI um and take a look at the documentation so this is a component Library which is accessible for react and we like to use use it um just to sped up the process and this is how we would use it let's first copy this command where we like to paste it into the client directory right I'll just paste that and that's going to give us the dependencies that we need and let's go with the framework guide of beat so we have got this script and it tells us to wrap our application with the chakra provider I'll just go ahead copy it and in my main.js Tex right I will just wrap it like this and let's get the chakra provider so it doesn't give me for some reason which is going to be this one and by the way while we're here let's go ahead and delete the assets delete the app. CSS and in the app. CSX let's just say uh P tag or maybe a button that says hello and this button is going to be coming from Chakra so there we can see let's delete this ifcs app CSS v logo and everything okay with that let's go ahead and also install a package called uh react Das icons we're going to be using them for the icons and with that I think we should be able to uh find with chakra UI let's say mpm runev to be able to start our development server which is going to be at this port I'll just control click to it it's going to open this uh Local Host 5073 and there we go now we have this button that says hello in your case that might be a light mode here it is dark mode for me but we're going to implement that so that we could switch from dark to light and light to dark and also this is the demo application that we're going to build so here we we're going to have this kind of nav bar where we could go from light mode to dark mode and here let's just start with the nav bar so the very first thing that I'll be doing is to go into the app. uh TSX and I'm just going to wrap everything with a stack which is coming from uh chakra UI and I'll say height is going to be 100 VH which is the entire screen so we're going to have a nav bar we're going to create this component and we're going to wrap rest of our application in a container where we'll have a to-do form and then a to-do list so let's take a look at the end result we have a nav bar and the rest of our application is in a container which just centers that here right so in the middle of the screen we have a to-do form and then a to-do list and each of them are going to be a to-do item right so this is a to-do item with check mark and delete uh button and when you say stack that's going to just put every child on vertical Direction so we have Navar at the top and below that to-do form and then just the to-do list so let's start with the Navar and for this we're going to be using these images and for that you need to visit the GitHub preo and under the public folder you're going to see uh couple of different files so I just grab them and paste it into this folder so I just copied all of them and I will just paste it into this file where we just have this explore. PNG go PNG this goang for the Fab icon and we have the react. PNG and we'll like to use that in the Navar so first let's comment this out and visit the Navar component which we don't have so let's create the components folder components and you'll like to have the navb bar. TSX so here our focus is not really the UI design so I'll just go ahead and copy and paste this code which is pretty basic and I'll just walk you through that and you can find this code and you can find this code in this kab prepo in the navb bar. TSX so we are never going to change this file later so you could just copy that and paste it so here we have a container with maximum width of 900 pixels and we have have a left side right which is going to be let's see it's going to be this left hand side with three icons with a plus and equal sign and on the right hand side we're going to have daily tasks with this kind of like toggle switch where we can go into light and dark mode and here we just say background of this box is going to depending on the uh color mode if we are in the light mode this is going to be that color and if we are in the dark mode we're going to be using this color and we are getting this Hook from Chakra UI where we have the color mode as well as toggle color mode function when we clict to that we're going to change the uh color mode as well as the icon so let's just save that import it and delete this and let's use it so this is our application there we can see it is here we can switch that mode but for some reason it is not being centered and let's see why this is the case first I'll go into the dark mode and it is because of this index. CSS we have this additional styles that came with v so if we delete everything in this file and if we just refresh there you can see it just works fine just like in the demo application so here you can see it is almost exactly the same where we just make this icon a bit larger and the very next thing that we'll click the add is going to be this um this to-do form where we just have an input as well as an icon so if you want to learn more about this dark and light mode you could always take a look at the documentation where you would go into the color mode and they have just example API so let's say dark mode and like if you visit use color mode they're going to just show you how you can make this toggle uh light and dark and this is the exact same thing that I'm using because I just take that from the documentation so there isn't anything complex in this file and I'm not going to explain that it is just CSS Styles so you would just grab that and paste it into this file from the GitHub repo and the next thing that we like to add is going to be this too form I'll just uncomment this and create this to-do form component so here I'll just say rafc and now we could really type this uh component from scratch and again there is not anything complex so I don't really want to waste uh time on like the UI I'll just go ahead and paste it and if you want to get this code I'll just put that at the very bottom of the file I'll just say starter code because we will uh change this code in the incoming minutes and I want you to have this starter code while you're uh following along okay so you would get this kind of code and paste it and just follow along with the tutorial so here we have a state where we keep track of the to-do and we are keeping track of that with this on change and this input is going to be focused by default when you refresh the page and when you uh click to a button it's going to make it uh scale so it's going to shrink that and if we are loading we're going to show a spinner of size EXO mode and everything is coming from Chakra UI and we have react icons if you want to take a look at that as well and when you submit this form we're going to just call this function which takes the event and this is the type of it that is coming from typescript which is a form event and we'll just prevent the default so that it doesn't refresh the page and it's going to say to do add it later we're going to add this functionality so that we could actually uh interact with our mongodb database let's save that and we have an error or it's just a warning it says you not using that but we'll use that later okay let's save and just see that in action here we go we have this input and the button if you refresh the page this is going to focus Itself by default because we have this lineup code and when we just add anything into here it's going to say too add it with this alert so that's going to be to-do form component and if you really want to see the um like the UI design just pause the video take a look at it from the started code basically we have a form and we have a flex on the left hand side we have the input and on the right we have the button if it is pending let's just make this to be true we're going to have this loading State into it but else if it is false we're going to see this plus icon and next we would like to build the too list component so that we could just see this data I'll go ahead and create that one to do list. TSX and in to-do list we're going to have to-do item. TSX so here I'll just again get the starter code pasted twice so that you could use it as well and again this is pretty simple file I'll just paste that and I'll paste it again comment this out um just like here and I'll just say starter code so you would copy and paste that part and basically we have fake data right three different toos buy groceries walk the dog do laundry and cook dinner two of them are completed and two of them are not so I'll just shrink this to-dos and we have a loading State and we are importing the to-do item for each to-do right so I'll just go ahead and add this to-do item as well and this is going to be the very last thing that we will copy and paste so about 40 lines of code and I will paste it again starter code for those of you guys that want to follow along right okay so these are just Styles that's why I don't really want to waste too much time on it and okay if we save this file and this one this is taking a to-do as a prop and we're just giving that type withd typescript and for each to-do we'll just check if it completed then it's going to take this green 200 color but else that's going to be yellow 100 and we'll just check so we're going to give this line through if it is completed right so just like that if it is not it's going to have this normal text and if it is completed it's going to have this done badge and if it is not it's going to show this in progress right so this is not completed and this is completed then on the very right hand side we have check mark and then the delete or the trash icon so that's going to be it let's save and see that in action in our application first we need we need to go into this component and import it just like this it's going it's going to refresh and there we go so here we have a loading spinner is because we have this loading state is true and we just check if it is loading just show a spinner of size x large and let's say like default that's going to be false and there we go so this is the today's task where we have just couple of them and all of them are fake data and also let's go ahead and update this uh title to have this kind of gradient and for that we could check the documentation let's say gradient and here you can see they are using it on the text and I'll just give you this uh BG gradient linear tool left right you just put the right uh value and then the left one so if we just put something like maybe blue it's going to go okay so it goes to left so that's going to be the right value and this is going to be the left value which is this pink color starting from right with blue it's going to go to the left with this pink color and let me just give you the styles to be able to get this kind of linear gradient so here let's just go ahead into the to-do list where we have this text I'll just give these Styles uh starting from this color to this one and BG clip of text so that we can get this end result now everything works fine it is time to actually add this functionality and grab these data from the database and for that we'll be using 10 stack also known as react query so if you visit 10stack query here you can see the entire documentation and basically we'll like to use this as our data fetching solution and here you can see the motivation behind it and like it just gives you a lot of different things out of the box that you could use things like caching duping updating out of uh out ofd data in the background and lots of other things and I think it's such a great library to use and at the end of the day you'll like to use it in your uh so say production ready applications because that's going to give you lots of different functionalities that you don't you want to reinvent so the very first thing that we'll like to do is just install it so let's take a look at from the documentation if we go into the installation we should be able to see this Command right I will copy it and paste it in my terminal and just make sure it is under the client so I'll just paste that and install it and while it installs in the background let's go ahead into the quick start we could take a look at it how they're going to set it up or you could just trust me and uh see my guide so this is something again I took from documentation where we would like to create a query client and import it from our package and we' like to wrap our application with it so that we could use this query client in our application and you'll see what that uh what that is going to provide right so I'll just say query client provider and then just wrap my entire app application with it so let's import that one as well okay with that now we should be able to send uh request to our database or our back end right so we're going to go into the let's start with I think to-do list where we can just fetch all the to-dos that we have in the database and before we start doing that let's just create a type so export type let's say to-do and we'll just say each to is going to have this underscore ID field type of number body of string and then completed is going to be Boolean and in the to-do item when we say we're getting this to-do let's say the type is going to be this to-do that we are exporting from this file okay and I think we could delete this to-dos now and instead we're just going to fetch that okay so instead of this fake data let's try to fetch it so when you want to Fed some data uh in react query you would use use Query hook okay which is going to take the first argument as U this object and we're going to pass the query key and you'll see what that is going to do in a second but basically this is like an identifier for this query and when you want to refetch data for this one we're just going to say uh batch the query that has this query key of to-do and that's going to do it so again you'll just see that in action in a couple of minutes let's say we're going to have the query function where we'll have try and catch in the try we'll say cost R await fetch where our endpoint was let's say HTTP uh Local Host 5000 SL API slash to and we're going to get a response I mean a data back and we could just say if response is not okay then just throw this data. message that's not going to be data. message but it's going to be error because this is what we are returning from the back end right and in the catch we could maybe just um console log the error and then here I'll just say return the data and if you don't have anything then just return an empty array um here we need to so this is going to give us a value let's say con data which is the todos I'll just rename it to be todos so to just to make our code a little bit more readable and instead of this fake use State I'll just say is loading is going to be dynamic and here now it just want us to put some value right so this is a generic here we'll just say this is going to return us a to-do an array of todos so just like that let's delete this one and here so for some reason it says property data does not exist on type string so let's see why this is the case so we say use Query we just get that not from Checker UI but that should be coming from the 10 stack query so just like that it should fix it where we just fetch our toos from the back end and if it is not okay we'll just uh throw that console log it and otherwise we'll just say uh return the data but if we just save it like that we're going to get a course error right let's just see in the console um let me just zoom in a little bit okay refresh oh okay so we don't even have our server is up and running so I'll just kill this client and open up a new one and I'll just say air and just make sure you're are not in the client directory but in the route so there you go now it says it is watching those changes but I don't think if it is correct because we set that um exclude the client folder so whenever you change something here it is not going to restart the server but I just don't know why it says watching and here we have connect to mongod Atlas let's send a request we got the course error where it just says you cannot send a request from this uh URL to Local Host 5000 and to be able to fix it let's go ahead and just add the course to our go server so in main.go we'll like to add course after we maybe before these requests so here I'll just say uh app. use and we'll just say course and make sure you import it from fiber middleware and you'll just say new we you'll like to say course. config and it's going to take this kind of like an object where we'll just say allow origins of let's say uh HTTP local host of 5173 which is going to be our front end application and we'll just say allow headers to be origin content type and make sure you put a dash and then the accept so if you save that now it should hopefully restart our server and we should be able to fetch data let's just send again so I think it just tries to restart let's just see okay it is up and running and if we just send that there we go now we have learn go and learn react which is in our database and they are not completed that's why we just see that as this kind of uh in progress and here we just say uh you need to add a key let's kill this one and in the too list we're going to add this underscore ID so here we already have it why do we get that so under the to-do list H it says they should have a unique key prop and it is coming from line 50 uh six so that should normally work but for now let's just say idx and we just put the index just like that and if we just refresh we don't have that error and we just fetch our data so the very next thing that I would like to implement is when I click to that I just want to mark it as completed let's go into the um to-do item right when I click to this uh check Circle so I'll just say on click let's just say update to do function and before we write that let me just quickly explain what we have done here um basically whenever we uh render this to the list we are calling this use Query which is going to send a fetch request to our endpoint and it's going to give us the data back which we call it as todos and we are mapping it uh with each to-do item and we pass this to-do into that component and we are just using it in here right and now we would like to just update a to-do and for that we'll be using mutation hook so here I'll just go ahead and say use mutation which is coming from 10 stack and here this is going to return us a mutate function right so say mutate and I'll just rename it to be update too and it's going to give us is pending State and I'll just call it as is updating just to make my code a bit more readable and here this is going to take again an object where we could give a mutation key so mutation key that's going to be let's say update too and the most important thing is to have this mutation function is going to be async and we'll say if Todo is completed then we'll just say return out of this function with this alert well where we'll just say uh let's say not task but let's say to-do is already completed and we're going to have the try catch so try catch and in the try we're going to just send a request to our endpoint so instead of always typing this Local Host uh 5,000 what I'll be doing is to create a base URL and for that let's go into the app. TSX and I'll say uh export con basore URL which is going to be on this port slash API I okay so instead of using always this value I'll just use this constant and let's save it like that and I'll just put it like this right this is my base URL which ends with/ API and I'll just say slash todos and then the to-do ID this is the to-do that I would like to Mark as completed then I'll say my method is going to be patch and headers is going to be content type of application Json and I think we don't even need to pass it because it is going to uh update it right it's going to make that completed field to be true and I'll say con data r. adjon and if response is not okay just maybe throw an error and return the data otherwise here we could just say console log the error itself and let's save so while we're updating we could show some kind of like loading State just like in the demo application so if I clicked that here you can see I have that loading spinner for a second and let's go ahead and add it um here I will cut that I'll say if it is not pending or I'm sorry if it is not updating this is how we have called it then we'll would like to show this but else if it is updating then I'll just say give me this spinner from Chakra UI and let's say size is going to be small okay so we have some kind of like warning from typescript let's just say just call it like that okay instead of uh ref giving a reference we'll just say the Callback function is going to be this update to do when you click to this box let's see this in action here I'll just say learn goal is completed so it says invalid to-do ID and let's see why this is the case so to do underscore ID is not working for some reason let's say console. log D too and just see that in console okay so it has the ID field and I think we forgot to update it in the like main.go I'll just say main.go here this should be called ascore ID and this is something I forgot so I just realized sorry about that save it it's going to restart our server and let's just wait for a second so I'll just go ahead and refresh it okay let's just refresh it again until our server is up and running there we go now we have the underscore ID field and if I click to that there we go it has been updated but we need to refresh it to be able to see it here you can see it just says now this has been completed and so let's implement this when we click to that it should immediately refat the new state so we don't really need to refresh the page to be able to see it and this is where that query key is going to come into play so we will say once you have completed this successfully I'll say on success then you will like to run this function where you would like to invalidate some queries so I know this looks a bit weird but just bear with me we'll say query client and get that from this hook okay so we'll like to just refetch some queries I'll say query client. invalidate queries and the one that will take the update or invalidate first just pass an empty object and we'll say query key is going to be this array toos okay so we had this query key in this to-do list when we try to fetch all of our toos right this is our query key and when we say once you update it just try to refetch this data okay so let's try to see that I'll just refresh and if I collected this it's going to update and there you go because it refet it immediately once this is done uh successfully and and the other thing we like to implement is to create a to-do let's for that go into the to-do form and before that instead of passing this Index right I'll just delete that and I'll put to-do doore ID and now it should work because this is something that we have fixed in main.go file I'll go into the to-do form and so we are storing this when we type into the input and when we submit this form we are calling this function which should actually create a to-do with the help of use mutation so I'll just delete this function and I will actually get that from the use mutation right and make sure you import that from 10 stack query and I'll say const this is going to give me a mutate function which I would like to call it as create too so this is how you would rename it and then is pending state where I would like to call it as Maybe is creating or we could just leave it is pending in this case uh it is just preference but I would always like to go with some kind of a custom name so that I could just know what is going on is creating just like that and here we'll like to pass maybe a mutation key just in case we use it and then a mutation function which is going to take the event right because this is a submit Handler and we'll just say e. prevent default so that it doesn't uh refresh the page and then we are going to have the try catch and I'm not sure why this is not happy with us so maybe we are not returning something let's see okay let's just try to see how this all end up in the try we're going to have con res await again fetch the base URL let's import it and so/ API SL toos we would like to just pass the method as well as the body of the to-do I'll just say method is going to be post headers is going to be content type application Jon and then stringify the body which is this new to-do string and we're going to get data out of it and then we'll just say if response is not okay to say something went wrong or throw the error and we'll like to say set new to-do to be an empty string is because here let's take a look at the demo I'll just say something here once I press this button it's going to create it and now it is going to reset this field so that's why we're using it and eventually we'll just say return data in the catch we could just say Throw new error and here we're going to have after this let's say um on success so I'll just put a comma and on success once we have Del I mean once we have created a to successfully we would like to refat all to do just like we have done previously and for that we need to get the query key and I think we need to say this e will be so react uh. form event and now this should be happy with us and let's say error is going to be type of any um okay so let's go ahead and say const I'll just give a little bit spacing query client get that and we're going to just refetch it so I'll say query client invalidate queries where you like to just refet toos and if there is an error so on error we'll just say uh alert maybe error D message and here this is coming from es lent so I'll just say quick fix okay so we'll just disabling that it's really annoying but okay for now let's just keep it like that and when we in the loading State let's say is creating then show this spinner but else show that plus icon okay hopefully this should be our function Let's test it out I'll just say Learn Python and send that there we go now we have created that one and as soon as that is been created we just invalidate our to-do queries uh so that it could refresh that and here you can just double check it if you go here I'll just clear everything and I'll just say learn C++ and once I send it it's going to first create that one this is the post request and then it is going to fetch it right so here you can see it is going to send a fetch request to API todos which is going to be get method and here this is the post where we can uh create the to-do now we can mark it as completed and I think we didn't implement the delete function and we're going to add that next but if you were to just take a look at the code pretty simple right nothing complex going on we just preventing the default sending a request with our to-do body and we're just doing some kind of error handling and then just return the data on success and on error cases and let's go ahead and implement the delete to-do that's going to be looking pretty similar to this function we could probably make this a bit more uh reusable but I'll just go with the simple uh simpler approach where I'll just uh type it again from scratch just to make it kind of like a beginner friendly and feel free to to optimize this code so again we're going to have delete to do whenever we collect to this uh box okay I'll just get that past it this is going to be calling the delete Todo function and we'll say if it is not deleting so here if it is not deleting State then show the delete icon but else we like to just show this spinner just like this and let's go ahead and Implement our function so here I think I'll just let the copilot to the magic where we're going to have a mutation key a mutation function just going to be async we are sending a f request our base URL and the to do that we' like to delete this is our method we are doing some error handling and returning the data and in the catch case we're just console logging it and let's save and let's just try to see in action but before that I think we we need to add this on success case as well to be able to invalidate queries because if we don't add it let's try to delete this one it has been deleted but I can only see that if I refresh and to be able to fix it we're going to go ahead and add the on success and let's just try to delete this one there you go they have all been deleted and now we just see all tasks completed and it's because in the to-do list we just say that if it is not loading and if the length of toos is equal to zero then just show this text with the image so I think we have implemented almost everything to this application right we can create a to-do let's just say watch a go tutorial and create that one and let's say watch a react tutorial and add that one let's say do laundry and let's say buy groceries so we have added all of them and we can mark them as done we could delete them and just uh just fetch all of them right and here we have the light and dark mode and there you go now light mode looks pretty ugly you can't really uh read this and it is not really uh accessible so let's go ahead and fix it and for that I think I'll just go into the source I'll create a folder called chakra where I could put my theme into it so I'll say theme. TS so here this is a file that you could learn more about in the documentation so that's why I'll just go ahead and paste this code which is about uh like 20 lines of code here we have the initial color mode is being dark and the it's going to use the system color mode and here we just say the background color on the light mode is going to be this one and in the dark mode just keep the default one so to be able to use this we're going to go into the main. TSX into the chakra provider we'll just say theme is going to be this theme that we'll just uh that we have just created and it is not going to be coming from this one but let's just see it is going to be coming from this theme. TS file that we have just added let's save and see this in action and now there we go we have this kind of like a little bit more soft uh background and if you don't like the way this looks just feel free to update it but with that I think that's going to be it for the client now we have this kind of like hardcoded variable right and it is actually fine but when we go into the production and development this is like this should be dynamic right uh it's because when we deploy this application we're going to have the both back end and client in the same route so let's say currently we have our back end in this uh URL right and we're going to have the client under the same URL as well because this is how we will deploy that and once we have once we have add this we are not going to need any course handling as well because both the back end and the client will be in the same uh URL right right in the same domain that's why I'll just go ahead and update this Al bit so I'll say import. met. EMV do mode if it is equal to development then this is going to be our URL so let me just zoom out a bit so that you could see the entire screen and if we are in the production then we'll just send whatever the domain of uh whatever the domain is slash API and I think this is going to be a bit more clear once we add this main. go file right so here first things first we don't actually want to handle let's see where is that course kind of thing so in production we don't really want to have this because as I said before our client and back end will be served under the same domain to be able to make that work we need to make this client folder to be static so after this port I'll go ahead and I'll say if OS let's say os. getet EnV environment if this is equal to production then we'll like to make the client folder to be our static assets so that we could run and show our react application so I'll say app. static when we hit this root route will'll just show let's say uh this client this folder which is going to have our built optimized version of react application and we'll just see that in a second okay so when you send a request to API to um in like all these endpoints you're going to actually call the Handler functions but any routes other than these is going to trigger this react application under the this folder in client and we don't have this environment variable so for now let's go ahead and added to be development okay so that we are in development and now we're going to deploy in a couple of minutes and it's going to be production so we're going to make that to be static and the other thing that we' like to update is that we can't really uh load the DMV file in production because we're not going to have that file in the production environment but instead we're going to have uh environment variables that we will put from the dash board so we'll say if again os. get EnV if it is equal to let's say EnV let's say if it is not equal to production then we would like to actually load the environment variables so I'll just put a comment so it is pretty self-explanatory but let's just have this comment where we'll like the load DMV file if we are not in the production now let's save this one and we're going to go ahead kill our maybe the server and then for the client let's kill this and we're going to say mpm run built and this is going to create a this folder which is going to be that optimized version of our react application and something that I want to change while this happening I'll just not ignore this this folder and I would like to have it in my GitHub repo so that when I push any change it could take it and uh like just deploy my react application so this is not really the best approach but it is going to work in our case and I I found this to be the easiest to work with Railway so there we go now we have the disc folder which is going to hold the optimized build of our react application now if we just kill the client we can just say air to be able to start our backend server so here it is up and running we are connected to mongodb atlas and let's visit localhost 5000 SL API SLT and there we go now we can see all of our toos that we have since we are not in the production we can't really see the react application that we have but now we are going to deploy that and you'll see it is going to work so let's go ahead and push this code to the GitHub so that we could deploy it so here I am in my gup account where I'll just create a repo I'll say react go tutorial and that was the module name that I have give uh at the end at the beginning of the video so tutorial just like that and let's say create the repo I'll just make it private and once I uh publish this video that's going to be public so you'll just see that to be public and if you don't really want to go with private then just select public so I'll go with this option I'll say create the repo and now I'd like to just push uh an existing repo from the command line so I'll just copy all these commands and first I want to add my changes right so here we can see I have everything and let's add them to the staging area and just make sure you are uh you are not ignoring the this folder and I think I just forgot to update one thing so in the index.html let's just say react I'm sorry let's just say go react and typescript where I'll just say for the Fab icon I'll just put this go.png so goang do not SVG but PNG and once we have done that we should CD into the client first and let's say mpm run buil whenever you change something in the client you need to run this to get the latest version of this this folder okay so let's just wait for it until it's been built again so there you go it has been added let's just add those to the staging area as well so these are our changes so stage all of them and I'll just put a commit message so this is my commit message third section completed and it is ready for deployment I'll just commit that and I'll just go into the root and let's just C copy this and paste it which is going to push this local repo to the GitHub repo that I have and if we just refresh there we go this is the application or the source code that we just have and to be able to deploy this we'll be using Railway so head over to the railway. apppp and if you don't have an account create one for free which is going to give you $5 that you could use as the trial plan so I've been using I think over the last one week and it just charg Me 3 cents which is pretty convenient let's go into the dashboard where would like to just start a new project so I'll just say new project deploy from my GitHub repo and this is the very last repo that I have just created and it is private so I'll just select that one and I'll say deploy now so here it's going to initialize it and try to deploy that and and while it's done I mean while it it tries to deploy we need to add a couple of different environment variables so the first one is going to be EnV and here we're in the production let's add that the other one is going to be mongod dbor URI right we need to get that connection string and then just paste it so that we could connect to our database so I'll copy that and paste it now you don't really want to put Port because Railway doesn't really want you to put that Port it is going to figure it out uh himself okay or itself let's just deploy that these are the changes that we have just made EnV is production and this is our connection string so it's going to redeploy the latest change that you have done let's just wait and hopefully it should deploy without any errors and and if we have we'll just try to figure that out so it just looks like the latest one is active now we could go into the I think that should be settings and for the deploy um maybe in the networking so okay we'll just say generate a domain for us and if we just uh wait a bit it's going to give us this URL let's click to it okay there there is nothing here yet let's just wait a bit and then hopefully it should be up and running so here I'm just keep refreshing and it just has not found but it should be up in a couple of minutes and if you go into the deployments like you could see the latest one has been removed and this is the latest one that we have and you could just see the deploy logs where it just says hello world connected to mongodb appas and this is the port that Railway just figured it out because we didn't pass into the variables and I think if you put that it's going to not be really happy so let's just refresh a couple of times and there we go so we have the loading state it connected to our database let's just um why don't we have anything so for some reason it failed to fetch let's just refresh um okay so it says Local Host 5000 API to which is not really the correct URL because we are not on Local Host anymore and there must be some bug uh in this app. TSX so here we just say if the mode is development then this is going to be our base URL but else this is going to be um I think at some point we should be using this Local Host value maybe in our to-do list okay there you go I forgot to update this part right I'll just delete this where I'll just say base URL and plus the todos okay slash toos just like that but first we need to see the enti the client and just say mpm run build and before that I just also realized in the index HTML this should be go length and here I just have a typo so that's why it cannot really oops it is not this one it cannot really get this Fab icon and it just throws an error that says 404 this image is not found so let's just update that and let's say let's say mpm run build just going to give us the new this folder right so it's just going to go ahead and update that and once that is done we could commit our changes and here these are the changes that we have done here we have kind of like es L warning it is not really important so just ignore that and add all of them to the staging area and I'll just say base URL bug fixed commit that and sync that up so once you uh commit your changes right and push that Railway will immediately see that and it's going to rebuild it there you go it says building and it has just been 8 and 10 seconds so just wait for this to complete and once it is done I'll just be right back okay so there we go it has just been uploaded let's go ahead and see and there we go we got the data it is up and running we should be able to get this FB icon as well I'll just keep refreshing and for some reason it is in the cache but it should update in a couple of minutes yeah it should definitely update it because we have update that file let me just double check if we go into the index.html oh okay I again still did the wrong one so that should be go length just like that and you could put another commit but I think I'll just leave it like that so there is a typo that's why it doesn't work but if you go here you could Mark something as a done is going to update you could delete it you could delete everything basically or just say add a new to-do just like that we could make it done and delete that one as well and as far as I know this should be responsive as well so it's going to work on your phone completely fine up until like here which is one of the smallest phones you could ever get and with that that's going to be it for this video if you want to see more tutorials like this where we buil full stack web apps with go and and react let me know in the comments and don't forget to subscribe thanks for watching and I'll see you in the next one\n"