Build a REST API in Go using Fiber + GORM

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] what's going on you guys and welcome back to the channel in this video we're going to be looking at a web framework for in for the golang language and that's called fiber and if you're familiar with express.js then this may be very familiar to you as it copies a lot of the patterns that are used there in this framework now fiber is extremely performant and its performance is i think definitely um blows the lid off compared to other apis or web frameworks and alongside fiber we'll be making use of gom now gom is a orm library for golang it's very popular it just allows us to communicate with our sql or sql lite database that we'll be using in this tutorial now the other thing i want to mention is that when testing the api that we build i will be making use of postman and you can download this at postman.com forward slash downloads i recommend using that if you have no other option however feel free to make use of car commands or any choice of software that you see fit the final thing is that when it comes to golang or building web servers in golang there's no real or nice way of actually having hot reload in it i think when it comes to node.js development you had nodemon and other python web frameworks they ship with kind of hot reloading or it's quite easy to add hot reloading to it but with fiber there is a workaround and i'll be making use of fiber or this thing called air and that's this thing here so you can go ahead and download this i have a um air.tamil file and that's in the github repo that's for this tutorial and that's all in the description in the description below but you can make use of this otherwise this isn't of course um this is optional of course um you can just run your go server as usual but you will have to restart it every time you make a change so whatever suits you but i do recommend making use of this air here that's by cosm trek forward slash or cosmetic in this positive core air um as it just makes development a lot easier and of course you would make use of this in production but yeah so let's first go ahead and jump into uh the directory or directory that you want to build this api in and let's create our module so we'll say go mod init and we'll just name it say dot com github.com slash your username and then the name so i'll just call this fiber api this now we now have our go mod file next let's go ahead and make the necessary installation so go get the first one is the sequel light stuff so we'll say dot io forward slash driver forward slash sqlite so this will just get the sql-like interface or api that we need when it comes to using gom next is actually installing gorm itself so go get gom dot io forward slash com that will install and lastly let's clear this let's install fiber itself so go get and then github dot com forward slash go fiber forward slash fiber forward slash v2 now this v2 is important this is the latest version of fiber and we'll be making use of that so make sure you specify after fiber forward slash v2 hit install and that's our installations made um if you want to use air like i said please feel free to go ahead and install this um probably using these commands you may have to if you're using zshrc or any of your kind of uh bash files or your bash configurations yeah make sure you add that in there too but it's pretty simple implementation or installation so i'm going to go ahead and open this up in vs code and just close all this and like i said when it comes to air again this is not um this this is optional it's not required but i'm going to go ahead and add this air dot toml file and i'm just going to go ahead and copy this tomo file that i have in my repository just copy that and just paste it in and that's it so let's go ahead and create our main.go file and let's get a very basic server up and running using fiver so i'm gonna say new file main dot go go and the first thing that we want to do is just say package main func main and then let's get our app so we'll say app we'll say fiber and this automatically imports fiber version two we'll say a new next let's go ahead and actually add an endpoint to this so we'll say app.get and we'll say this is forward slash api and we'll call a function we'll say this is a welcome this of course will return an error right now as we don't have a welcome function defined but we'll get to that in a second finally we can just start our app so i like to kind of wrap this in a log which will just print out the current status of our server so whether it's starting up or closing say app dot listen and we'll specify the port so i'll say port 3000 so already it's very simple we have um our app up and running well not technically once we've defined our welcome so let's actually just do that now and then run this so funk um welcome now this will take in a argument and this is the context and this will just be a pointer to fiber dot ctx which stands for context and this will return an error now this context is basically everything that comes with a request so your header your body if it's a post request all that so that's what that is what's contained in this so to get this working we can just say return c dot send string and then we'll just write in a nice message so welcome to my awesome api so yeah that's really it when it comes to getting a server up and running let's go ahead and run this so new terminal now if you if you're not making use of this air.tamil then you can just run this as you would any normal um go app so go run and then just main.go and you'll get this output here so we can actually take this copy this there and then let's actually call it so let's paste that in here oops hit send and then we just need to put api and then send and we get this message here so this is in postman by the way like once you have open so you have welcome to my awesome api as it's a get request we can also just run that in the browser and we get welcome to my awesome api nice so that's our server up and running and if you're using if you're making use of air all you have to do is type in air and there you go and any change that you make it will just reload it for you but that's that for now let's just zoom out hopefully you guys can see that all right um probably one more time anyway so the next step is to actually connect our database up now this again is rather simple it's not a lot to take a lot of line of code to actually get this working so the first thing is let's create a new directory we'll call this database in that we'll create a new file we'll say database dot go this will be a package database now the first thing is to declare a struct which will just hold our database pointer and this will be db instance and then struct db pointer to gom dot db and that is automatically imported next let's create a object so we'll say database and then this will be of type db instance and then we can say funk connect db takes no arguments and returns nothing and let's call [Music] the gom to open up our db power database so we say gom dot open and as we're making use of sql lite type in sqlite dot open which again is automatically imported and then within that we'll say the name of our database we'll call this api.db name it whatever you want just make sure it ends with the extension.db and then we can add our configuration and as we won't be having any configuration just type in just throw in a pointer to gom.config and then just curly brackets so the struct okay so that's our first line for our connectdb next is to check if we get an error so if there is an error so if the error is not nil then we can say log.fatal you can say failed to connect to the database we'll just add a new line and then error and we'll just do a system exit of two okay that's if we get an error if we don't however then let's print out that you just log out that you printed that you've connected to the database successfully and then let's create a logger for our database so this is just logging information out it's just printing stuff to the command line and this would be logger default and then dot log mode and we'll say logger dot info so just to add some nice colors etc and to know the state of our database next we'll say log dot print line and we'll say running migrations and we'll get to that the actual migration part in a second so we want to add a to-do so we'll come back to this add migrations that's because when we open up so let's say we start this from the top um where we don't have our database just yet um what will happen is it will create our api.db or create our sqlite database however it will just be an empty database there will be no tables in there so we'll be building an api that basically um uh holds users and uh it holds products and a user can then make an order to that product so very simple we won't be making it too complex but we want all of those so the users the products the orders to kind of be added so those tables to be created in our database and that's what we'll do underneath this to do but for now let's go ahead and set our database so we'll say database so this database is struct here and this will be a db instance including db and then just db so the database that we get back from when we call gorm to open so that's really it i mean like i said with these migrations also if you're familiar with django or prisma in javascript then yeah it works just like that now to actually create our tables let's go ahead and create a new directory we'll call this models in that let's first create a a model for our user so user.go now for this it's very simple first we'll just state package models then we'll create our struct and they struct um the struct that we create here is just a representation of our table it's just the golang representation of it so type user and then struct oops now we want the id which will be an unsigned integer will be and then in backticks json so how it will be how it will look in json format so we lowercase id and then to tell gorm we want this to be a primary key for this table next we want a created app and this will be time.time and by saying like this it will automatically create this uh and then first name which is a string backticks jason and in double quotes fast underscore name next is last name this will be jason representation as last name like so so that's our user next let's go ahead and create a product model again package uh models just to make sure this is models yep and we'll say type product and then structs we'll have the id which is inside integer and this will have a json representation of id and as for gom we'll just say this will be a primary key and make sure the spelling is correct and in camel case uh next we'll have our created app and this will just be time.time and we'll have the name of the product which is a string in json we'll just say lowercase name and then the let's just give it a serial number json serial underscore number so that's really it for our products um lastly we just want to make use or create our model for order and this will have some foreign keys so this is where it gets interesting for we'll say package models and then type order structs and this will have an id so i'm just going to go ahead and copy these two in order to not repeat myself for the third time and then we want a foreign key for the product and a foreign key for the user now to do that we want to create something like a product referrer and that will be an integer as it's just a an association with the id in the other table so the product here or will be associated with this id here and we'll say here that this is in json representation just the product underscore id next we want the actual product itself and as this is sql we cannot actually there's no sql type for the product struct that we defined here that's why we need this product referrer so here we can just say and then foreign key and then colon product referrer so saying okay the product here is going to be a reference is going to be referenced by this product referrer which will then look inside our product table and then fetch the product that has the id that matches this product referral here so that's our product next is our user referrer and this will be of type int json user underscore id and then our user and that will be in backticks.com foreign key user referrer so yeah these are our models so we have our user which is very basic has the id created that time first name last name our product which again has id and created that a name for the product and the serial number and then the order itself which is id created app it holds a product and it holds a user now let's go back to our database dot go and this is where we'll add our migrations in so to do that all you have to do is type in db dot auto migrate and then just pass in the models themselves so the first one will be models dot user so let's drop that a pointer to it of course with this ampersand then we want the models.product and lastly we want the order so now when this runs let me just get rid of this to do when this runs it will create the tables for a user models and order now before we actually go ahead and run this one thing if you are using uh vs code then one extension that i find very handy is this here sqlite and what this does is it just allows us to have like a nice visual representation of our database inside vs code so we don't have to query it all the time so yeah feel free to go ahead and install that and if you have installed it then what you can do is actually let's just run this quickly so let's clear it i'm going to type in air to use the hot reloading let's give it a second to start up any section now ah yeah okay yeah so one thing i forgot to do is actually call this connect db so back in our main.go um we need to do that so we can say database which is automatically imported and then dot connect db that's it so i forgot to do that sorry um let's just zoom in type in air just building it running and here we can see that it's creating our table orders um it created the table for products and it created our users table so you can see here in the file explorer that we have this new file now called um api.db if you have this new this extension i just mentioned you can right click it and say open db or open database and down here you will see the sql lite explorer you can open that up and you'll see now that we have orders products and users so that's what this auto migrate does it takes our structs creates a table out of it in our database and yeah that's pretty much it it's quite simple it's quite elegant to do as well so i'm just going to close that but that's really it for our database now we can actually get started with creating our api endpoints so to get started with our api endpoints the first thing i'm going to do is create a new directory in our project and i'm going to call this roots within that i'm going to create a new file and this is going to be user.go so all of the endpoints in here are going to be related to the user so creating a user reading a user reading a list of users updating and deleting so let's go ahead and write package and then roots and the first thing i'm going to do is let me first just go ahead and close all of these and just leave the main.go and the user models file open so i'm going to go ahead and create another version of user so another struct for user and i want to have the id the first name and the last name and the reason i'm doing this is a from what i understand is that it's a good way for readability to kind of separate the model from like and this will be more like our serializer and it's quite nice how is how you can do this in golang so i'm just gonna say user and then it's going to be a struct it's going to have an id and i don't want to have the creator that i'm not really interested so i'm going to leave the create that part out but it's going to have the id this is going to be an unsigned integer and we'll just give it the json format of just id in lowercase next i'm going to have the first name this is going to be a string and the jason field name for that is just going to be fast underscore name then last name string json and then last underscore name now you can see how similar it is to the user model i've just separated it out as it's just easier to kind of use this as our serializer if you're familiar with serializers in when it comes to restful apis so i'm just going to leave a comment to say that this is not the model user um see this as the serializer and you'll see why in a second the next thing i'm going to do is actually create a function that will create this so we don't have to keep on building a struct by hand and what this will do is is a create response user and this will take in a user but it will be a model so from models.user and this will return user so it will take in the user the user model struct as a as an argument and return this user struct here i mean i could change this as like user serializer if i wanted to but it's fine to just do that as user here but you can go ahead and name that if it helps so this will just return a user struct now it would be if we were to do models then we'd do models.user but we actually want to use this struct here so what we can do is just say user then we can pass in the id as being this user so this one here um actually it might be best to just name this as user model so this will be user model dot id we'll have the first name and that will be usermodel.firstname and then lastname which will be a usermodel.lastname and now we'll use this as our helper function when we create our endpoints so the first endpoint i want to create is one for creating a user so we'll say func and then create a user and here we'll just say we'll create just like we did in main.go so the beginning of the video we created our welcome so we'll have this context pointer so fibre.ctx and you can just do that here we can say fiber hit enter so it automatically imports it dot ctx and this will return an error so all endpoints or yeah all endpoints that we write in using fiber will always return an error so the first thing is let's create an empty variable um or object of models.user and then let's go ahead and look at our the body of our post request so we can say if the error does not equal c dot body parser and then we can just pass in a pointer to user so this user over here and then we can say if um the error sorry if error we assign error to the value here so if we get an error back from that so if it's not nil um then we can return an actual http error so status set this as 400 and we'll just say that the error is error.error so what this does is whatever we pass in in our request it will map that input to this uh user so the model instance in this case um we're not doing any other form of validation i mean you can put in as many fields as you want there are other libraries that help with validation um but i'm not going to cover that in this video for this it's just going to make sure it'll just map like the the first name to the model first name the last name to the model's last name the id doesn't matter as that's automatically generated so when you're creating user you don't actually pass in the id or you don't put that in the body post request next we'll say database so that will automatically be imported as well we'll say database dot database dot db so our actual database instance and then we say create and this just creates an object and then saves it into the database and we'll pass in our user so a pointer to our users so ampersand user next let's create our response and we'll just say response user and we'll call the create response user and from there we can just pass in user and then finally we can return that response user so we can say c dot status first of all just to say that it's successful status 200 and then we can jsonify our response user so that's it that's our create user endpoint we can go back to main.go and actually add this in and what i want to do in main.go is actually create a function that will set up all our endpoints so we can say func set up roots so set up roots like that we'll take in the app which is a fiber are pointed to the fiber app it will not return anything so we first have our welcome endpoint which we can just say as app.get and we can just add in four slash api and then just welcome next we'll have all our endpoints for our user so user endpoints say app first of all we have a post one so we'll say forward slash api forward slash users and then we'll say call roots dynamic routes yes roots dot create user so now down here in our main function we can say we can get rid of this and we can just say set up roots and just throw in the app cool so now we have our two end points we can go ahead and test this out so back in postman i'm going to say users we cannot get anything um actually on top of that i don't think this server is running anyway um so i'm just going to type in you can again you can do go main go run main.go or if you're if you have the kind of hot reloading just type in here so just give that a second for it to build okay so yeah it's running successfully now i can go ahead and do a post so switch that to post and then in the body let me just shrink this um the body we want binary it's odd that it's so zoomed in for some reason zoom out yep so binary um [Music] post or raw sorry so go into raw and then just set this to jason and we can say first name we'll set that to harry potter or harry and then last name we'll set that to potter if we send that now we get back our id id one so that's automatically created for us like gorm handles all that we have our first name and our last name so now if i go back and if i run the database so if i open database using the extension um just close that if i open this if i click play on users then i can see here in the right that i have uh the id which is one the created at so the exact time in which it was created and then first name and last name so that's it for creating a user um which is fairly simple we only wrote a few lines and yeah worked out fine so next i'm going to go ahead and get create another endpoint and this endpoint will get all the users in our database so we'll say funk get users so plural c and then asterix fiber dot ctx and this of course will return an error okay so the first thing is that we want a list of users from our database so what we can do similar to what we did here apart from we want to specify that it being a slice rather than a single object we can say users and then we will say square brackets models dot user and then curly brackets next we can query the database so we can say database dot database.database.db dot find and we can pass in the users variable that we have here and notice that what we're doing here is actually um we're taking this empty user's slice and then we are uh throwing it into this uh function here that looks for all the matches like gorm handles all this under the hood which is very handy as it's just saying okay find everything that matches with this user model throw them into this users so now we technically have a list of users and next we can go ahead and say that the response users is going to be a list of this user struct here so our serializer so square bracket user like that and now we can loop over each of our users that we get from our database and we can kind of create our response call this create response user and then chuck them into this slice here so we can say four and then underscore because we don't care about the index we'll say user we'll say range over the users so for each iteration what we want is to create our response user which will be create response user throwing user response users so our list of user response our users that we want to return we will say append response users so that just autofilled it for me and then just pass in response user and then finally we can do return c dot status 200 and json and then response users so that's how i get user's endpoint and go back now to main and in our setup routes we can say app.get and it will be the same endpoint as the one before so api users will say roots dot get users so as i've got air running it just reloads it for me again if you want if you don't have air if you don't have this whole reloading function then you can go ahead and just run you have to restart the database and type in go main go run main.go but i'm going to go back now to this i'm just going to go ahead and actually save this in a collection i'm going to call this um fiverr.com in this collection here just so it's just easier to kind of find these later on and this is create user just save it okay let's open up another tab http api users this is just a get request send it we get back a list of users as we only have one we get harry potter so let's create another user and see if we can get back more than one say this is john doe send it so now we have our response in our create user and if we go back to our get users and we call this now we get back two users we get id we get john doe and harry potter so i'm just gonna go ahead and save this again now we call this get all users save it so yeah that's that one let's go ahead and create a few more um so we want to get back individual users now to do that what we need to do is first of all create a a function to just get user and this is where it will get a bit interesting compared to the last few endpoints that we've created so as always pass in a argument or parameter of context which is a pointer to fiber context and then it will return an error and when it comes to a individual user what we'll do is actually add another forward slash after users and then specify the id so maybe one or maybe 34 and we want to grab that id so in order to do that just say id and error is going to be set to c dot params as it's an integer we could say primes int and we'll be looking for id next let's create our user so our user and then models dot user and let's check to see if we get an error back first so if this if we don't actually pass an integer so it will raise an error then we can say if error does not equal nil then return c dot status pass in 400 of the error and then jason we can just put something like please ensure that say id is an integer next we can go ahead and actually fetch our user now to do that we're going to go ahead and create a helper function and this is going to be called find user it will take in an id which is an integer and it will take in the user pointer that we want to set this to so it'll just be models asterisk models.user and this will return an error and here we can say database.database.db and then find so just like we did in get users we did this find and then a list of or a slice of users um in our case we don't want a whole list back we want to filter it based on um the id that we pass in so we can just say something like we want the user amazon user we can set the query so we can say where id equals and then question mark and we can say the question mark will be filled in by the id itself next we can say if the user does not exist so all ids begin with one so they can never be zero so if we have user dot id that equals zero then we'll return errors dot new and then we'll just say user does not exist and then finally we'll just return mil okay so down back at our get user we can say if the so we can call this we can say if error and then set that to find user we can pass in the id and then the user itself which is a pointer so ampersand user say if the then have our conditional error does not equal nil then we can just return c dot status say that's a 400 and jason and we can say error.error like that as that error will just be user does not exist so okay if that all passes then we can say the response user is going to be create response user and then just user and then finally we can add c dot status pass in 200 and then json response user so what's happening is when we do this find user we're passing in this user variable here so as a pointer in here it will query for that user if it exists it will then associate whatever it finds with this user variable that's why we can do this create response user user as this now has a variable if it didn't then we'd get an error back and we'd get the message status of 400 along with our message saying user does not exist so let's go ahead and add that we can go ahead and say here app dot get we'll say forward slash api users and then forward slash colon id and then roots dot get user so this id here this id part after this colon is what's read here on line 57 params in find id and we can go back now to postman we can make a request of http users and then pass in the id so we know one exists and we get back harry potter if we do two we get back john doe now if we try something like three send we get user does not exist so all working fine and we also get the status of bad request and let's go ahead and save this we will say this is get single user save it and yeah so let's now move on to our update which takes in a bit more so what we can do is say funk and then update user this again we'll do the fiber dot ctx return an error and let's do what we did here so we can take actually a couple things from this me take all that um actually i think we can take all of this to be honest so from the id params int all the way to find user the whole if statement there let's paste it in so we're getting back our error as we want to update our user we need to actually fetch our user so we can do now is create our struct and remember we cannot edit we don't want the user to be able to edit the id the id is set by the database it's something the user should not should never really care about they can only change their first name and their last name you can say update user we'll set this instruct and this will just have the first name string and we'll say json double quotes first underscore name and then we'll just add another one so last name we'll say last underscore name so yeah that's our update user struct so we only want the user to change their first name and last name what we can do now is create an instance of this struct so var update data will be update user next we can go ahead and pass it so we can say if pera does not eat or if error so set error to c dot body parser not body for body parser and we can pass in the pointer to update data if the error is not nil so if there is an error we can just say return c dot status give this data say 500 and json error.error so if this all passes then we have our update data associated to this we have first name last name so now that we have that we all we need to do is say user so the user that we get back from our database when we do this find user user dot first name equals update data dot first name user dot last name equals update data last name and then finally we can save this we can say database dot database dot db save and then just pass in a pointer to our user so that's now successfully updated it we can then just create our response user by saying response user is going to be create response user and we can just pass in the user model itself and then just return c dot status of 200 dot json and then pass and response user so yeah that should be our update so we can go back to our uh main.go file in our setup roots we can say have dot put and forward slash api for users and we want the id included as well and we can say roots dot update user so now once that's built we can go back to postman let's create a new tab http users let's do harry potter so this is going to be a put request in our body it's going to be raw and it's going to be json we can say that the first name is going to be larry and the last name is going to be let's just say snape okay so let's send that and we get back id1 so where harry potter was once id1 we get back first name larry and then last name snape if we go to our get all users we send now we get larry snape rather than harry potter and we can also do single user at id one to send and we get back to larry snape so updating is successful i'm just going to go ahead and save this tab call this update user cool so the last endpoint for our user is going to be the delete user and for that let's go back to our user.go for roots and we'll say func delete user c so pointer to fiber.ctx and then error and again we can kind of pretty much copy what we have in this here so we can take that um actually we can take all of this again so we get back a user if it exists so and that's set to this user here and then what we can do is actually delete it and with deletion it can it could return an error so to do that we can say if error equals database dot database db dot delete and then we can pass in our user so we want to delete this individual user the error error does not equal nil so if we get an error back then we can just say return c dot status and we can set this to a404 dot json and then we say error otherwise we can just send back a message that basically says c dot or return c dot status 200 and say send string successfully deleted user so that's our deletion we can go to our main.go file and we can add that in we can say it's pretty much the same as this apart from instead of put it's going to be delete and then here we'll just say delete user so just wait for that to rebuild head back here let's create a new tab http uses let's delete larry snape so we'll send that and we get successfully deleted user so if we go back to get all users send we don't get back we don't get uh larry snape anymore um so yeah that's our deletion so that's really our user uh endpoint so it covers all the basic crud stuff um in the next uh part now we'll just go ahead and create our order um roots so just know our older our product roots um which is pretty it's very much the same as our user and then our order one which is will take into account our foreign keys so for our product endpoints um we're going to be doing something well pretty much what we've just been doing for our users so in our roots directory let's create a new file and we'll call this products dot go and for that the first thing that we need to do is actually state the package name so package and then roots and then let's create our product struct so pretty much like our serializer that we did for our user and for this we want the id which is going to be an unsigned integer and we want the json which is going to be and just id next we want the name of our product which is a string json for that we'll set that as just name but lowercase and then finally our serial and number string and jason oops in backticks so jason and serial underscore number so yeah that's our product serializer again treat this like a serializer this is not the model and down below we can add our create response products so funk create response product this will take in a product so product model we'll call it and this will be of models dot product and then this will just return the product struct that we just defined over here and all we can do here is just say product this will have the id of product model dot id we want the name which is the product dot name and then we just want the serial number which is product dot serial number okay so let's create our first endpoint which is to create a product again very much same as our create user so i don't really want to repeat too much for the sake of time so a ctx return error and then we'll save our products and then models dot product we will do if there is an error so set error to c dot body parser we will throw in our product um so a pointer for that and then if there is no error obviously this will then become a this will be set to our product variable or object here if there is an error um then we want to deal with that by saying return c dot status with a 400 and json being error.error next we'll just say database dot database db dot create and we'll just pass in our product so like so and then we can say the response product is create response product and we'll just pass in our product and then finally we can do c dot status 200 and then jason just say response product so that's our create product let's go ahead and add this now in our setup roots function in main.go so we'll say product and points say app dot post this will be forward slash api forward slash products roots dot create product so once this has reloaded we can go back let's just save this one here we'll call this delete user create a new file a new tab http set of users to products we'll do a post this takes in a name and a serial number so it's jason you can say the name which is going to be say ben and jerry's cookie dough ice cream the serial number will just say serial underscore number and we'll just put in a bunch of random numbers send this and what we get back is the id name and serial number okay so again very similar to how we did users let's go ahead and do our get products so here we can say funk get products c and then asterisk fiber dot ctx error and this will have a list so products or slice sorry we'll say models dot product so a slice of product structs from models database dot database dot db and then we'll find them so find all the products and then associate with products the response products will be a slice so response products a slice of our product struct and then let's loop over them so four and then product um range and then over our products and we'll say our response product is going to be create response product will pass in our product then we will add that to our response products so append response product oops there we go just get rid of this bracket there and then finally we can just return c dot status 200 and then just add jason and then our response products so that's how we get uh products we can go back and add them all in in a second let's just add our endpoints in first so just like we did with our user roots we had this find user function or this helper function that we created this find user we can do the same for products so i'm just going to copy that go back to products paste that in instead of find user we'll say find product so we'll take in our product instead of using here we'll just call this product then we'll have a product here and product id there and then as our arrow will say products does not exist oops cool so that's our find product we're getting a warning as it's unused so let's go ahead and use it so for our user.go we did our get user we can do the exact same let's actually copy this and then just change it for our product so we'll say get product and all this is fine this is going to be products and we'll say models.product um so this part's fine we'll call instead find user we'll say find product and we'll pass in our product create response this will be product and create response user will not be instead be create response product and that's about it so yeah that's our get product again we'll add this in a second let's just add in the rest of our endpoints because this is somewhat of a repeat of what we've already done with users so our update user actually just copy in both update and delete so just down here so for our update user instead we'll say update product and for that we pretty much have everything in place we just need to change some stuff some models product this instead will be product find user will not be the case we'll have find product and then for our update user instead of update user we'll have update products and then we'll have name this here being name and the serial number so just serial underscore number and instead here we'll have update data but this will be update product so destruct and then so this is all fine instead of user here we'll say product and then we'll just say name is set to the updated name here we'll have product instead of last name we'll have the serial number and the updated serial number and then we save our updated product we create a response so create response product this will be a product and there we go so that's our update now we can look at our delete instead of delete user we want delete product and again product product we will call find product pass in the product then here we'll say delete the product itself and successfully deleted products so yeah that's our endpoints now for product we can go back to main.go and let's add them in so we'll say app dot to get and this will get all of the products roots dot get products then we'll have our products for our single product so id and instead we'll have get product then we'll have our um our put which will be instead of get product we'll have update product and then finally we can just do delete so forward slash api products and then column id roots dot delete product so let's go ahead and test all of this out just very briefly so back here this is our let's just save this as create product and let's actually go ahead and create another product so we can have a few to mess around with so we'll say instead of ben and jerry's ice cream we will say jordans give it a code send next let's give it something else we'll say macbook give it a code send so let's go ahead and first test our get all products so here send and we get back all the products should save this as get all products add another one so this will get back in individual product so we'll say four slash one so the one with id one we get ben and joe's cookies let's say three we should get back macbook if i try a different one we get back product does not exist so cool that works fine so we'll say get single product and just for the sake of it let's test our put so http products say our first one so our ben and jerry's one let's change this so that it will as it was cookie dough let's change the flavor flavor of it so we'll say name we'll say ben and jerry's brownie we'll change the serial code of it as well so serial number actually and we'll just add something else send it and we get back id1 so before it was the cookie dough but now it's ben and joey's brownie and we get back our new serial number that works fine let's just save that uh update product let's add another one so i'm just going to close some of these tabs just to make some room but let's delete something so this is going to be a delete it's going to be a product so our first one so this is now ben and jerry's brownie let's send it and we don't get anything back because i'm writing right products are products so i put product it should be products id let's try that again just wait for it to build send it and we get successfully deleted product so all good um and if we actually go back and get um all the products so get all products here send we just get back ids two and three so that's it for when we want to um so all the crud stuff regarding our product again very similar to our user so our user roots so apologies if it seemed quite repetitive but the next part is to create our routes for our order so when creating an order reading an order etc we will not be adding update and delete because i think from a domain perspective it's it wouldn't make sense to update update to delete an order maybe i mean depending on the kind of order you may want to update it um but also just be very repetitive what we've done already um so yeah we'll just focus on actually like handling these foreign keys etc and how we would work with that but yeah so let's go ahead and create our order roots so for our orders endpoint let's create a new file within our roots we'll call this order dot go and as before let's first of all set our package so package uh roots and then let's create create our like struct serializer so type order strut and then we'll have our id which is an unside int and this will have the json in backlit so just under this uh lowercase id we'll have the user and we want to the way in which we want our order to look so for our endpoint i'm just actually gonna just comment it up here or just yeah just write it quickly like this so we'll have our id which is going to be something like one then we'll have our user and this is going to use the um user struct that we built in here so this guy let me just shrink this so this struct here so i have the id first name and last name so id like 23 the um uh what is the the first name which could be say bob marley bob and then last name like molly and then we'll also have the product that you've ordered this will just look like i mean id 24 let's say the name is a macbook and the serial number to be add something like that so this is what we want our serializer and like in this kind of format so let's continue so user user so the user struct that we defined in our user root so not the user model um this will have a json of user then we'll have our product and again so product the one that we defined in our product roots and the json product like that and then finally we will have our created at and this will just represent the time in which the order was placed so time.time and we'll write this as uh order date cool so again let's create our create response order and this is going to be slightly different so create response order what this will take in is first the order which is going to be of models.order then it's going to take in user which is a a object of our user struct from our user roots and then product which is going to be product so this is just going to return order and so we can just say order and then id which is just order dot id and then we can also add the user so user which is just the user that we pass in here we want the product which is just the product like that and then finally we can just add our created app as well so we could say created at which is order dot creator that and that will just be our order date cool so let's do our create order first so we'll say funk create order and we'll say c asterix fiber dot ctx this will tell an error and what this will file what we will do first is actually get our object so var and then order models dot order first let's do our check so if the error so set error to c dot body passer will pass in our order so map all the input that we do to this model instance and if there is an error then we'll just say return c dot status of 400 and then the json which is errod cool so that's that one and i know we're not doing a lot of validation at all well not really a lot of validation but um for this we want to make sure that the user that we associate with our order and the product that we associate with our order that they both exist so we can do that by simply by saying the error will be set to find user and this will take in the user referrer that we get from our body that's from our request and we'll pass in our user ins our object which we need to create up here so we'll just say user or var user and then models dot user and then back here we can say the error does not equal nil then return c dot status 400 in fact let me just copy this yeah so that's our user so if we get back an actual user that actually exists in the database then we'll continue on to the product and we'll just do the exact same thing as we did with user so models dot product and we'll just copy all of this and we'll place find user with find product order dot product referrer and the product and that's about it that's pretty much our validation what we can do now is actually create our order and add it to the database so database or database or db create will pass in a point to our order and then let's get our response user which is going to be create response user we'll pass in our user we'll say response product set that to create response product and then response order which is just going to be create response order will pass in the order itself so the model instance the response user and the response product and then finally we can just return a c dot status of 200 and then json response order let's go ahead and test this out now so as soon as it's built so we have let's first go ahead and check um what we have so get let's save some of this stuff oops what was this so this is actually delete products okay close that just close all of this so this one actually we can call so we can say get all our users so we have one of id2 we can use that user and so we can also just get our request as well so get all products what products we have for ids so two so we'll say that john doe has ordered a pair of air jordans and actually we just need to add this to our main.go so we'll say order endpoints app dot post say forward slash api and then orders roots dot create order and back here let's go to the endpoint so http api orders this is going to be a post we have a body set this to jason so first of all we need the user underscore id so user let's go id and notice that we're not putting user referrer that's because in so here we just put um like user and product uh or not here sorry in the actual model because we map it against the model itself so this var order and then body parser we actually pass in a pointer to the order model so we have this product referral which is just product id and user id that's why we set it as that here we'll set the user id to be 2 so john doe and the product id to be i think the air jordans is also 2 as well let's set that to to send that and we get back the response which is our order so id of one the user so john doe the product jordans along with the serial number etc and the order date so the date in which time and date in which it was ordered which is nice so we can now create an order let's create something so that we can get all of our orders down here we will say get orders so funk get borders and it will say fiber dot ctx it will return an error and so we'll say orders is going to be a slice of models.order and then we want the database to find all of those find all of our orders so pass in understand orders and then we'll have our list of response orders which is going to be a slice of order so we'll loop through so for order range over orders and we'll say var user and then this is models.user we want the var product models dot product because for each order we need to fetch both the user and the product so then let's do a database query so database.db and then dot find we'll pass in our user the id so id equals question mark and the the orders user referrer so we'll do order dot user referrer which is actually the user id so we can pass that in and that will then find a user of that id and associated with user if it exists we'll do database.database.db find and we'll do the same for product where the id equals order dot product referrer so now we have both the user and the product now we can create our response order which is going to be create response order we need to pass in the order itself we need the user um that we created here and then we also need the it's interesting that the ah we need the response so create response user we can just do it in line like this and create response product which will also be product that so now we have a response order we can then append it so response orders append and then add in the response order and then finally we can say return c dot status and then 200 and then dot json response orders so back in main dot go we can add this we can say app dot get forward slash api orders roots dot get orders just wait for this to rebuild now back over here let's just save this as create order we can call http orders we can get it do a get request and we get back all of our orders in this case it's just one so yeah that one works the next one and pretty much the final end point is getting an individual order now we can do what we've been doing before so we can say funk and then we'll create a function that will find an order based on the id that you provide which would be of type integer and the order which is a pointer to the model object to the model struct this will of course return an error so we say database.database.db dot find and then a pointer to order where the id equals whatever id we pass in we can say if the order dot id equals zero then we can just return errors dot new order does not exist if it does however we'll just return nil so that's our find order so now we can do a create a function or our endpoint to actually get an individual order and say func get order the c the context so fiber dot ctx return error we have the id and the error which is c dot params in get the order so order and then models order if the error does not equal nil then we can just say what do we have in products let's just copy this so we'll say if there is an error please ensure the id is an integer then we'll do if error and then we'll do the find order and we'll say id and pass in our order pointer here and then error does not equal nil and we can just return c dot status of 400 json will have error.error next let's go ahead and get our users a user and product for our order so far user user models of user for product models dot product say database dot database dot db dot fast so this is just a query for the give me the user of with the id of whatever user referral we have in the order so we can just say understand the user and then order dot uh user referrer we can do the same for our product we could say product and then say product referrer oops like so we can create our response user and say create response user throw in user we will create another one so response products say create response product pass in the product and then we can create our response order so response order create response order and then pass in the order the response user and the response product and then finally we can just return it by saying return c dot status and then 200 dot json and then response order and there we have it so back in our main.go we can go ahead and do app dot get forward slash api and then orders and then the id so colon id and then roots cree um roots dot get order and that should be it this is finished building let's go back let's um do a get to that so we'll say http um i think it's down here orders and we'll save the id one send we get it back we try something else we get ordered does not exist one works let's create another order um so we'll say what other products do we have send we have macbook so let's say john doe orders a macbook i think we've had these three there send now we have a macbook we can get the order of id2 send we have macbook and yeah that's about it um i mean you can definitely of course like feel free to build upon this um kind of change up the user's uh endpoint to show how many orders they've requested but yeah there's quite a bit of messing around you can do here or maybe look into validation but this pretty much covers the basics of getting up and up and running with fiber the golang web framework with the gom so the golang orm and yeah how to kind of make use of um like or creating a crud api and taking into account foreign keys etc but as of that that's about it for this tutorial the uh github or the source code for this project is of course in a link in the description below so feel free to yeah mess around with that and just experiment with it um but other than that if you enjoyed this video please leave a like and also subscribe it would mean a lot um but yeah have a wonderful day have a wonderful month and yeah stay healthy and stay safe and i hope to see you in the next video [Music]
Info
Channel: rithmic
Views: 1,344
Rating: undefined out of 5
Keywords: Golang, Go, GORM, Fiber, Go API, API, Web Development, Go Fiber, Go Gorm, Database, SQL, Programming, Computer Science, Software Engineering, Programming Tutorial, Go Tutorial, Golang Tutorial, REST API, RESTful, Programming for Beginners, Fiber Gorm, Golang Fiber Gorm, Go Fiber GORM, GORM tutorial, API Tutorial, Software Engineer, Computer Programming, Fiber Tutorial, Web development tutorial, Postgres, SQL Tutorial, Golang Web development, Go web development, api, api tutorial
Id: dpx6hpr-wE8
Channel Id: undefined
Length: 88min 29sec (5309 seconds)
Published: Sat Oct 16 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.