Microservices in Go - Create an API with Heroku and PostgreSQL P1

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
all right welcome back everybody today we're going to be building more microservices and go we're going to build out a very basic very simple uh api and go using postgres we're going to deploy it with docker onto heroku uh we're going to make use of the free heroku postgres add-on um so that we can just get a feel for how to deploy really basic microservices on roku and get things up and running um this service you'll be able to use it if you have like a fronted app built out in react or angular maybe another microservice can call this or you can just manually call it postman or curl the api we're going to be building out is going to be really straightforward um we're going to just build a simple api that allows you to do crud operations on home so that's create read update and delete on homes so maybe you have some kind of real estate business and you want to track the homes that you're purchasing or your agents are selling so that's what we're going to cover we'll also go over how to run migrations right so anytime you have a database or a data store you need to be able to set it up and you need to be able to maybe alter tables create new tables um and just kind of have rules for the database so we'll cover that as well uh libraries we'll be using uh we already covered um the heroku add-ons specifically for postgres totally free to use there for our api we're going to be using qi it's just a light rate router i'm a big fan of it there's other ones out there i believe gorilla mux or you can just use the classic go http standard library works just as well for our postgres client and kind of semi lightweight orm we're going to use gopg this is a very well maintained repository very well maintained package and library so big fan of that and for handling our migrations we're going to use go pg migrations this is also very well maintained and it comes from the similar similar people as uh go pg so these are two that work very well hand in hand together okay so we've covered this um let's talk a little bit about the basic setup for our repository that we're going to be using um i'm a big fan of katzine's uh structure for go ops uh she has a great talk uh given back in gophercon about how to structure your go apps i'm gonna link this in the description check it out listen it uh listen to this on uh you know 1.5 or 2x playback speed um really good structure really straightforward for organizing microservices and go link so that's how we're going to structure it let's hop into the code here i have set up a basic um just empty um empty project here empty project in goland and let's walk through so we're going to start by creating our dockerfile our main.go and just kind of the package structure okay let's hop into that so the first thing we'll do is just create the folder layout here so let's create some directories we're gonna do cmd we're gonna do just we'll call it server and let's create our main.go what does it say looks like file name yes create file okay cool so package main and funk main um let's just do a log dot and we'll just say we're up and we're running all right so there's our cmd server so cmd is going to hold all of the executables we're going to build basically when we compile um when we compile this there we'll get a generated executable in this folder and that's what cmd holds right it's all the commands we can run let's make a second directory here we're going to call it pkg that's package and this is going to hold all of our modules essentially so we'll create one of them we'll just call it api we'll create a second one and we will call this uh what should we call this db and let's hope there's no complex in these names so in the api here uh we'll just do api.go package api good and in here we're just going to do our db.go okay so api is going to hold all of our routes essentially it'll hold our setup function to create our new router so maybe something like funk new api and this will probably return like a qi router eventually for the time being it's just blank and database um we already have that file this will hold all of our basically data layer data store operations so anything that actually interacts with the database here so maybe we would have a func like a new db and this will return like our actual this will connect to postgres uh make sure that's all running uh maybe this will run migrations maybe we'll have a separate function to do that we will get into this shortly okay so we have our packages set up we have our our buildable kind of cmd set up here as well so now let's set up our [Music] docker file and our docker compose.yaml so that we can run this locally here for the yaml i'm just going to use version 3.3 you can use whatever you'd like and services we're going to have our api um we're going to have our api service and we'll we'll figure out the context for that in a bit uh we'll have our api service and then our other service is going to be our database service here so in here we can just pass in um any basic postgres image so we can look up docker postgres image here and let's just take the official uh postgres image right and let's find here we go and we will just paste that and what do we need here so image there we go let's get rid of this line okay postcards password sure we'll say admin i believe there's the user as well let's see postgres password this so user is an optional environment variable if not specified the default user of postgres will be used so let's get rid of the user here and let's see this is required um it must not be empty or undefined okay so i'm fine with that being admin all right so we're good to go oh we gotta indent these okay so let's work on our docker file now to actually get uh to actually build our main.go and get that running um and from there we can wire that up into our docker compose so let's get started in here uh let's import from goley so from google lang i'm not going to specify a version or anything we'll just take the latest um let's run maker so we're going to make a directory we are going to add everything into that directory uh we're going to set that to be our working directory and next we're just going to build that so we're going to run this command here run go build we're going to output main and we are going to pass in cmd server just main.go finally uh we're gonna expose this thing on 8080 and we're going to run the command app slash main and that will be the executable that we built okay docker compose here so we're building from this when you pass on this dot it looks for the nearest docker file essentially right here in the same directory so that's what we're building from let's expose that port ports what do we do 8080 so there's the internal to external mapping that's good there so we'll have to wire up a connection between api and database so that we have those in our environment variables here um let's see environment we're going to put one end that's port um when you deploy on heroku you need to you always need to use this port environment variable they choose the port that you listen on so you need to listen to that so this is 8080 that we're using locally and let's see yep that should be all the environment variables we need uh let's try to build this so we'll do docker compose up and pass build okay so we're up and running here we see our database container postgres has started up and we see we get a nice little log we are up and running and then uh because we just don't have anything else in main we just terminate um and api exits cool so let's close this down docker compose down all right let's link the two we can use the depends on and use db um as well so this controls the startup and shutdown order so our api can't really function without this database so we need to make sure that database starts up first uh that's what depends on does depends on db and later on we might run into this issue um where even though the database so depends on basically ensures that this container this database container has started that doesn't mean the actual postgres service has gotten up and running um you can kind of see in these logs there's a lot that happens um there's a lot that happens before so we start up the database container and then there's a lot that happens before it's actually ready ready for connections right so database system is ready to accept connections during that time um api would have already started up and probably started to try to connect to db so we might run into this this issue where we're going to try to connect and the database isn't ready so docker has this little workaround here you can run this command and basically wait for it and so you can put in a custom kind of a script that'll just ping the database and kind of figure out is it awake is it ready for connections yet so we'll handle that later we won't worry about that for now okay we've got a basic service we have our docker file we have our docker compose file so we're good to go let's start setting up our qi router next so let's hop in over here and let's just look at their example so here's just the basic example let's just bring all that over and we'll bring it in first thing we're going to need to do is go get chi so let's paste that in cool and we see now it's in our go mod okay so now all these imports are resolved okay so things we need here so we're creating a new router we're going to use their built-in logger middleware this just logs any incoming requests it's just a quality of life thing to show you when your api actually gets hit and they're setting up just a basic endpoint on just slash that just writes back welcome to the user and they're listening and serving on port 3000 okay so let's um let's move this over to our api and new api so in here is where we should set up our router so setup router okay so let's bring this over here okay there we go um so this is going to create the new router this is going to use uh middleware this will set up any endpoints that's fine for now we'll have individual handlers um below and then let's not listen and serve yet um let's have this return that router so what does this return it just returns a chi dot mux it looks like g dot mux okay and let's return our all right so there we go and now in main let's create that router so let's say router is uh api dot new api okay and now we can listen to that all right and let's get our port remember we have our port set here and our environment variable so let's get that os dot get in and port and we can listen and serve on that instead so let's just do a format dot spread out there and it's a string and it's port okay this returns an error so we can handle that and we'll just do print line um error from router we'll just say that we do print that and we can format in the error and let's get a new line at the end okay okay so we're creating our little api here building up our new router we're going to log out that we're up and running we're listening on the ports and we're handling any errors here all right so let's build this again okay so we're up and running i'm going to split this and now we should be able to curl localhost 8080 slash and let's do a gq okay so we get a logline back here and we return to 200 there's no json to parse so jq isn't helpful here we can do verbose and we see that we got a 200 back all right so we're up and running we have our basic api our basic router running um so remember we were going to cover homes right so we're going to cover um crud operations on homes so we should create a handler for our homes endpoint here so let's hop into the qi documentation and we can find what we're looking for all right so we are right here and you can have sub routers in there right so you make your initial router and then you can say r dot route articles and you pass in a new router here you pass in this function here that takes in the router and you handle these endpoints on top of it so we'll do that similar thing for homes so we can um copy this over here and let's see so we have our middleware let's paste this in uh we don't care about pagination we just want to handle some of these basic get endpoints for now okay so get so we'll do we'll do some function git homes let's get rid of this white space here um what will this take let's see i believe it's a response writer and a request yeah okay let's just leave that blank so there's git homes we'll do one for create homes update home and homes okay so get we'll do post we'll say create home create home get homes update and then finally delete okay create i'm just gonna reorganize that put and finally delete okay so we have slash homes and we have our handling for get put etc so let's put these in we're just going to put a basic response in each of these for now all right and we don't need this uh sure we can keep this we can keep this base handler all right let's get rid of that comment okay so here's all of our handlers that looks good let's restart this okay and let's test those two endpoints so let's test the base endpoint here we get hello world that looks good we can test slash homes and that's get home and we should be able to do x post create home and put update home and then finally delete delete home cool so now we have all of our um handlers here so we have git homes one additional one i'm gonna do here so for update home you need to pass in a specific home so let's add in a url parameter here so let's look in the documentation and we can find this here and right here we can see in the subrouter section you can put in what do they call it url parameters here you can put url parameters into your request so for update home let's go ahead and put in this here home id and we can do one more endpoint why not we can do git home get home by d and we can put in home id and let's create that function so there we have that um let's test these out really quickly uh let's see so you can get it the euro parameters just like this let's do that and let's let's uh write those back so get home by id let's get the actual home id and that's the key or my d and we can write this back now we'll change all this later don't worry we'll put json responses into all of these um get home and we'll do the id i'll give it home id okay and similarly let's do this for update and i realized well we'll want to do this and delete also because you'll need to delete a specific home this will be update okay so let's do this similar pattern for delete cool let's change that name too to more accurately reflect that by id let's do that as well okay all right and cool let's test that one more time all right we're up and running and let's rerun this here so we see delete and we don't see any parameters so let's see delete slash test there we go so that one passed through um so there was a 405 there so that requires when you just pass delete without this this home id euro parameter um it's going to give you a 405 because you don't have that url parameter so that's fine um we're on board with that we're okay with getting the 405 back there that's kind of like a nice built-in validation for us it ensures any request that comes to this handler here will have that home id similarly we can do a get request get there we go and we see 200 back and get test awesome so there's all of our handlers set up that's good um let's for our next step let's start thinking about modeling our data structure for home
Info
Channel: devtopics
Views: 2,233
Rating: undefined out of 5
Keywords: microservice, golang, microservices, heroku, api, backend, software, docker, docker-compose, docker compose, deployment, deploy, postgresql, postgres, go
Id: WTEsUZ8MUxo
Channel Id: undefined
Length: 22min 35sec (1355 seconds)
Published: Sun Aug 01 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.