Microservices in Go - Heroku and PostgreSQL P3 - CRUD API - Connecting API to DB

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome back to microservices and go uh we're building a microservice on heroku uh using their postgres add-on so in our previous video we set up the database connection and also our migrations that we run here so today we're going to actually start hooking up our apis taking a request and actually inserting stuff and getting stuff back from our database um so let's jump in let's get started so i am in our api.go and i'm looking at our handlers and we're going to go through and implement each of these today let's start with the create home so let's build out our request and that'll be just create home request and this will need all of the pieces of a home so this will need essentially these here and this this will be an agent id this will be an n64 so when we create a home we're not passing in the entire agent object or structure we're just passing in an id and the id will be agent underscore id so this is what the create home request is going to look like and just to give you an example here i have this little uh test request um that i just made in the repo just rec.json and this is what that request is going to look like when we come in so just the agent id and these will be the rest of the values and let's build out a response so create home response uh this is kind of optional but previously we sort of talked about having this maybe success field and maybe an error field as well so i think that's i think that's useful um so we can do that so success is just a boolean and there we go we'll do errors and this is just going to be a string okay and then finally the home that will return and we can just return a full db.home and we'll do that i spelled successful nice okay that looks good so now we have our request body and we have our response so let's go ahead and get rid of this here so let's just write some comments what we're going to do um we want to parse in the request body so we want to parse in the request body we need to get the database somehow and finally we need to insert insert our home and then return a response so these are the things that we need to do so let's go through one at a time let's uh do them so the first step is parsing in the request body so uh just built in go has the json library here and we can just use a new decoder and it takes a io.reader so if we do r dot body we can basically read in from the body so we can get whatever text is in our body here and we can read it in and we can decode and we need to specify where we're going to decode to so let's do request and make sure it's a it's a pointer it's an address and create home request so we're going to decode into request and that returns an error so let's handle it and if our error isn't uh no we're just going to do http dot error um well let's see so we have a nice response so we can use that so let's go ahead and we can just encode and return that response so we'll build the response set up all the fields success is going to be false and our error we can set to the actual error that it is and our home is nil and let's just encode that okay and this returns an error as well and here i'm just going to log it just in case just in case we failed send that back to the user and let's see here write the status back um so if we can't become a response we'll just say that's a bad request all right and finally let's return so that we don't keep processing okay there's that um so we can try this uh right now here let's go ahead and build okay we're up and running and to test this i'm gonna just change the type we're expecting an integer but if i pass in with a string it should fail so curl and this is the syntax we can use the method is post and to use a file in the current working directory you can just do hyphen d and at that file let's do that and i'm going to use jq to kind of print it in this little pretty format here so we see success false and we see the error cannot a marshall string into it all right if we change that back to an end we run it and we just return to 200 back cool so let's go ahead and work on getting the database out here so to do this um we can use context so chi has a lot of middlewares here and a nice way to pass values down through your requests is using the context so that all of the incoming requests can access things so if you have like loggers or maybe you have metrics that you're going to admit like statsd or something like that you can use the request context to kind of add in key value pairs so we can do middleware dot with value and we'll say db and now we need to get our database in um we just need to get our database here so if we do pgdb we'll alter the structure of our new api we're going to add this parameter so we're saying when we build an api we need to also give it a database and then we're just going to put that into our context here so that means we'll need to change main cmd server main so right here now we need to give it a database so pgedb and we've built our database right there and we can just pass it through okay so now all of the incoming requests will have this this database value in the context so if we go around here now we can get the database from context so let's do that so we do our context dot value and then we just pass in the key and let's cast this to pg.dp so this this specifies the type and then we'll get our database um we'll get our database out of there and we'll get okay because we're doing a cast here and this is going to be a boolean true or false whether or not we were able to find and pull this out so if not okay we're going to do this same thing we're going to need to build this response again and this time our message is just going to be we couldn't get the database from the context okay so there's that so now we have our database um so now let's insert our home so the next step um the next step we're gonna do here is actually create the row um i'm gonna change this to pgdb just so we don't get a naming clash with our db package over here okay so db dot create that's what we want to do and we're going to want to pass in pgdb and something some kind of um some kind of object from this create home request all right so this function doesn't exist so let's go ahead and create it so if we go to db home.dp this will be where we'll keep all of the functions for interacting with our home database model so let's create the function create home and this is going to take a db which is our postgres database and then this will take in a uh just a home object here and we'll return um home and an error and for now let's just return nil nil all right so we have this um so we're using our pg library here and to insert uh we do something like this db.model and now we need to pass in the actual model here so request dot insert okay so that does that uh that actually will insert our row it's going to return a result object and an error object so let's hold those and let's see so result um result is not really useful to us if you want if you're doing like a bulk insert or like a bulk update you can see exactly how many rows that you've worked with but this model object isn't really useful to us so i'm actually going to just use underscore and ignore that one and right here let's handle the error so if there was any kind of error we don't want to return any home let's just return the error okay otherwise we want to retrieve um this whole object otherwise we want to return that and we also want to return the agent which has an id and a name so to do that we'll write a query and let's hop to pg's examples so i'm just on the github page right here and if we scroll down right here so select story and associated author in one query this is exactly the kind of thing we want to do we have this relation here and we're trying to select the story so we can bring this over and i'm going to change this to be this address pointer syntax here not a big fan of using the new method that's just a code style if you'd like to use new go for it all right so our relation here is agent so whatever the name remember we set up this relation here whatever the name of this relation is this specific name here you'll need to pass in so this is like agent one two three for example we need to put that here okay so whatever you call your agent uh whatever you call your relation that's what goes there and for us it is our request sorry um so we're to read we're reading into this empty home we're going to pull in this relation as well and we need to get home.id equals request id so one other kind of facet for gopg so when we do this insertion here and we pass in that request it actually updates that request object and it puts the id that it automatically inserted into that object so when we pass the request in here this id is going to be just totally empty there's nothing in there yet but as soon as we've ran this insert and it there's no error and it succeeds it's going to write id for us so now we have access to that id all right so we're going to query our home and we're also going to query the relation okay so that looks good there um one additional piece that we're gonna have to modify too let's open up homes and let's look at this briefly so another facet of gopg is that when you do an insertion it looks for these column ids specifically these ids so when we pass in dbmodel request.answer we need to also have an agent id field and that's an n64 that's the type we're using and it needs this json this json string here that we're setting needs to match this column that's how it'll do it so we need to add this in as well okay so that's good now we want to return home and we can also just return error so we'll handle this we'll handle if it's a home or an error outside of this function okay so we're set up here um let's see here um one additional thing that we haven't done yet is just set a foreign key on here so in postgres um just to make your database stronger more robust and more secure we can use constraints and keys so if i do references agents id this is going to create a foreign key on the agent id column and it's going to make sure that every row we try to insert into homes must have a valid agent id that maps to something in that agent table so it's going to look up in the agents table and that's going to check if the id column and agents matches this so we can't create any homes with random agent ids that don't actually exist all right so we created the home let's go back to api here so create home takes a database and a request so let's make that request let's fill up fields so we're not passing an id but we are passing in the price request price remember we're getting this from the request body here and request that description request dot address and we have the agent id as well you don't need an agent okay so this returns a home and an error and let's handle that error so if error is not equal now that's fair dot error so we're going to just send back the what look wrong okay otherwise everything's good um we're successful here so we can actually write back this home uh into the response so here we'll do rest equals faithful response and let's fill all fields so in this case it's true we succeeded and the home now we can just pass in and now we need to write it new encoder w code res all right okay so we're going to send the response and we just write back the status okay okay so we're all done um this hopefully will work let's rebuild this and test this out all right so we're up and running and let's test this out so everything's good here and let's go ahead and curl send it okay so we get an error back awesome so this is this is actually looking kind of nice here so error insert or update on tail violates uh table homes violates foreign key constraint homes agent f key so remember we set up this constraint right here that says every agent id needs to exist in the agent table but we don't have any records in the agent table right so we can actually just insert a row here so as part of our integrations we can insert in some default agents so maybe our little real estate firm here has a couple of agents already in it and we just want to always create these these agents whenever we run our migrations so let's do that so we just do insert into agents and values and we pass an id and a name so let's do one comma dev topics okay and now we'll rerun this and our migration scripts will automatically create this record all right we're running it's clear and let's go ahead and post this again awesome so now we get this full response body back so that succeeded there so we see success true errors empty and we actually have our home now we have an id of one so that's the id that's postgres our database automatically generated for us and we see all of our fields and we also see our agent so if we pass in any other agent id like 33 we see that we fail to create that and for example if we create another record here we should see a different id so here you see home now has this id it has id3 that was successfully created and one thing i just wanted to point out too you might be wondering hey why is this home id three we just have one other home right um yeah that is just a facet of postgres um postgres and the serial type so we created the first home that's id1 then we tried to insert a second home and that failed because postgres said this foreign key doesn't exist but when you use serial um it just increments every time this is this is like a way that postgres handles some concurrency issues um so rather than having to like maybe revert what current id you are from i don't know from three back down to two um it just always increments so even when you fail to insert you're always going to increment that cereal um there's only two rows created there's not there's not like a ghost second row created okay so let's keep going here you
Info
Channel: devtopics
Views: 625
Rating: undefined out of 5
Keywords: microservice, golang, microservices, heroku, api, backend, software, docker, docker-compose, docker compose, deployment, deploy, postgresql, postgres, go
Id: UCV7Z8KryS8
Channel Id: undefined
Length: 20min 51sec (1251 seconds)
Published: Sun Aug 29 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.