How to build a REST microservice in less than an hour - Golang Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi welcome in this video we are going to cover this HTTP framework that we are looking at called gin so what we are going to do is basically build brace microservice using gin gonig and we are going to use this framework in order to build this pretty small bread's microservice okay so what we're going to do we are going to work on these role and examples right but you can find them in the github repo in the description down below so what we are going to do here is creating a new folder called micro services in this case slash main code ok so as simple as that and here we go so the first thing that we are going to do is basically create our handler so in this case we are going to work with a micro service called a users so we are going to develop a user's API so in this case this will be the package name and we are going to create our user being unstruck and as you can see here we have a user ID being an integer 64 and when working with Jason we are going to call this ID okay then first name being a string and in Jason first plane and finally last name being a string Jason last name and that's pretty much it we can also add an email address being also string and just index okay so as you can see here what we did is actually creating an a basic stroke this is what we are going to serve and the whole idea behind this micro service is going to provide all the endpoints needed to you need an updated even user okay so as I said before what we are going to do here is create our handler in this case would be the entry point of our application so we are going to define a handler called Quian okay just like this and then the basic signature that a handler needs to learn to implement the interface that we need to implement is C being a pointer of chain that context so as you can see here we are importing jingo neck / gene this is the HTTP framework that we were looking at before this one right here so this is a handler okay now in this case what we are doing is in this same point creating a given user and since we are not going to cover any database at this point what you're just going to do is basically creating a variable called users equals integer 64 just like so we are going to create our users it just me network okay now over here what we have is and the whole idea behind this gene framework is that basically simplifies our development process by providing a set of tools that we can use when creating new microservices in this case using go and using this framework so let's suppose that we send a post request like dates to localhost 8080 slash users okay and we are sending the ID over here being actually the first name being in this case last name the wheel here and finally email just like this okay so if we send a post request to our slash users hand point over here when we send this request we are sending this JSON specified by the content type application Jason so what we can do here is doing something like the bytes the error equals a request that poverty we don't like it and as you can see here we have the bites a year if here Dex things new then we spawn a bad request for example if we reach this point we can now create our user being of type user and in here pair equals Jason unmarshal with the bytes and a pointer to the user and these things do so what we are doing here is basically taking the byte array corresponding to this jason body that we are sending and trying to use this JSON to populate this user very good based on the JSON definition that we have over here so if we have an error so for example we have an email address being a string and let's suppose that we pass an integer over here that would be an error when trying to unmask on using this chaser so in this case we can respond a bad request and if we have and we reach this point then we have a user complete over here and we can just put this user into our map so we can find something like the current D being an integer 64 equals one and then user that ideal equals currently currently Express and users so yes or D equals this one okay just like this so what we are doing here as you can see here is taking the the body tag with us from our request and trying to populate this user variable using this JSON body okay now the whole idea behind using an HTTP framework is that basically simplifies the way we interact with request response okay so the end the only point where we interact with this gene framework is in the handle or the controller or the presentation layer inside of our micro-service we are not going to work with gigantic but with playing go in this case so the only point where we are taking care of gene the gene framework is in our handlers in the entry point or the first layer of our application so gene provides something like this equals C that should be in JSON where we pass directly a pointer to the variable that we are trying to to populate with the jason okay as you can see here doing this over here is exactly the same than doing all of this so instead of using all of these lines of code to take the JSON the input jason and trying to populate a given struct like in this case the user gene provides these Shoaib in json where we're basically if we go to this function you can see that we are saying being over here and the binned interface is implemented in json being binding and over here we have the code JSON and basically this Tico Jason finally does the the JSON ownership okay so that's the whole idea behind this in HTTP framework that we were using that basically simplifies the way we interact with a given request and the data that we have in the response so over here as you can see we have a given user we attempt to create this user will turn a bad request and return we assign a random user ID over here and finally we create the user in our users map and now we need to return created user so the good thing about using DHD framework is that basically we can say see that jason and as you can see here the json function takes a code an HTTP code and an object that we want to display as jason so in this case we are not going to return HTTP status created and our user and that's pretty much it so if we take a look at how this works we have created a handle in this case okay so we have this pattern implementing this interface being sea being a pointer of gender Jason we take a given user we attempt to use the current request to populate this user if we have an error will return the earth to the final user otherwise we take a current ID a random in this case and just add a mod current and use already and we increment this for future interactions with this method finally we assign the user today mode map that we have over here and then we'll return the created user now how we define this create over here what we can do is put a function call map your around where we are going to define each of the mappings that we have in our micro-service ok so over here we are going to have a router being gene a default so as you can see here this is the default router and returns a pointer to join that engine and this is the the core engine that we have engine connick so every interaction that we need to make to this engine we need to do it through a common barrel over here so what we can do is say router that post and we need to implement this interface over here so slash users when we receive a post request against slash users the handler in charge of handling this request is going to be they create handler okay so that's pretty much it over here we have our main function and the only thing that we did is map around when things and finally routered run and you want to say to run this application in the 8080 port okay just like this so as you can see if we run the application now we have gene debug because we're running in the back mode not in production mode listening and serving on 8080 so as you can see here we pass things and we get over here a 200 okay because we have an error trying to create this email address so if we put a valid email address like this there we go you can see that we have user ID 1 first name last name and email and we can keep creating these users and that's pretty much what we are doing okay saving these users in our user map and that's the beauty about this basically about any HTTP framework that it's they simplify the the development process providing a lot of tools for interacting with requests responses because what we want to do here is basically take a look at their the headers that we have and the content on the request to perform different actions based on this information and as you can see here we need to return a bad request in this case so one thing that we can do over here is create our type HTTP error being also olestra and over here we are going to say we have a message being a string and as Jason we are going to say Mace's and a code being a string actually an integer and in Jason you're going to call this code just like this so over here what we can tell is the HTTP air equals HTTP error where the message is going to be invalid adjacent body and the code start a spa request just like this and over here well what we want to do now is display this error as a jettison so same as we did here we can do over here and say now the code that we want to use is going to be aired the code and the JSON is going to be the HTTP error so if we execute this again you can see that now if we change one of the parameters in the request so for example instead of passing on a string here we pass an integer so this will have an error when trying to unmask of this JSON you can see that now we have our 400 and these status that we have over here is pretty much the same that we have over here and the message okay now what if we create and get to slash users slash a given ID okay and even use already so in this case we are going to perform a get so again you create a function called get and we need to implement the handler interface so in this case C being a pointer of chain that context as you can see as soon as we do this now the get function is a valid handler okay there you go we have an error and if we implement this interface now we are allowed to display an - to use this function as handler over here now as you can see here we are taking a user ID like this so this is something really common when it be able to retrieve be able from the given URL that we are handling so in this case what we are going to do here is use already and an error it's going to be a string first int and we're going to use C that query actually Pam like this and as you can see the palm takes the key not a the key name being the same name that we have defined in the mapping and we want to convert this into an integer stick support like this so if here is the miss neele we can do exactly the same as we have over here so in this case invalid use already exists now that we have to use ready what we are saying is user equals and we want to get the user from the user's map users that is already if user equals name it means that we don't have any user matching this ID so we are going to return this message user not found we stop just like this and over here passing user ID so what we are saying here is returning this error where we say the user and the user I didn't we will proceed was not found in our database otherwise we return JSON HTTP status okay and the user okay and that's it let's take a look at how this works so we take this URL from here and we're going to perform a get request slash user slash one and get user one in the phone and you have a not found over here and the same over here and the good thing about this implementation is that basically we are returning the response code as part of the JSON body that we are responding so if someone is taking this these response and trying to do something with the response they actually have the response code in the JSON besides the response code that we are responding in the the actual response okay so as you can see here now we have our users slash one same not found so if we now create a valid user like this so ID 1 first name last name email and now we perform the get request again there you go we have our Musil and that's pretty much they get and they create so now what if we pass on the get we pass a header saying accept and we want to get this response as application XML okay I don't want this for response as JSON I want the response as an XML so in this case what we can do over here in the the get is if see that header and as you can see we can pass a given header and obtain the value that we have in the header if the accept header equals application slash XML then we are going to return this but as XML out actually return and finally over here it's either Jason okay so as you can see here what we are saying is if we have the header accept being application XML draw this response has XML and return an XML instead of adjacent so as you can see it is really easy to interact with every element that you can might have on the request you can interact with the header with the body that you actually have so over here we have our user created so if we remove this header as you can see here we have the response being a JSON so in the response headers you have the content type application Jason but if we pass the accept application XML now you can see that we have our user return has application XML and this is the beauty from an HTTP framework that we can rely on all of these features to simplify the way our application is actually working but one of the things that you can see here is that we receive the accept header for the entire response ok like this but if we pass an invalid user you can see that instead of an XML now we have a JSON okay so in the success case we are returning an XML but in the failure we are returning and JSON so this jason that we have over here needs to be modified so in this case we are going to say respond and we are going to pass the respond with the moment being the string no just JSON or XML is XML being born the HTTP code being an integer and the body being an interface okay just like this and over here we pass see it being a pointer of chain that context so what we are going to do here is in its XML then see that XML with the HTTP code and the body weight time otherwise you're going to do exactly the same but instead of XML JSON so over here instead of calling Cena Jason we are going to pass respond see we are going to have this over here it goes eczema so see instead smell HTTP let code and HTTP and that's pretty much it you're doing the same over here and finally we are doing exactly the same over here we spawn seen this XML HTTP status okay I use okay just like this so as you can see here now it is really really easy for us to switch between different response types like this so you have the accept header in application XML and as you can see here our main section code and now a valid XML now if we pass a JSON that's exactly what we are getting if we create this user ID 1 and we get the user 1 now we have a user as an XML and if we pass this header we have the user as a JSON so as you can see here what we are doing is we are not taking care the JSON or XML in anywhere inside of our application we are just taking care of the the way we should respond this given entity in this case being a user only in the presentation layer ok so now we have our really basic micro-service design over here so we can get a curry and create different users and now one of the things that we are going to do we can have this code as it is right now but this is actually not really cool or really nice because we have the entire code in a single file so what we are going to do here is create different structures for implementing this in this entire micro service ok so first thing that we are going to do is concentrate in the model so over here we are going to create a folder called domain slash users slash user let go just like this and as you can see here we have the main users user code and basically what we're doing here is moving every entity that we have the entire entities that would process to the domain layer okay so whatever we are ready processing it could be a user an item an order a payment or any other model that we are processing in our micro service is going to be part of the domain okay now once we have this we are going to create a new folder called HTTP arrows slash HTTP error just like this go and we're moving the HTTP L to this package just like what we did here now as you can see the HTTP here it is private in this case because we are having this sort as a private stroke and this is for a risk because if we want to use the HTTP package over here we put HTTP tab and as you can see we have nothing over here so let's take a look at what why we are using and what we are using the HTTP error for in this case we will return a bad request in this case we'll return a user not found so what we can do here is create a function called new but request error receiving just a mask and returning in this case a pointer to the HTTP error so what we did here returning a bad request copy place please we turn HTTP our point on twitch beer the cold and we can pass an error equals but request like this okay just like so you can see here now we have a new button request error and this is the message that we are going to respond same as here we can place a new note phone but found error where we say status not thrown not found and from the main what we can do here is just saying it'd still be errors new pad request just like over here invalid yes already and this is the HTTP error that we are created okay same as here in this case yes or no pound gives us the message that we are going to send and instead of a new but request new not power and as you can see here what we did is actually moving the entire logic of handling HTTP error to a common package and we have all of these functions returning the error as our API needs to return the error so it is really really easy to keep moving things around and in this case let me just replace in this case is simple request and there is just this one like this okay now if this is what we have so far the HTTP error our main function and domain so let's take a look at how our code looks until now we have domain HTTP error and the users now what we are going to create here is our controllers in this case we are going to implement Model View controller but you can implement examine out clean architectural any other in in in pattern or architecture that you want to use in this case we are using the MVC pattern so controllers slash users control that go okay so we have controllers user controller and over here what we are going to put are all of the mappings that we have and the handlers that we have so in this case we have in the create handler and they get handler so our main function our main package is looking really really clean and as you can see the entry point of our application is going to be the controller layer over here now the what we need to do now is move the router into our application so in this case application slash application let's go and in our application we are going to have the router ok just like we did here and these map URLs you're going to do here our function start application that basically called the map URL and over here we are going to define our URL puppies at the same level as we have the application so over here we are going to put our you're out okay like this so as you can see here now from our start application we say map URLs we have the router and finally we move the router crammed inside application so first thing that we do is create and then indicate we define the URL mappings in the router and finally we call router touch run and that's pretty much it so as you can see here we don't need any of these baritones you can't remove all these and over you can consider you're just going this way removing this and there we go so as you can see our main file looks really pretty clean because the only thing that we are doing is calling application that start application from the main function so we go over here we Nikolai's all of the routers so we feel the router with every map in that we want to create and then we say router that brat in the 8080 port we can take this as a parameter a configuration file or from whatever you want to check this but what we are doing here is running the application now our controller in this case this generic function called respond and there we go so now that we have the controller and the mappings we need to figure out a way of saying handling this create and get or any other handler that we have in our application so we need to call this create function from our your mappings and one of the really good things that we can rely on is the sir from the from from go being encapsulate encapsulating behavior in an interface as methods instead of calling just package functions because if we go in this way we have no way at all to mock this behavior so what we are going to do here is create our type users actually adding something a little bit users controller being destroyed okay like this and what we're going to do here is instead of putting the create function as a package function we are going to put this as a method in our users controller okay and we are going to do the same over here for the gate so as you can see what we did here is creating an empty thread called users controller and we define they create and they get methods into the struct and not as packaged functions now over here what we are going to do is create a variable called users controller being of type users controller okay so what we are doing here is actually the type of the very lives like this what you are saying here is create a variable called users controller being of type user controller being this interface this stripe and the value of this variable is going to be an empty him and an empty user control in this case a brand new user controller so we'll remove this because goal is importing the data type from this variable so what we can do here is call controllers users controller slash in this case create okay just like this and over here we are going to do the same like this so the good thing about this is that basically if you say controllers you can see that the only thing that we have in our package controllers is these users controller because this is the only public function or variable constructor anything that we have in this package okay we have a single public component in this case at a public variable and the entire behavior of our users controller is inside this is front so if we remove this for example you can see that if we go to the URL mappings and we say controllers now you consider we have users controllers and create but they create is part of the users controller behavior that's exactly what we are doing this we are defining the create as a method in the users controller okay now finally what we are going to do is move the business logic into the service layer so what we are going to talk here is create a new layer called services slash users service and over here we are going to do pretty much the same we are going to create a new type users service being construct an empty stroke now we create a function call create or we received a user being user so as you can see here we import the domain package and the user and this user is part of the domain that we have defined before and we'll return a pointer to users that user and a pointer of HTTP errors like we have over here so I'm going to HTT hear that hdtb okay so now the create function that we have over here is not going to be a package function but a method into our user service okay and finally you have our variable section where we define our real users service equals user service okay just like we did in the controller later on our next video we're going to work with interfaces over here so we can mock the behavior of different service but for now what we are going to do here is move this entire piece of logic to power user service so over here we are going to have registered users map integer 64 and pointer to the users that useful like this and the current usefully being an integer 64 equals 1 okay so we do exactly ask me did before registered users use of the return pointer user okay just over them so what we're going to do here is if user that first name equals an empty string or user last name equals an empty string return nil as a user and HTTP errors the new path request invalid actually let me select this use your first name okay first name the same we're going to do we the last name and if we don't have an ear then we can just return the created user and from the controller what we are saying is on the create we could take a new user variable being of type users producer we do pretty much the same as we did before we try to gain the JSON request into this user and over here what we're saying is created user and the error equals services user service create and we passed the user okay so as you can see here Services is an import to our service layer if error distinct mean then return absolutely this one over here your that code and otherwise created user and as you can see the entire is a logic to create a given user is now part of the services layer and not the controller so the the behavior and the responsibility of the controller is just taking the request validating that we have a valid request and then sending this request to a service to be in executed based on the basic logic that we have now over here to get pretty much the same we take a user ID and now we say that our user and year equals services user service and we need to develop our create and get function over here so we get and we pass use already and over here we do pretty much the same if error this thing its new then just return here this is our get girl respond get our that code and it'll run otherwise response tell us okay and the user so we need to implement this get over here so what we're doing in the service pretty much the same so creating a new function on the surface call to get where we receive I use already being an integer 64 and we'll return a pointer to a user or an HTTP so what we are doing here is user equals registered user is ready user these things new then we have values or so return user otherwise return new HTTP arrows you not found and as before user with this ID not just right okay so that's pretty much it as you can see here now in the controller we call the user indicator equal services that use our service and over here we have get or create so we use the user ID if get their distance new we don't care about what type of error we are getting it complete and not found because the user was not fun it could be a 500 and internal server error because the database is down we don't care we just return that error to the color and otherwise we'll return the final user okay so as you can see here now the application is defined in this way and let's take a look at the final product our main function just import in micro-services slash application being this package over here and we call third application so the first thing that we did is create a router being of type Ginga default so when we call start applications since the Ural mappings is in the same package as the application this router Birbal is private to this package and the good thing as you can see here is the router that we are using is only part of the application package so if tomorrow we want to remove Jing gonig and use goryeo modes or just a plain HTTP listen answer we go we can just do it because with the only point where we need to modify something when we want to change or modify the HTTP framework that we are using are the application package and the controller package okay so as you can see we initialize the router saying when we get a post request against this path the handler in charge of handling this request it gonna be users controllers last create and that's part of the controller layer as you can see here the only thing that we are doing is creating the domain that we we are receiving in the request trying to populate this variable with the JSON body that we have in this case we are saying see that shall be in JSON but we could do something like see that should be in XML for example if we know that we are handling XML or young or whatever you are handling so once that we have our user created now we send this user to the service and the service is going to have the entire business logic to create this user so in this case we're creating our users in this mock map that we have over here we could be using any database that you want relational nor relational and elasticsearch or any other persistence layer that you want and that's pretty much it ok so one final thing is you have the user and these validations over here so what we can do is call terror equals user this user that we have over here user that validate here these things you know return nil and they're okay so what we can do over here is to our user create a method to this user called volunteer that returns a pointer to HTTP errors and we do this over here like this okay so the user knows how to validate itself to say if this is a valid user or not so in this case we can do pretty much the same for the email address and say invalid user email address and since we are always working with the use of this is unnecessary first name last name in the trace and that's promoted so from the beginning the main function is calling start application from the application package the application is defining the the mappings on the router like like we have over here so each mapping is defined on a given controller and as you can see here we are defining the behavior into a given strut and not as packaged functions so the controller is just taking the request sending that request to a service under serve the service is the one that has the entire business logic to handle each of these requests okay so finally as you can see here we execute the entire application and there we go user one phone and now we have enough pound the code if we pass XML we have this as XML then we create this user sending a post request to our create handler so in this case let's suppose that we pass an invalid first name invalid first name we pass valid first name but and invalid email address invalid email address if we pass an invalid Jason we now have invalid Jason and since we have created our user now we execute the gate and we are hacking this user as Jason if we send accept header we have the user as XML okay so that's pretty much it I just wanted to show you how easy it is to create a brace microservice ago and over here we are using gigantic SN HTTP framework of course we can use different types of HTTP frameworks over here so I really hope that you have enjoyed the video if you did actually I'm going to ask you for for you to subscribe to the channel so you can have in notifications every time I upload a new video and that's something that I'm going to start doing really really often so I really hope you have enjoyed the video if you have any questions or any comments please use the section below so I can go back to you and see you next time okay bye
Info
Channel: Software Engineering
Views: 2,354
Rating: undefined out of 5
Keywords: rest, build, google, go, microservice, how, golang, example, tutorial, restful
Id: SpNsRVSW90U
Channel Id: undefined
Length: 55min 19sec (3319 seconds)
Published: Mon Mar 23 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.