How To Build A Complete JSON API In Golang (JWT, Postgres, and Docker) Part 1

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
I am going to teach you how to create a complete Json API project in golang we are going to build a bank we are going to transfer money we are going to create accounts and everything is going to be authenticated with Json web tokens we're also going to use postcards we're going to hook that up into our handlers and we are even going to test the complete project we are even going to test the HTTP handlers and after that when everything is done we are going to dockerize this project so we can hand that over to our devops team and set Margaritas at the beach all right so the first thing we're going to do is actually find a good name I think we're going to call this go bank because we're going to create a bank API right so we're going to say I like usual we're going to do this completely from a blank page we're going to say amcader go Bank we're going to CD and go Bank like this and then I'm gonna use vs code with some Vim Shenanigans but you could use any editor you like so let's create a couple of files the first thing I'm going to do is a make file uh the make file is being used to basically bootstrap some of common tasks right that's what I'm always doing that's a good practice to have so I'm gonna say built which is going to be go build minus output and that's going to be in the bin go bank right the binary it's going to be called go Bank then I'm going to say run which will build first and then we're going to say dot slash Ben go Bank and then I'm gonna say test because we're going to test our application we're going to test our HTTP handlers if everything is working fine and my hands are so cold we're gonna say uh go test minus verbose and we're going to say dot everything in our project right and the verbose stands for more logging if you're in the test right so I'm gonna always do an at before these commands so they are not being printed out the next thing we're gonna do is can I do um like this I'm gonna make a main.go file and I'm going to say package Main function main which is going to be our entry function and we're going to say fmt parent Allen and we're going to say yeah buddy with an exclamation mark um yeah so let's test this real quick uh I make run make run and it's telling us that we need a mod file so we're going to make this real quick quick we're going to say go mot init github.com and DM slash go bank and if you're following along you can actually use your own GitHub handle or whatever it's all good right so now we have a mod file let's do make run once again and now we see yeah buddy so everything is ready to go the first thing we're gonna do is create our API uh packed or API file where we're gonna create an API server and or handlers right so it's going to be package main there is no need to uh make other packages because a lot of big mistake a lot of beginning goaling Gophers are doing is to split everything out in different packages in different folders but that will cause a circular dependencies Cricket then [Music] um if you can imagine so just keep everything in your main in your main file in your root file and if needed then we can split things out right but only if needed we're going to say type uh API server it's going to be a strict we're going to give this a listen address a listen address which is a string like this and of course we're going to add our DB or database which is going to be a post class database in our application and we're going to add that in later on right but first of all we're going to start with the basics we're going to say uh Funk new API server which is going to take the lesson address which is a string and it's going to return a pointer to our API server and we're going to say return the pointer to an API server and the listen address is going to be the let's add this right oh it's going on here all right so the first thing we're gonna do I'm gonna move this mouse cursor out of the way or handlers right so we're gonna do something like Funk s uh API server I'm going to see handle account because we're going to handle accounts we're going to create accounts we're going to get accounts we're going to delete them and we're also going to transfer and in golang it's a common practice to prefix these things with a handle uh it's a community it's being appreciated by the community right handle account it's going to be an http response writer like this and it's going to take in an HTTP request and it's going to return an errors right and we're gonna return null to satisfy the compilation what's going on each handle account W yes of course we forgot the r for our request all right that's nice we're gonna copy this function like this and we're gonna make handle uh get account I'm gonna copy it again we're gonna make and handle um create account and maybe you should also do a handle maybe delete account or something yeah like this and also a function for transferring money so we're going to say handle transfer like this maybe that sounds good all right so we are not going to use any extensive framework like gen or bigo or Fiber we are going to try to do as much or self because a lot of people are so used to in installing so much packages that they have actually no clue how these things work under the hood although it's a good thing to install packages to save your time but for most of the cases they are not needed right you're going to have a bad time and prediction if you need to if you install a package that's not good supported or that has a bug and you need to update your whole stack that can be that can that can cause a lot of issues I'm not gonna lie and in the industry especially in gooling a lot of these if you're going to prediction that's what I'm actually going to learn you is to write code you should you actually gonna write in in the company you're going to work for or in production instead of making these tutorials with all these Frameworks you actually never gonna use in your day job right um so API server the we're gonna make a function to to start or server up so we're gonna say s API server we're going to say run uh what's going on here then key binding is not working all right so run and now actually we're going to install a package and we're going to make we're going to install a minimalistic package and it's going to be go get up.com gorilla mix right because golang has a good support for HTTP and to handle all our requests but it's not provides us a way to um get the parameters uh we could do that but then we need to make our own drag expression and all that stuff and that's something we don't want to hassle with so we're going to install mix right it's as old as the streets it's basically gorilla mixes is there from the beginning from even from the beta I think in golang so that's a very very long time that package is stable as yes all right so run we're going to see uh first of all we're going to see a router that's going to be a Max new router and I don't think it's going to import it nope sometimes he has code but that's no problem we're going to do it manually now we're going to say getup.com gorilla mix like this and it should be all fine and I'm going to say routers uh handle funk handle think like this and we're going to say slash account of course and then we're gonna say s handle account like this and of course it's not gonna work right we get we got this red compiler warning and that's because handle funk is actually taking a pet and an HTTP Handler heat right and our function looks like it but it's not the same right if our function if you go to API we can see our function we have is basically the same but we are returning an errors so we need to convert our function into an HTTP Handler that's the first thing we need to do so uh because you could leave the errors right you could say hey then we just use an HTTP Handler func without the error but then we need to then we need to handle the error inside of uh or handle it and I don't like that it's it's it clutters up it's it's no Gucci so we're gonna transform this function so what you're going to do first is we're going to make a type and this type is going to be an API func right and this API thing is basically the thing the function signature of the function we are using right and that's going to be a function uh HTTP response writer response writer and a pointer to an http request and it's going to return an error that this is our function right this is the function signature we are using here then we're going to say func make HTTP handle func uh handle think like this and this is going to decorate or API Funk and to an HTTP Handler function if that makes sense so we're going to say uh it's going to take an F which is an API Funk and it's going to return an HTTP Handler Funk Handler Funk like this right this and if you see Handler's phone let's let's take a look at this right so you could see this is a Handler Funk which is basically just a response writer and a request but our API func is basically an adult right so we need to just uh make sure we can convert these two and we're gonna say uh we're just gonna return a function which is going to take a response writer http response writers it's going to take an odd which is an HTTP request and it's gonna not return anything so we're going to say here we're going to say if it is an errors uh and we say or function right this this F is basically one of these functions here which should turn an error and we're going to catch that error here so we're going to say if our function with the response writer and the request and the error is not nil right then we basically gonna handle the error fees okay that's what's going to happen of course we don't have any way to handle our error yet so we're going to make that but the first thing we need to do is find a way to write Json right because we are gonna make a Json API so we're going to make a simple function and that's going to be Funk uh write Json and we're going to take in the W which is an HTTP response writer response writer you're going to take in a status which is going to be an integer and we're going to take a value which is any and it's going to return an error so it's nice compatible with r function signature so we can just return this right so the first thing we're going to say is W writes header the status right so we're going to say write the status we give it in the header right and then we're going to say W uh I think it's headed set we're going to say content type I think it's like this not quite sure I'm going to say application Json and then we're gonna just return very simple Json new encoded because we're going to encode it into the response right because that's a writer right I think new encoder takes we will see later on I will show you and then you're going to say encode and we're going to encode anything and that's the V and and that's done so if you let's take a look at a new encoder you see it takes in an iodo to write it right are you the writer and luckily or response writer s and Iota writer it implements the right interface right cool so now we could uh let's make an an API Adder type real quick we could say type API errors which is a structure like this and we could say yep there is an error and that's going to be a string like this and then we could say here we could we cannot return because um a normal handle Funk does not return anything so we're going to just say right Json we're going to put in the response writer we're going to put in uh for now you could say a status bad request Maybe a battery Quest and of course later on what we could do is uh make an assertion on the error we we returned from our handlers and then we could basically switch based on the error and return the appropriate status code right but for now we're just going to say about requests and we're going to write uh anything so we're going to say we can we could write our errors like this and then we're going to say here that the error is going to be the ad we give it but we're going to say Adder so we have the string right so that's being done and now of course we have this error still so now we need to wrap this now we need to transform this function into our HTTP Handler into a common HTTP Handler and we made this function ourselves we're going to say it make HTTP Handler func and Rapid in and I think I made a little mistake make HP handle funk like this boom all right so now everything is working and then of course we're going to say here uh HTTP listen and surf and we're going to say the S listen address we're going to serve on the address we give it on the port we give it and then we're going to put in the router as the Handler and listen and server it's listen and serve rather like this all right and maybe you could do a login you could say log uh print a line maybe and we could say um Json API Json API server running on ports maybe a space heat and then say that it's going to be the listen address like this all right do we need something more for now I don't think so maybe we could actually try or uh oh yeah what we could do here right so the problem is with a mixed router is that we cannot specify if it's going to be a get a post of a put or a delete request so we need to basically handle that ourselves and that's why we made this handle account so we're gonna do that real quick we're going to say if the requests method equals get then we're gonna basically a return as get get handle account handle get account rather like this and then we're going to copy this a couple of times I'm going to say if the method is post gonna say you're going to create an account right uh what's going on here I think I put my yes little mistakes a little there are no mistakes only little happy accidents right methods posts gets uh what do we need maybe delete right so we're going to say delete and that's going to be the lead account which we don't have for now and then we're gonna see if all of these cases no need to use an else you could use a switch a you are the painter of your drawing you are the creative artist you are the Bob Ross of your program you can literally do whatever the you want but I'm gonna use this thing a switch is maybe even better I don't know um it could be maybe even better hey it works right so we're gonna say adult F we're going to say methods uh I'm not supported or something not allowed Maybe not allowed and then we could say something percent s and then say the our methods and everything is fine can we actually test this no because we need to open up uh our main file like here what's going on here yes now I'm going to say that the server is going to be a mu API server no typing at all but it doesn't matter I'm going to say for 3000 is the way to go and now we're gonna say server run and delete this and maybe we're gonna you see sometimes vs code maybe I'm too fast I don't know you tell me let me know in the comments uh go back gonna say make run all right and we see Json server is running let me see if I can open up a local host 3000 we say page not found that's perfectly fine because we don't handle uh the Slash and we're gonna say account and then we have um a white screen so maybe we could do something better we could uh make types we could say new file types.go I'm going to say package Main like this and I'm going to say type account which is a strict we're going to give this an ID I guess it should be an end then we're going to give this a first name which is a string I'm going to copy this into last name maybe a number a bank number right which is going to be in an INT or maybe an N64 and a balance maybe right have you gonna change this upright it's just for uh for demonstration purposes all right so we have this account do we need new account yeah let's let's make a Constructor real quick we're going to say new accounts uh which will take in the first name and the last name and they are both strings you could do that in in Google and you don't need to specify if you're all specifying strings you can actually specify string as a lost argument so it knows the boat those those both arguments are being a string those both types right and then we're gonna return a pointer to an account like this I'm gonna return an account and we're gonna see what's going on uh we're gonna say that the ID is going to be a rant and and I'm gonna say maybe so many IDs we can choose from the first name is going to be the first name we give it yes and of course the last name is going to be the last name you give this and then we're going to say that the number the bank number and that actually should be maybe a uid or something a uuid we're going to use but for now I'm going to make it an N64 we could do whatever we want whatever we want if you want to have something different a make it as crazy as possible right um like I mentioned your Bob Ross as long as you don't beat the devil out of your keyboard it's all fine so number we're going to say again right we're going to make it a rant and uh n and let's make it even bigger like this I think this is actually too big already oh wait this is a rent and Returns what does it return an end actually that's bad news so we're gonna convert this to an N64 right and the balance of course that's going to be zero so we don't need to specify this because Google Ang will automatically initialize all default values to the default value which is basically zero uh for an N64 right uh yes yes yes yes yes so now we're going to go to our API back which is actually here but hey um let's let's make a mock real quick and we are going to use a postgres as a database it's we're going to make a complete uh prediction prediction created project but hey we need to build this up right we need to build a tension uh we need to start from the beginning we need to learn how to walk before we start sprinting handle get account so we could do something like this right to give you an idea how this and I'm my hair is itching but I don't have air so something is wrong uh let's say we're going to say that the account uh is basically something like a new account like this and you're going to call this uh Anthony maybe with a capital n capital a Anthony and the last name is going to be GG and then we're going to say something like return Json new decoded and we're gonna taking the response write it and then we're going to say decode me uh this actually we don't need to we can uh oh what are we doing we could just do return right Json right return right Json we're going to say W uh http that is okay like this and I'm gonna just put in the account look at this and if we run this again clear make run and we open up our thingy and um we do slash then we see that we have a nice Jason I'm not quite sure about this I think I need to install the Json plugin for um for my browser and I will do that in the next episode so you see we have the ID the first name is Anthony the last name is GG the number is this and the balance is zero I'm poor and broke all right so something we need to we need to realize is that for example you see these ideas capital and and um wait let me let me do something else guys real quick let me open up uh uh this one let me open up Postman uh what's going on each my workspace real quick let me open a postman and you see we're already doing some shenanigans on stream and all that that making our own matching engine trading engines crypto exchanges from scratch poker traditional it's crazy we did so many stuff and we're having a good time so we're going to say get three thousand slash account right what's going on we don't actually set Json right you see I think we have a little bit of an issue let me open up these headers real quick content type you see content type is text plane that's that's that's not good so we need to fix this real quick and write Json right application Json how how do we how do we how do we do this I have no clue I thought it was something like that but apparently it's not right that's crazy I'm not gonna lie I need to figure this out and I have no clue header set that should be good application Json right anyway it doesn't matter I'm going to fix this in the next episode guys um sometimes even myself does not know what to do so we're not going to lose any time anyway you see what's going on here uh and maybe I saw something in my in my thingy here yeah it's okay it's fine so we can see that if we uh body body this oh yeah this is fine if you do it to Jason no it isn't body heat man so I'm so sorry so we can see that this first name last name and numbers and and all these things are with capital B and of course it can work but I want to have these things small caps so how can we do this well we go back to uh or type stinging and instead of uh we need to have some Json annotations and I need to jump to my keyboard because I don't have this letter apparently on my 60 thingy I don't know I'm using a 60 keyboard and I have no clue where that uh thing is on that keyboard so uh we're gonna say Json I'm gonna say uh it's gonna be ID right like this and now I need to basically delete it paste it then I'm gonna say this is going to be the first name right so this basically is some kind of a strict annotation where we actually specify that if this field if the strict is getting serialized or encoded to Json how that variable name should be we can actually completely rename this into its into another name so although it's going to be first name in the strict an adjacent representation it could be a username or something completely different right uh but it is what it is we're going to say here last name uh this is going to be we could actually say for example yeah let's let's just call number it doesn't matter it doesn't matter number and then in this case it's going to be the balance uh like this like this balance right balance yes that should be good so if we now run again right and I'm still a bit pissed about the content type but we will fix it so now you can see that everything is small right ID is small first name starts with um the F with the small with the small cap F uh and and I and so on and if you really really want to be fancy you could do for example a snake is right you never know maybe that's the that's the name of the game in your company where where or for your client wants to have the API in snake is then you could do it like this right um then then first name would be sneakers in the Json a representation right but hey we're using this right cool um uh let us see letter C let us see what are we going to do next so the server running is perfectly fine let me open up uh the server that's something different right we need to uh our API right do we need to do we need to have something else before we call this a day yes what we could do actually in handle accounts right so we need to have a way to specify uh to which accounts actually what you're going to do we could do something like this we have a handle account but we also is going to have a handle account and I think we need to do something like this syntax and we could say ID maybe right and then we could we could say here handle get account my so let's try this but I think we need to make sure yeah I think that's fine that's fine that's that's going to be fine let's see if that works first of all what we're going to do in handle get account is do something for example ID is going to be actually first right so we're going to say the vast it's going to be Max vars I'm going to give him the request and I think we could do something like um instead of returning this account let's actually return fast just for the sake of seeing if it's going to work I'm going to say make run uh where is my Postman Postman is here so let's say get account and let's say we're gonna give it an idea like this and I sent this and then you could see that we have the ID and that's fine because right now what we could do in our code is basically this we could say uh that the ID is going to be mixfart and ID like this and then we could do here database right we could say DB gets uh ID and all that stuff right that's that's what we can do um so for now what we're going to say is um let's return an empty account to make this happy and then maybe we just log here rmt uh and we're going to log out the ID real quick here make run and see if that is going to work boom so we have an empty account which is what we did and then we're going to see we have the ID here right so it's all set up for um the next episode we're gonna where we are going to start Implement uh our database you're going to use postgres we're gonna hook postgres up with our server so we can actually use it we're going to make actually an interface and storage interface so we can for example swap um postvest out with I don't know mongodb or something it's a very common practice that you don't hard coat your storage into your into your handlers so when the time comes you need to I don't know maybe you're going to use something different you can just Implement a new type of storage and hook that up to your server without the need to rewrite all your handlers that's that's actually amazing and that's what I'm going to teach you and we're also going to use gbt out and all that good stuff and of course in the end we're going to dockerize that stuff so we can hand that over to our devops team and sip Margaritas on the pitch thank you for watching consider subscribing to my channel if you like this content jump into my Discord if you want to be a high value engineer and I'll see you in the next video bye bye
Info
Channel: Anthony GG
Views: 65,129
Rating: undefined out of 5
Keywords: go programming language, golang docker, golang programming, go programming, go tutorial, golang project structure, golang testing, golang json api, json api tutorial, golang for beginners, go language, go, the go programming language, golang tutorial for beginners, go programming language tutorial for beginners, golang tutorial, golang, go programming language tutorial, learn golang, json web token, golang jwt authentication rest api, golang jwt authentication, docker, go lang
Id: pwZuNmAzaH8
Channel Id: undefined
Length: 30min 50sec (1850 seconds)
Published: Fri Nov 04 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.