Go and AWS - Code and Deploy a Serverless API
Aug 16, 2023
Go and AWS - Code and Deploy a Serverless API
Learn how to create a aomplete AWS serverless stack using the Go programming language. This course covers both coding and deployin a simple serverless stack using API Gateway, Lambda, and DynamoDB. ✏️ Coruse from Akhil Sharma. Check out his YouTube channel: / @akhilsharmatech 💻 Code: https://github.com/AkhilSharma90/Gola … ⭐️ Course Contents ⭐️ ⌨️ (0:00:00) Introduction ⌨️ (0:00:48) Project Setup ⌨️ (0:02:45) Main File ⌨️ (0:17:22) Rest of the Code ⌨️ (1:18:25) Testing ⌨️ (1:34:37) Deploying 🎉 Thanks to our Champion and Sponsor supporters: 👾 Raymond Odero 👾 Agustín Kussrow 👾 aldo ferretti 👾 Otis Morgan 👾 DeezMaster — Learn to code for free and get a developer job: https://www.freecodecamp.org Read hundreds of articles on programming: https://freecodecamp.org/news
Content
0 -> The Gold programming language can be
used to deploy serverless stacks to AWS
4.96 -> in this course. Akhil Sharma will
teach you how to code and deploy
8.64 -> a complete serverless stack with basic CRUD
functions on AWS using go. This is a complete
15.92 -> serverless stack. Right, so you're using DynamoDB
serverless, you're using lambda serverless again,
22.48 -> and then we'll be using API gateway again,
serverless. Now API gateway helps us
27.04 -> enables anybody across the world to interact
with our lambda function, right. So we'll be
31.68 -> deploying all these three things. From the AWS
console, right, we'll be using the AWS console,
37.84 -> and then we'll make settings for all these three
things. And we'll deploy all of this. And anybody
42.16 -> across the world can use our lambda function. So
this is more like a real world scenario. So I'm
48.8 -> in a terminal now. And you don't really have to
keep this project in your go route. Because it's
54.24 -> Golang. One point 12. And anyways, they had,
you know, go mod in it, which we're going to
58 -> do anyways, out here, go modern, it takes care
of everything. I mean, you don't have to really
62.48 -> do anything manually. Alright. So here, we will
say, we will make a directory first we will say,
68.8 -> Go server less, and YT. Alright, and we'll
cd into this. Go serverless tack YT. For yt
76.64 -> is basically YouTube, I'm making this project for
YouTube specifically. Alright, and here, I'll say
82.96 -> go mod in it. And which is basically
github.com/akil/go server less. So that's
95.6 -> my project. It's initialized go mod for me, go
mod is basically like my package json file. If
100.24 -> you're from a Java background, it will have all my
dependencies for me, you know, easily listed out.
106.08 -> So now what I can do is I can just open this
project up, and code editor, which is VS code,
116.32 -> in my case, just as a pointer, right, I'm using
windows inside Windows, I have something called
123.44 -> as WsL. Inside that I'm using Ubuntu 20.04. And I
use multiple different versions of open to write
129.84 -> Stan this for this particular video I'm using
over in 20.04. And in my open 20.0. For instance,
136.16 -> I have VS code setup. Alright. Now, I don't
want to install a lot of extensions for calling
144.72 -> because I know when I'll start typing, I'll start
writing a lot of code. I'll make some mistakes,
149.28 -> right with Golang. I'll make some mistakes, but
I will fix them. But don't worry, I don't have
153.92 -> extensions, because I don't want to like start,
you know, ballooning up my instance. Because
158.8 -> this is just one of the instances that I use. On
my Windows PC. For over two, I have, like 1015
164.16 -> different versions of Uber, right. So if you need
to go line, by the way, main.go file is your main
171.84 -> file right in the project. And this is how you
start to main.go file, you say package main and
176.32 -> you say import. And because you'll import some
packages, right? Not everything you'll have.
182 -> Inside go Lang go. Lang is very modular, you have
to install a lot of external packages, and a lot
186.64 -> of, you know, packages that come with coal, and
you have to specifically tell that, you know,
190.4 -> this package from cola. And so the the third party
packages that we'll be using will be mostly around
198.48 -> lambda. Alright, so we'll talk about them in a
while. And then the most important thing here
205.44 -> will always be func main, because that's
your entry point into the program,
209.2 -> right, the func main. Now, before I start
writing anything in main.go file, what I'll
214.88 -> do is I'll just try and create, like a very simple
project structure, I need the build folder, right,
222 -> because I'm going to keep my build of this
entire project in my build folder. And that's,
225.92 -> I'm going to zip it up, and then I'm going
to keep take that zip file to my lambda,
230.32 -> sorry, my AWS lambda console. Alright,
so that's why I need the build folder.
234.16 -> And I need my CMD folder, because that's where I
usually keep my main not sorry, not in the build,
240.72 -> but in my CMD folder, I keep my main.co file.
Alright, and then you will have a package folder.
249.84 -> So if you work with Golang, before this, like
the very standard kind of structure, right,
254.72 -> nothing, nothing new. So package will,
as you already know, will have handlers,
259.76 -> right handlers to handle the API's. And then
you will have I'll have a folder for user.
266.8 -> I'll explain to you why I'm doing
that. And then I have a very simple
270.08 -> validation functions where I'll keep that in
a folder called validators. validators. Sorry.
277.6 -> That's it. Yeah, so in validators, I will
have just one little file of Pedley like
285.44 -> five, six lines of code, I think. It's just
going to be as email valid just to check if
289.68 -> my email is valid for the user. And here in my
user, I'll have a file called user.co. Alright,
299.12 -> and my handler That's where my main logic
resides. So this is a very short, very small
303.68 -> project handlers, I'll just have two files,
I'll have API response.go, because I need this
311.36 -> file for my API gateway, I'll build it, you'll
understand what it is. And then it's handlers.co.
320.64 -> Right? Now, my user.go file is kind of a
combination of my models, and my, almost like my
331.6 -> controllers as well, you know, so I have handlers.
But you know, user.go file will have a lot of
337.28 -> code, which kind of which talks my database,
alright, directly talk to my database. So
342.08 -> I'll have those models like those structs as well,
at the same time, we'll have model functions,
346.32 -> those. So database functions at the same time,
I'll head over to your main go file. And func
351.76 -> main, I think what I'll do is I'll start
with this place, right, once I was taught,
359.92 -> get environment AWS region. So AWS region
is very important, because that's where your
367.68 -> lambda will go and set. Right. So with
AWS, if you've worked with AWS a lot,
372.48 -> you know that he has different regions, right. So
my particular AWS is considered configured with
377.52 -> India, which is Asia Pacific South one. So
if you have been using the CLI and setup is,
382.72 -> it'll be amazing. Otherwise, also, I don't
think you should have a problem, right.
387.92 -> But just try and just try and set up a CLI.
It's very easy, just a five minute process.
392.56 -> And it will be very simple for you to follow
along with all of my other videos as well,
396 -> because in my other videos, it's a
prerequisite. So how do you create a session?
403.92 -> So you will say session dot new session.
Now, if I'm calling this old, who is
413.04 -> here, right, so I need to have us here. That's the
package, right? And if I'm calling session here,
418.4 -> session is something that AWS lambda gives me,
AWS gives me sorry, so I'll say github.com/now.
425.44 -> Looking at the documentation for the AWS packages,
at the same time, you can do that otherwise,
431.2 -> in case you're the type of person who wants to,
like know exactly which package you're installing,
436.16 -> because I'm that type of person, I want to install
any extra packages, right. So if you're like me,
441.12 -> you, you might want to open up, just like
I've done, you might want to open up the
446.72 -> AWS SDK, it's called so I'll say AWS
slash AWS SDK for go, you want to,
452.64 -> we want to open up the documentation. And
here you'll see it will just slash session.
459.68 -> Alright, and to create the new
session, you will say AWS dot config
473.2 -> and the bracket which will be curly braces
bracket, you will say region, AWS taut
482.96 -> string and say that you'll
pass the region alright.
499.2 -> Alright, right. And then, as you know, with
all everything to do with Golang, whenever we
506.08 -> haven't, we get two things usually right,
we get the thing that we're looking for,
510.24 -> which is the earpiece session which will come
from the session function, right, or sorry,
514.88 -> the new session function, which is a part
of the session package that we have here.
520.32 -> And we get the error. So with go Lang,
you have to like keep handling errors,
526.16 -> and this is a very neat and clean way of handling
errors because at every stage you know where that
531.28 -> is coming from and you can handle it there itself.
So if there's an error just return right and
537.28 -> I want to create a variable called
Dinah client which for my DynamoDB and
546.56 -> dot new and how you create a
new client will say AWS session
554.16 -> perfect which you just created out here. So
you've created the session and then we'll say
560.72 -> lambda dot start and handler. So this you may not
understand right now not a problem. So firstly,
570.72 -> we want DynamoDB How do you get DynamoDB you get
it like this, it'll say github.com/aws/aws SDK go
580.88 -> slash service slash Dynamo DB. Alright,
so you have session you have DynamoDB and
594.56 -> you want AWS itself and the first place we will
say github.com slash AWS SDK co slash class.
608.32 -> To get this lambda function or sorry, the lambda
package, which has the Start function, you need
617.12 -> the Start function, or you will do is you'll
say github.com/aws/aws Lambda go slash lambda.
631.36 -> Cool. So far, so good. That's what I needed, you
know. And I need something called as the handler,
643.2 -> which we'll talk about. Okay,
for now, I'm creating a constant
653.52 -> called table name. Stable name is
lambda user. I'll say lambda in go user.
666.08 -> And now it's time to create my handler,
which is this basically. So I'm passing
672.24 -> by handler there. In my handler,
what I'm doing is, I have a request.
680.4 -> Basically, I accept some things right. And this
function, and I return some things, and it has
685.6 -> some definition. So what does it accept?
It accepts events dot API, Gateway
694.8 -> proxy. requests. So you're wondering what's
events? Right? So events is basically what?
708.88 -> Go Lang. lamda will give us so I'll come
here. And I'll say github.com/aws/aws,
723.52 -> lambda go slash events. Perfect.
735.68 -> And the other thing that this
accepts is star events dot API.
745.52 -> Okay, to a proxy response. Sorry, I meant that
this it accepts a request, returns a response.
758.8 -> I'm not sure what I said actually, before that.
What I'm trying to say here is that, you know,
763.2 -> this is a function that accepts something and
it turns something, obviously accepts requests,
767.36 -> obviously returns a response, right? No
complication there. That's what you want to do.
773.44 -> And what you will do here is you will switch
the HTTP method. So you'll say switch,
780.48 -> insert request dot HTTP method. So what are
the methods that you have you have get POST,
787.92 -> PUT and DELETE? That's all you have. So
for every single different history method,
795.04 -> we want to call a different function. How do you
do that? So you'll say switch. So we've already
800.24 -> switched, right? We already switched. It's
like, it's 830 here, so I'm kind of sleepy.
807.68 -> I usually get sleepy at 11pm. But somehow, I am
sleepy earlier, because I woke up really early.
813.04 -> I've joined this martial arts class that that,
you know, gets me to wake up at 5am these days. So
824.4 -> so you'll have something
called as handlers. Right?
828.16 -> And where will those handlers come in
from it's basically these handlers that
832.08 -> you want to import. So which are basically your
own creation, your you know, the handlers or your
838.08 -> own creations will say github.com/kill/go
server less, righty slash packets slash
849.6 -> handlers.
854.08 -> Cool. So you're saying to go Lang is that
this is my project github.com/search Go to go
862.96 -> serverless whitey? And say that I have a
folder called package instead of I have a
867.92 -> package called handlers. Right? And handlers
the file. On top of that file will say package
877.04 -> handlers and it belongs to the handlers
folder, then go Lang understands, okay,
881.36 -> this is what we're talking about. Alright. That's
the format. I mean, though, the folder name
884.72 -> and the package name have to be the same. Just
letting you know, in case you didn't know that.
891.92 -> I mean, I'm pretty sure you knew that, but I'm
just making sure right. So you have requests table
898.08 -> name and Dinah client Right, so you sent this to
this function called handlers dot get user, which
904 -> we'll work on in a while. So that was your case
get. Now you have more cases, right you have,
911.36 -> depending on the HDB method, so you have post,
you will have put, and you'll have Delete. For
926.48 -> post, you'll see return handlers dot create. User.
Again, you'll pass request comma, table name,
936.96 -> comma Dyna client. For put you'll pass written,
and lawyers dot update user request comma, sorry,
949.52 -> request comma, table name, comma, diner client.
And for delete, process two handlers dot delete
961.36 -> user. And same thing as you pass
the same things comma, Dinah client.
968.64 -> And after delete, you will just give it a default.
If you work with case switching case statements,
976.48 -> you obviously know this default, right? And try to
keep the orientation same. It won't affect it. But
985.84 -> just as a good habit, you know, I mean, I don't
do it many times. But I try to do it these days.
996.48 -> Alright. So by default, you want to call
this function called unhandled. Method,
1004.56 -> which is again in your handlers file or handlers
package. And this is the entire picture. I mean,
1011.84 -> I don't think we're missing anything. We have the
OS package down here, we have events lambda AWS
1017.36 -> session DynamoDB. Yeah, there's one more package.
Actually, if you look at the AWS SDK, document,
1025.52 -> then you want to import it was SDK, go slash,
service slash DynamoDB slash Dynamo DB I face.
1040.48 -> Just keep these packages. And what I think we
should do is we should just say go mod tidy.
1050.24 -> So we'll get us all the package
that we've just talked about.
1054.32 -> And usually, like many times I do this at the end
of the end of the video, right? But this time,
1059.92 -> I'm just doing it beforehand itself, because many
people they can start freaking out, Hey, you're
1064.8 -> installing all these packages? If not, you've not
run the command go might go more tidy. Or you're
1069.68 -> making so many mistakes, man while typing. Why
don't install some extensions, I've explained to
1074.24 -> you why don't why don't install extensions, right.
So, so with Golang, I mean, what happens is that,
1080.88 -> you know, we usually come from JavaScript
kind of a background, and then we think that,
1084.56 -> oh, you know, if you're making all these
mistakes, and the complete program will crash, and
1089.28 -> it will be difficult to solve it with go Lang.
Golang is very different from other programming
1092.96 -> languages, right? Make as many mistakes as
you want. And once you run the program, Golang
1100.32 -> will really handle everything for you will tell
you which line, what's the problem, it's quite
1104.08 -> intelligent. Right? It's not like your regular
other programming languages like JavaScript.
1115.6 -> So here, one thing that we missed out was to
create the data client in the first place,
1120.48 -> right, so the client has in the variable, and the
defining the type of variable the data client is,
1127.36 -> so what type of time they will
be. That's why we will use this
1131.84 -> or maybe ifs, right, we'll say dot Dynamo.
1140.56 -> Dynamo DB. API. Just make sure
you get this right. All right.
1150.8 -> So that's your main file,
your main file is complete.
1154.56 -> And now you want to start handling handlers. So
here, since these two files belong to the same
1161.44 -> folder, call handlers. We wanted to both to be
package handlers. Right? So we'll say, package
1171.52 -> handler yours. Right. That's clear. Now, I'm
hoping and after writing the package, you say
1178.88 -> import and then you have your main function for in
this case, this the main function of this file is
1187.76 -> called API response, accepts some things, return
some things and has a function definition.
1198.16 -> What does it accept accepts status, which
is int and body, which has an interface.
1209.52 -> What does it return? It returns the event start,
API gateway proxy response, comma error. All
1226.64 -> right. For importing, you'll say and
coding slash JSON github.com/aws/headress,
1243.28 -> lambda Gqo slash events. Okay. All we're
doing with this is basically defining
1257.04 -> the response, right? So we'll say response
is equal to events dot API gateway response.
1269.68 -> And the response, you're just setting the headers.
Pretty standard. Because the way we're going
1280.08 -> to set up these headers are something that we've
already seen so many times. It's basically content
1284.8 -> type and application JSON. So we're saying that
we're returning JSON from our lambda function,
1293.04 -> write nothing out of the ordinary. So we'll say
response dot status code is equal to status.
1306.56 -> And so basically, you're like 400, or 300,
1311.84 -> or something like that. And then you'll
say String body comma JSON dot Marshall.
1323.2 -> So you're, if you've been with Golang, you
already know it's marshalling and marshalling and
1327.52 -> marshalling sorry, is Golang, doesn't understand
JSON on its own. So it needs the help of
1334.8 -> JSON marshalling, which is part of this encoding
slash JSON package. And so whenever you send
1341.6 -> some JSON, from postman into post postman, or
maybe terminal, wherever you send some JSON,
1349.68 -> it basically we want coolant to understand it,
and also the information that Golang produces
1355.68 -> for it to become JSON, and send it as a
response that also needs, you know, help,
1361.2 -> go Lang itself with boats. So that's what's called
marshalling and unmarshalling. There are hundreds
1365.12 -> of videos about it. On YouTube, you can check
it out, nothing fancy or nothing complicated.
1372.24 -> You have to do that in, you know, almost all the
other languages, right, which are not JavaScript,
1376.32 -> which is like basically, Java and Python, all
these languages, you have to do something like
1380.08 -> that, right? Because any language that's not
JavaScript does not understand JSON, by default,
1386.72 -> because JSON is JavaScript Object Notation.
So this is your API response to go. Alright,
1393.36 -> that's it. I mean, there's nothing much going on
here in this file. But the other file in handlers,
1402 -> package handlers, this is where we're
going to spend some time because
1407.04 -> obviously, there will be a lot going on
here, right. So the main functions that
1414.64 -> usually will be there will be based on our main go
file. So main, go File requires get user function,
1420.4 -> create user, update, user, delete user and
anonymous method. unhandled method, sorry.
1424.96 -> So these are the functions that obviously that
you need to create, right? So we'll say get user.
1433.28 -> And he will say Create User. He will say
Update user and delete users. Update user
1453.04 -> and delete user. Alright, so here. The
last function that we want to keep here
1461.28 -> is unhandled. Method. Right? So for let's
say, if somebody uses the patch method,
1469.68 -> because we're handling, get POST, PUT, delete,
if somebody uses patch, then we'll say that, hey,
1475.6 -> it's not handled, right. So
we'll say unhandled method,
1479.12 -> except some things return some things and
so, function definition. Alright, so this is,
1486.32 -> in general, this is how your handles file is
going to be like. And what we can do is we can
1494.48 -> work on our is email validated, valid
file So we'll say package validators.
1505.6 -> And there's a package that you get with
go Lang. It's called regular expressions.
1512.32 -> And we're just creating a simple function where
we just saying if the email is valid or not,
1518.32 -> right, really simple. All it
does is accepts an email string.
1526.8 -> And returns a Boolean, like, true or false.
1532.32 -> We'll take a variable called Alex email, we'll use
the like expression, regular expression package.
1538.56 -> And if you look at the regular expression
documentation, like I have in front of me,
1543.2 -> go to the Golang official documentation and
check out dragon regular expression package,
1548 -> I highly recommend you to open it if you
want, because that's what I've done out here,
1551.68 -> in my other screen will use the
function called must compile.
1560.32 -> And I'm going to copy and paste
a regular expression string here.
1566.56 -> You don't really need to understand what
this does, you just get it directly from the
1572.32 -> documentation. But if you really want to
know, basically, you're just checking if
1576.32 -> you know the numbers are between A to Zed A to
Z, and zero to nine, that kind of stuff, right?
1581.44 -> That's all it's doing. And it's
also checking for at at symbol.
1585.6 -> Right. But obviously, if it's anywhere, it needs
to have an ad, right. So those kind of things,
1590.96 -> just basic email validation check is happening
out there, do check out the regular expression
1596 -> document if you want to really understand
what this regular expression does, alright.
1600.72 -> But if you want to save time, just
copy and paste it like I just did.
1604.96 -> And now we want to check the length of email.
If email, if another female doesn't three, or
1614.08 -> length of email is more than 254 or
Arex, email variable, not match string.
1631.52 -> Then you'll just return false. Right,
so this returns either true or false.
1636.64 -> If these conditions are not met, then you return
false otherwise, you return true, that means
1641.84 -> everything is fine. And email is valid. Right?
Obviously, if this is not proper, it's not working
1647.76 -> properly. If length is more length is less,
we'll say that the email is not valid. Otherwise,
1653.76 -> I will say to you can change these numbers as
you want. But I've kept them to be three and 254.
1658 -> All right, change it on your test. So now we'll
go to our user.go file. And we'll just add a very
1666.64 -> 10,000 feet level, I'll just set up this file. Now
what I want should happen is that for my handlers,
1674.16 -> like domain control, you know what that will go to
the main file to our, you know, to this function,
1679.04 -> basically. And this function is calling the Get
User function and create user function update
1683.28 -> user. And all these functions are, as you know,
mentioned in the handlers, right. And from the
1687.36 -> handlers from handlers, you will call the
functions in your user.go file. And these
1691.76 -> functions will be actually the database functions
that actually talk to the database, right. So
1696 -> every function that you have here, except for
the unhandled method, because it doesn't do much,
1700.88 -> these four crud functions that we have, they
have an equivalent function in your user.co file,
1706.4 -> a complete like one to one function in your user
go file that talks to the database. Alright,
1711.36 -> so let's do that. Let's create those functions.
So firstly, as you know, when we start off a file,
1717.12 -> we import some things. And then here, I'll
also want to define some variables, some
1722.64 -> errors that I want to define. So the functions
that I want to have here and my user.go file,
1729.52 -> which will have one to one
relationship with these four functions,
1732.64 -> the first function will be called I'll
call it fetch user. So that means is
1741.84 -> my Get User function gets called My handlers.
And this function will call in my user.go file,
1746.32 -> the fetch user function, which directly
gets the user from the database itself,
1750.48 -> the database, in this case being DynamoDB.
Alright, so it accepts some things,
1755.2 -> return some things and has a function definition
simple. The second function I want to have is
1760.48 -> for getting multiple users actually, so
I'll say func fetch users. Similarly,
1773.24 -> will look very similar. Then I want to have
a create function. So we'll have create user
1782.96 -> and then it has update user you just have to keep
looking here and then creating these functions.
1799.04 -> Then you have the law as well as delete
user, right, so you will come here
1811.44 -> right, if it doesn't get deleted, then you
don't have to return anything specific special,
1815.76 -> you can just return an error. That's why
from the return here is just an error.
1821.36 -> Right? And that's about it. So we have managed
to one functions, all of these, but one extra
1827.44 -> function is there is just fetch users. Alright,
so we'll see where to get where to use it.
1833.36 -> So from a 10,000 feet perspective, this is your
user.go file, and this is your handlers file.
1839.36 -> So what we'll do is we'll start with Nora handlers
function, and then at the same time, we'll start
1842.8 -> working on our user.co functions. And here,
you'll all obviously, import some things, right.
1854.08 -> The first thing that I need is net slash
HTTP. Then I need my lambda event. So I'll say
1860.8 -> github.com/ad/aws, lambda go slash events. Now,
it's possible that I'm importing these, but you're
1870.8 -> not understanding why I'm importing these. So you
might get confused. So now there are two ways to
1874.72 -> do it. One is when I'm actually writing the code,
and then I use this events packet somewhere,
1879.36 -> and then I come in come up and you know, import
it. Or I know, you know which ones I need. So
1884.72 -> I'll just import them right in the beginning
itself. So they can use them later on. So I'm just
1889.6 -> doing this. So try not to get confused, because
we'll actually be using these packages in just
1894.4 -> like two, three minutes. Don't worry, you know
why we are importing them, we will reuse it. So
1901.76 -> please be patient.
1904.8 -> Slash AWS. Right. So these are the same package
that we already use in our main.go file.
1913.28 -> And we'll say github.com/aws/check it go slash
service slash, no DB slash Dynamo DB I face.
1928.72 -> Great. One thing that I need here, because I would
want to call these functions, like I told you,
1935.2 -> right, I want to call this function. So that's
why I want to import this user package and my
1940.24 -> handlers file. How would I do that? I would say
github.com/achill/go, server less writing slash
1955.68 -> package, slash user. So inside package inside
the user package, we've inputted it here.
1967.6 -> Alright, and then before I get started, these
functions I want define a very variable called
1973.44 -> error method not allowed. Is equal to method
not allowed? And why do I need to create this?
1989.44 -> Because firstly, we'll be working
on this function unhandled method,
1992.72 -> right? So that's why you want to call
this function. So here, this returns and
1999.12 -> event API gateway event. So it will say
API, Gateway proxy response, comma, error.
2009.12 -> Right, so we will send response from
here, or it will send an error. And
2014 -> here we'll say return pay API response, the
response that you want to send is HTTP dot.
2021.84 -> When we say HTTP, we are talking about the
history package Nesta history package, alright,
2026.16 -> status. Method, not allowed comma. Header method
not allowed, which we have just defined together,
2035.84 -> right? That's what you're saying.
So you're saying that we have,
2040.88 -> you know, something for get post put in place,
but we don't have something for patch, so
2045.36 -> patch or any other method that somebody wants
to use. So if you get something like that,
2049.92 -> like an unhandled handle method, so you'll send a
response saying that, hey, this meter is not loud.
2057.04 -> Alright. And I want to create another variable,
but it's actually a struct, right? So it's an
2066.08 -> error body. And I'll be using it a lot so
just bear with me as to why I'm creating it.
2072.8 -> This struct has a variable
called error message, string.
2082.48 -> Error comma, omit empty. Now
for your get user. You have
2098.08 -> he accepts something and you turn something
Before I get user, what do you accept? What do
2103.2 -> you what does the function get you get a request
right from postman, the request that you get is
2111.28 -> part of a savings packet. So you can
say events dot API gateway request,
2120.24 -> comma table name, which is string,
comma, Dyna client, dot Dynamo DB API.
2135.52 -> And what does it return? returns the
response, obviously. So we'll say events,
2140.4 -> dot API gateway, proxy response, comma, Irish.
2149.76 -> Straightforward. And actually, this, these two
things, right, was going to accept and was going
2158.96 -> to return is going to be used by all of the
functions. So what you do is you just copy
2164.16 -> and you just paste it here for
CREATE USER for update user, as well.
2175.6 -> And for delete user as well.
2184.16 -> Awesome. So we've done a lot of heavy
lifting. Now, I want to start working on the
2192.48 -> function definitions for
these all these functions.
2196.4 -> Right, so the first thing that you'll say is
email, request dot query, string parameters.
2210.24 -> So if you've guessed, what's happening here
is you want to get the user but by using the
2215.6 -> email ID of that user. So for my request,
you will have your query string parameters,
2222 -> which will pass an email and that we're
going to capture in a variable called email.
2226.96 -> And then we will check the length. So we'll
say if length of email is greater than zero,
2236.08 -> then you'll get a single user. So we'll say user
dot fetch user, which we've just created together,
2241.84 -> right? We have not created the definition. But
you know which function I'm talking about. It's
2245.12 -> in my user package, which has been imported here
already. So fetch user is going to take the email,
2255.52 -> table name and donor client.
2261.6 -> And I'm going to capture this in the result, or
the when there's going to be an error. And if
2267.52 -> there's an error, I'll handle the error.
So I'll say if error not equal to nil.
2271.84 -> Return API response has to
be dot, status, bad request.
2283.6 -> Comma, or body. So everybody's a struct
that I've already defined. And in our body,
2290.16 -> I want to pass AWS dot string error dot error.
2309.36 -> And otherwise, you'll say hello, DB dot,
everything is okay. So we'll say status. Okay?
2314.48 -> If everything goes well, and you'll
pass the result from this function.
2321.04 -> Now if if you want multiple users,
2330.48 -> you'll say user dot fetch users say
same thing, they will name a client.
2344.72 -> And what you will do is, you will again, use
result and error to capture the values coming from
2350.88 -> this function. And if there's an error, and you'll
check if error is not equal to nil, you will
2356.32 -> return the API response, saying HTTP dot status,
bad request because there's an error, right?
2364.48 -> And you'll send the error body, just like
we did earlier error body is a struct that
2368.4 -> we've already defined. That's the error body that
we're sending, which is basically JSON. And here
2373.52 -> the error body. Inside that, we're going to send,
you're going to send a WS dot string, header dot.
2385.76 -> Got it? But if everything went well, and
there was no error, then we're going to return
2391.68 -> API response and HTTP dot
status. Okay. Commerce result
2401.6 -> So the basic gutsier get user.
Now what we can do is we can
2407.04 -> work on our fetch user and fetch users both
of these functions in our user.co file.
2410.96 -> Or we can work on our CREATE USER function in
our handlers. So I think I'll do the former,
2416.56 -> I'll work on fetch users, and I'll work on
fetch user, let me just check if everything is
2422.24 -> recording, yes, everything is recording perfectly.
I just need to keep making sure otherwise, you
2426.8 -> know, I end up making a long video when nothing
has recorded. And that leads to a big problem.
2432.48 -> Alright, so before I do anything with
users, I want to first create a user right.
2439.52 -> So like I said, this file is a mix of
that model file that you usually create,
2442.96 -> where you define the structure of how the user
is going to look like. So I'll say user struct.
2450.72 -> Email. Now, since this user struct is small, and
we don't have multiple stocks, like if this was a
2458.4 -> e commerce, for example, then you would have had
users and orders and you know, all those different
2462.24 -> like products and so many different stocks,
right. So you'd have to have like a model
2466.08 -> separate Models folder for all these different
models. And then you'll have, you'd have,
2470.32 -> you know, database functions separately,
and controllers or something like that,
2475.6 -> right. But since we don't have that, we have a
very small project, which just has users and users
2480.96 -> all itself, it's a very small struct, because
you just have email, first name and last name.
2488.48 -> You don't have too much here, right, you can
combine controllers and models into the same file.
2494.56 -> Now, email is going to be a string
2501.68 -> which is going to say JSON. And you
say, like this JSON email, because
2507.36 -> for Gulags purposes, it'll be emailed with
a capital E, whereas JSON where it's stored,
2512.64 -> it's going to be emailed with a small
e. So you need to pay a telco like
2516 -> that, you know, there are two versions
of it one, the JSON version, the another
2520.112 -> is the version that Golang understands,
because Golang does not understand JSON,
2524.72 -> as I've already told you. So that's why we also
have to use some marshalling and unmarshalling.
2530.16 -> To get it to understand and interact with JSON.
Alright, so you'll have first name and last name.
2537.52 -> And then what we'll do is we'll
create our fetch user function,
2540.8 -> what does it accept. So if you actually go to
handlers, you will see the fetch user function
2546.32 -> accepts email table name to a client. So we'll
say here, email, and table name, which is string.
2555.6 -> And your Dinah client, which is of type, you
already know that dB, I face dot DynamoDB API.
2565.12 -> And it just returns a user. Obviously, I mean,
2568.96 -> you fetch user, you return that particular
user or return error, if nothing works out.
2575.76 -> You define a variable called input. And
it's of type DynamoDB dot get item input.
2591.52 -> So we'll have to define the key based on which our
database function will run to find that particular
2597.28 -> user. And you already know that the user will be
formed for the database based on the email ID. So
2601.68 -> we take an email id, you take an email ID, and
then we want to find the user that's associated
2606.16 -> with that email id. Alright, so straightforward.
We'll say DynamoDB dot attribute value.
2617.2 -> And we're going to say email because we want
to run a query on email. So email is equal to
2622.8 -> s equal to AWS dot string, dot, sorry, inside
that bracket will pass email. Now the string
2630.88 -> is a function that is given to us by AWS package
Aerospike. It is something that we'll have to
2635.2 -> import out here. All right. And similarly
with the DynamoDB. So we'll have to also
2638.96 -> import the DynamoDB package. So come here on your
import, and firstly called encoding slash JSON,
2646.96 -> because like I told you Golang does not understand
JSON by default. So you'd need encoding slash JSON
2652.64 -> package to use the marshalling and unmarshal
like functions and I need the errors package
2657.68 -> also. Then I want to get my hands on the events.
Now we'll be using it soon. To send responses and
2674.08 -> the usual ones. As you can see, I need DynamoDB
and I need AWS. So let's get those ones. So I'll
2680.96 -> say AWS slash AWS SDK, go slash AWS and also
github.com/aws/aws SDK go slash Dynamo DB.
2703.52 -> And what I'll also do well also
get this particular package.
2712 -> Yeah, let me do that for now. So
I'll say github.com/aws/aws is
2718.48 -> a case called slash service slash, Dynamo.
dB slash Dynamo DB. I face. All right.
2736.96 -> Now coming here, you've already
passed this. And after this bracket,
2747.76 -> you need to specify the table name in which this
2751.2 -> function is going to run. So we'll use the regular
string function again, to pass the table name.
2759.68 -> And after this bracket, you want to use your
data client to finally start getting the item.
2770.64 -> Input is this basically the query that
you created, right and get item is the
2773.6 -> function that you get an error client. And
you will capture that end result an error.
2782.32 -> So, standard practice, if there's an error,
we'll have it on the header soon return nil
2788.24 -> for the value and will return errors
dot new error failed to fetch record.
2804 -> So you must be wondering, Where's What
is this error come from? Probably never
2809.36 -> seen this error, right? Because this is
a new error that I've created on my own.
2812.8 -> How can I create my own errors, I can
create my own errors like this. So error
2819.76 -> failed to fetch record is
equal to fail to fetch record.
2827.6 -> And similarly, I can define any errors that I want
in this variable defined as a variable, right?
2837.04 -> So you've, you know, created a query that is
similar to MongoDB, right, you've created a query
2843.6 -> based on the email, because you want to search
for that email so that you can retrieve the user
2848.64 -> and you've run the function get in get item for
DynamoDB. And you've passed the query to it,
2854.48 -> and you've received that in something
called as result or you received an error.
2858.32 -> If there's an error, you handle the
error. But if the result is fine,
2861.28 -> and nothing really happened, then you
would do something right. But before that,
2868.24 -> we will create a variable called item
and it will be basically a new user.
2874.48 -> And here you will say error is
equal to Dynamo DB attribute.on.
2886 -> Martial map. Okay, so DynamoDB attribute is
another. By the way, if you have not opened
2893.68 -> up the DynamoDB and AWS SDK, go, documentation, do
that, because I have it open on my other screen,
2900 -> you can do that as well. And then
everything will make a lot more sense,
2903.76 -> because these are actual packages inside
that main package. Right? So I'm using those.
2909.52 -> And once you go through the documentation, you
will understand where to use, which one, are you
2915.76 -> or if you really don't care about that, you can
just keep following along with what I'm doing. But
2921.12 -> I just recommend that you just read it because you
know, everything will make more sense. Here I need
2930.48 -> this package right done, what do we attribute?
This is helping me unmarshalling the user.
2936.72 -> So first, let me write the
whole code. So I'll say result,
2940.72 -> sorry, not here. He'll per record
will say result, dot item comma item.
2953.76 -> And this error if this error is not equal to nil,
2957.44 -> what we want to do we want to return nil comma,
errors dot new error failed to on Marshall record.
2975.92 -> So you must be wondering what's happening here,
right? When you get the data from your DynamoDB
2982.72 -> using the get item function into result. You
want to unmarshal data into an actual user,
2990.96 -> which the front end can understand as a
JSON basically. So you use the user struct
2999.84 -> and and you don't take that in a variable
called item. Right? So item is basically
3007.28 -> a variable of type user. And then, you know,
you want the data that's coming from your
3013.92 -> result or item, you want that to be unmarshal and
brought into item so that now whatever has come as
3020.24 -> JSON becomes, you know, the type, which is user,
which is understood by go Lang, but and it's
3026.88 -> captured in a variable called item. Right? So
I've tried to explain to you every single line,
3033.36 -> in case you don't understand it, to check
out what's marshalling and unmarshalling.
3036.72 -> Alright. And if you have any, like, if you still
have any confusions, you can just put it in the
3041.84 -> comments below. I'll sort it out for you. But
it's nothing very difficult, right, we just
3047.6 -> taking what's coming from DynamoDB,
the JSON, and you're on marshalling it,
3051.04 -> to make it into a struct, right? Which is of
type user, which has email first name, last name,
3056.8 -> something that can be understood by ko lang. And
you're capturing that in a variable called item,
3060.56 -> which is obviously of type user, right?
That's struck that we have defined.
3066.08 -> This is standard practice, I do this in all
my other videos as well, in case you're new
3069.92 -> to this channel, I have hundreds of videos
on ko lang, you can check all of them out.
3075.04 -> Like literally hundreds of videos on Cola,
right? Check them out, build projects with me.
3079.04 -> And you'll understand very everything
very easily. So if everything went well,
3084.16 -> if there was an error, obviously, you
sent nil and you sent the errors. But if
3087.52 -> everything went well, you'd return the item,
and then you will return nil for the error.
3092.4 -> Now you'd want to also work
on the fetch users function,
3096.56 -> though, plural fetch users function. How do
you do that you are passing table name there.
3105.28 -> As you can see, here, you're passing given him
an ANA client. So Duolingo has been passed,
3109.52 -> which is obviously a type of string to
pass 10 Nine, a client which is of type,
3115.6 -> you already know, Dynamo DB, I face dot
DynamoDB API. And you return multiple users.
3127.68 -> How you doing multiple users, you return basically
a slice of users, when users is the struct that
3135.36 -> you've defined, right? So you're using a struct,
you're making a slice of all those users,
3139.36 -> and then that's what you're returning. I hope that
makes sense. If you don't know basics of like,
3145.68 -> of Kulang, like slices and structs, then I highly
recommend you check out the basic tutorials before
3153.28 -> you get more confused. So I want to use a function
by the DynamoDB gives me it's called Scan input.
3169.76 -> To get access to a table name, which has AWS dot,
3174 -> string, and table name that we are already
passing here. Right. And he will say Dinah client,
3186.4 -> thought scan and you want to scan the input, the
query that you just created. So here, as you saw,
3196.56 -> we had a more elaborate query, because we had
to get a particular user with email. But with
3202 -> fetch users, you just getting all the users, you
don't have a specific query that, okay, you know,
3206.08 -> for this email, get a particular user saying,
Give me all the users. So you don't have any
3211.28 -> query as such, you're just passing the table name.
So that's when your diner client, but can you just
3215.68 -> pass the input, that's it. And scan is like get
all, you know, you can say that. So if you've used
3224.4 -> that MongoDB, it's, you have find, find all
something like that. Here, you just have scan,
3230.4 -> find and find one you have
in MongoDB. So you just have
3233.6 -> scan, alright, scan and get it. So you're doing
scan to get all the results. And you're going
3241.2 -> to capture that in a variable called result. And
then you will obviously, if you have an error, you
3245.68 -> know that standard way to handle errors is like
this. You'll say return nil for the value when
3254.96 -> you return an error. She'll say errors
dot new error, failed to fetch record.
3263.12 -> And, again, like we did out here, item will define
item, right? The item here is not just a user,
3274.64 -> it's a slice of users, multiple users because
we're getting all the users from our database.
3281.6 -> And, again, the same thing that we've just
done here. We'll do the same thing here.
3285.28 -> So we'll say or do just copy the whole thing
actually. Copy and paste. But there's only one
3295.44 -> more little change instead of result
or item. You'll have result dot items.
3302.32 -> Because obviously from AWS, you'll get multiple
items, multiple users, that's what you're getting.
3306.88 -> And you're returning your item. And
for the error, you're returning.
3314.24 -> Make sense. So we've done quite a bit, right,
we've already done the Get User function and
3320.08 -> get user function had fetch user and fetch
users two functions from your user.co file.
3326.4 -> Now there are three functions left here, and three
functions appear because we've already taken care
3331.84 -> of the unhandled method function, you don't have
to anything more here. So just three functions
3335.76 -> left here, three functions left here. And all
the other files are kind of complete. Right?
3341.76 -> So if you reach this far, congratulate yourself,
because you've come you've come a long way. Right?
3350.24 -> So now let's start thinking about how our
CREATE USER function is going to work. Alright.
3359.2 -> So for the CREATE USER function,
let's let's start building that.
3363.84 -> There's actually not much happening there. All
these functions, right? Create User, update,
3368.88 -> user, delete user, like, they're all going to
look very, very similar. So going to say user,
3374.88 -> because you know, you want to call the CREATE USER
function, the user package, so we'll say user dot
3381.28 -> create user, which is this function,
that's what you're calling,
3385.12 -> right? And you're passing it three things
request, table name, and a client makes sense.
3393.12 -> Nobody will respond to this function returns, you
want to capture that in a variable called error,
3398.96 -> sorry, result, and you will get an error
which will be captured an error. And you know,
3404.24 -> the process from here, if there's an error, which
means error, not equal to nil, you will return
3410.08 -> API response, HTTP dot, status, bad request,
comma, error body and what will be the URL
3418 -> body. Everybody in this case, by the way, is,
sorry, the struct that we want to define right?
3425.36 -> So was there in the body, it's AWS dot string,
with a single or sorry, string, e RR dot error.
3437.44 -> Comma. Okay. And you'll return API
response. HTTP dot status created.
3451.36 -> Comma result. So if that means if there
is no error, everything goes well,
3456.16 -> then you will say he should be
dot status created. Alright. And
3464.8 -> that's about it. That's it, actually, that's your
CREATE USER function, there's nothing more to it.
3469.76 -> Alright. And then for your update user function,
very similar. You'll obviously call the user,
3476 -> just like you did here, user dot create, user
here, you'll call user dot update user method.
3481.44 -> So we'll say, update user. And you'll pass three
things request, table name and diner client.
3490.24 -> And you will capture that in result comma,
header. And then you'll check again, if error
3498.88 -> is not equal to nil. return an API response has
to be dot again, status, bad request, comma,
3510.48 -> error body inside the body. Again, the
same thing, it was a string or a dot.
3519.36 -> Alright, but if everything went well, if the user
did get updated, then you'll return API response.
3528.96 -> And you'll say SDP dot status, okay? That
everything went well, and you'll return
3535.84 -> the result. So that means what's happening,
these two functions CREATE USER update user
3543.36 -> is that these two functions are being
called. That means a lot of the logic
3548.56 -> the main logic is going to happen in these two
functions, right? Because not much happened
3552.16 -> in the handlers. Similarly, let's work on our
delete user function. Here. You'll say user dot
3561.28 -> read user, insert request, comma, table
name comma Diana client. Here also,
3572.64 -> though, the only thing you will learn from here is
the error, right? If the user didn't get deleted,
3578.8 -> you will turn the error. You don't need to return
the result and result from the delete function.
3584.56 -> So if the result is not equal to nil, you will
return API response. You know by now what we're
3592 -> going to say we're going to say says bad request
and we're going to also send the error body
3596.88 -> which will have AWS dot
string And the error itself.
3605.84 -> But if everything went well, you
would want to return the response with
3612.72 -> status, okay? And you will
return nil for the error
3624.64 -> okay
3632.24 -> so that's that's about it.
3639.68 -> And yeah, that's it, I think the entire file is
complete. Now, we don't have anything else to do.
3648.88 -> I've also gone through the AWS SDK documentation,
I don't think anything else needs to be
3653.84 -> done in the handler. So everything looks alright
to me. And now we will have to work on our
3660.32 -> user of go file and all these different
functions that exist on a user.go file.
3666.96 -> For your CREATE USER function, we're all
it's going to accept depends on what you're
3673.52 -> sending from here, which is request a preliminary
client. So here, you'll say request, events dot
3680.96 -> API gateway proxy request, comma table name,
which will be string, and then a client,
3688.4 -> which will be you already know, there
might be a face dot nanodegree API.
3695.76 -> So what is it going to return, it's going to
return the user that has been just created,
3700.72 -> or an error. So here, the first thing
that we'll do is we'll create a variable
3707.92 -> here, which is of type user user being the
struct that we will define that means you will
3712.16 -> have email first name and last name. Alright.
So let's start from there. Now we'll use you,
3719.92 -> why'd we create this variable you is because we
want to capture what's coming from postman. So
3725.76 -> from postman or from let's say, the terminal
wherever will send the JSON of the user with
3731.92 -> the email, first name and last name. And
that data needs to be unmarshal into you,
3738.72 -> so that Golang is able to understand it and also
perform any operations on it. So what do you want
3743.84 -> to do is we want to use the JSON encoding slash
JSON package to call the unmarshal function.
3759.2 -> And what you want to do is you want
to pass the request dot body to it.
3765.28 -> Comma ampersand you if error is
not equal to nil, and also here.
3778.72 -> He called the right syntax for the if statement.
And if error is not equal to null, then
3783.12 -> we'll return nil, and we'll return something for
the errors. We'll say error, invalid user data.
3797.92 -> But we don't have this error here, right? We don't
have this error error fail to unmarshal record.
3805.44 -> We don't have error, invalid user
data, we just have error fail to
3808.88 -> fetch record. That's all we have defined.
Now let's define all the other errors.
3814.96 -> Let me define all the other errors that I'll need
in this entire file and the beginning itself.
3821.68 -> So we'll say error failed to unmarshal
record is equal to fail to unmarshal. Record
3833.92 -> and error and add error and valid user
data is equal to and valid user data.
3855.44 -> invalid email also will be there and valid
email is equal to invalid email. Then we'll have
3870.48 -> good not Marshal item and
could not delete item so.
3896.48 -> Then we'll have could not put
item so we'll say Could not
3904.4 -> Dynamo put item as equal to code not
Dynamo put item. And user already exists.
3926.8 -> user does not exist, or the user does not exist.
So why do I need all these errors? Obviously,
3941.84 -> by now you would have understood, I'll just give
you an example that when creating a user, right,
3947.92 -> if we check if that user already exists, then
we don't need to create that user. That's why
3951.28 -> we need this kind of an error. And if you want, if
you're updating a user, then or deleting a user,
3956 -> we can use this, that user does not exist. So
I trying to update that user, right? That's
3960.8 -> why I'm just thinking about all type of error
functions, I'll need error statements I'll need.
3966.56 -> So depending on that, I've just created
them. So going back to your create users,
3974.56 -> right here, now, we will start
validating the email. So we'll say
3982.88 -> validators dot validators is the package that
we have created together, right, this one.
3989.52 -> And the function that we created in
that package was his email valid.
3997.28 -> And you is the variable that you define. And
now after unmarshalling, the request that you in
4003.28 -> the body body is of the request that you got from
let's say, postman, or from the terminal as JSON.
4009.76 -> You captured that in you. So now you can now
go Lang can easily understand you because it's
4015.92 -> unmarshal, right? It's not just one and more,
so you can access you dot email. And you can
4022.64 -> run the validation function on it. So here the
spelling is wrong. Should I when is email valid?
4030.32 -> And you'll return nil, comma, errors,
dot new error, invalid email. Right? And
4050.16 -> how how the reason why I created this error is
because I want to see if that user already exists,
4057.76 -> right? So if the user already exists, then you
don't need to create it. So we need to throw an
4061.04 -> error. So we will check if the user already
exists, right? So I won't put that comment,
4067.68 -> actually, I was just trying to show you. So
to check if the user actually exists, you have
4072.64 -> to run the fetch user function, you will say u
dot male comma table name, comma Diana client.
4083.04 -> And to capture whatever comes from
this function in current user,
4089.92 -> and we won't handle the error,
so I'll put a blank there.
4095.52 -> So if current user is not equal to null,
that means there is this user exists, right?
4101.36 -> If current user is not equal to null, and length
of current user dot email is not equal to zero,
4113.68 -> then you return nil comma, errors
dot new error user already exists.
4127.12 -> And so all of this if the user
exists, but if the user doesn't exist,
4131.2 -> he will just say that user right,
so how do you save that? So first,
4134.88 -> to save that, obviously, whatever you
now have in you, you want to start
4143.2 -> want to start marshaling it right? So
that DynamoDB can understand it now.
4147.44 -> So you will say Dynamo DB, attribute dot
Marshall map, you and you'll capture this in AV
4164.48 -> and you'll check for the error. So if there's
an error, we will return nil. And errors dot new
4172.64 -> error could not Marshal items which you've already
defined, we've already defined this error right?
4186.24 -> And now, you want to start creating your data
that you will be sending to DynamoDB. So how would
4196.32 -> you do that? You'll say DynamoDB dot put Item
input item is Av. Comma. table name is AWS dot,
4213.04 -> string table name. And finally, you'll see
Dana client dot put item, and you'll send
4226.56 -> this input that you've defined here. So
yes, missed the is equal to sign by mistake.
4232.64 -> Similar to fetch users, right, you created this
input, and then you call the ANA client function.
4236.96 -> Similarly, you're doing that the same thing here,
you're calling the put item function. And you'll
4244.8 -> capture that in a blank actors blank variable or,
and, or you will get an error from here. And if
4252 -> error is there, then you will just handle it very
easily. You'll say return nil, comma, errors dot
4256.72 -> new error, could not timer put item right here
faded this error already. But if everything went
4266.24 -> well, you just want to return the user are nil.
Awesome. So this is your CREATE USER function.
4281.28 -> And now you're left with update user and
delete user. Everything else you've taken
4288.56 -> care of right, the handlers are go file
is complete API responses complete as
4292.16 -> as an email validator is complete,
and may not go as complete.
4298 -> And I think for our user file, we have imported
all the packages except for validators. So you
4306 -> need validators. So you'll say github.com,
the validators package that you've already
4310.72 -> created? We talk I'm talking about that one.
So we'll say go serverless yt, slash PKG slash
4320.88 -> validators. It will also check what else
am I missing for handlers? I think I've
4327.76 -> already imported user. And I don't need
any more packages. For API response.
4337.2 -> I don't need more packages. For his email valid,
I don't need anything else. My main.go file,
4343.6 -> probably, I might have missed something. So it has
handlers has always even slammed on AWS session
4350 -> DynamoDB DynamoDB is, so everything is proper,
based on the AWS SDK, go right, check out this
4358.32 -> documentation, you will know why I'm importing
these packages and how I've used these functions.
4362.96 -> You already know that because you've been building
it with me, alright. Then we'll come here,
4371.12 -> again, back to our user.co file. And let's
start working on the update user function.
4377.84 -> So what does it accept, accepts request, which is
of type events, and thought API gateway requests,
4387.04 -> comma, table name, which is string comma,
Dinah client, which is of type DynamoDB, I face
4395.84 -> dot DynamoDB. API returns a user the
updated user. And, or fine, I mean,
4407.36 -> or it sends back an error. And we're going to do
a lot of things which are going to be very similar
4413.76 -> to the Create User function, which is basically we
create the user. First we created the user, right,
4419.12 -> which is the variable u, which is of type user.
And we're going to unmarshal, just like we did,
4427.68 -> we're going to unmarshal the request body that
you get. So request dot body, comma ampersand you
4442.32 -> so by mistake, yeah, so I have to
close the bracket here, because
4449.28 -> this is together. And this is this variable view.
4456 -> Okay. And her nautical tunnel, if you don't want
to follow along, you can just copy and paste
4462.8 -> this part, right? I'm not copying and pasting
because this syntax might be new to many people.
4467.92 -> Because it's DynamoDB, kind of working with
DynamoDB. So I'm writing everything by hand.
4474 -> If you want to copy and paste, if
you're very comfortable with DynamoDB,
4478 -> go ahead and do that. You don't need
to, you know, practice along with me.
4483.68 -> Then you want to fetch the user and see if that
user even exists. So you will say your email
4487.68 -> comma, table name comma, data client. And you
want to capture that in current user Adding on
4503.6 -> a check or the current user. So if current user
not equal to nil, is exactly what you did in the
4512.96 -> create function as well. And length of
current user dot email is equal to zero
4528.16 -> then you'll return nil comma errors
dot nao error, user does not exist.
4539.44 -> So for the CREATE USER function, we were
checking for the user associated with that
4544.56 -> email, because we want to see, you know,
that is really exists, we don't want to
4548.32 -> add that user. But for update, we're doing the
reverse, we're checking for that user. Because
4552.4 -> only if that user exists, we can update
the data for that user make sense? And
4559.44 -> exactly the same things will do, because now you
want to start. So now that the user, you know,
4566.8 -> if the user doesn't exist, will throw an error.
But if the user exists, then you want to start
4570.8 -> updating the table with the new data. How do you
do that? Whatever you've unmarshal right now,
4576.56 -> from JSON to unmarshal, to something that Golang
understands, now you want to start marshaling it
4581.84 -> to something that DynamoDB understands.
So you already know what you want to use,
4586.24 -> you want to use the marshal map function. To pass
you to it, because you've just done marshaled.
4595.04 -> And which packages is a part of so it's
part of the Dynamo DB attribute package
4606.96 -> we will capture it in a variable called
AV or we'll get an error. And now we can
4612.4 -> easily handle the error. So if error
not equal to nil, return nil comma,
4619.92 -> errors dot new error could
not Marshal it, this one.
4626.96 -> Really, really straightforward. Now you just
want to create your input item and then you
4631.28 -> want to just call it and a client function,
only two steps remaining. So you will say
4635.12 -> input is equal to ampersand Dyna, more dB, dot
put item input, and the item is equal to Av
4648.96 -> comma, the table name will be equal
to AWS dot string. table name.
4659.44 -> And the last thing is you'll use Diana
client dot put item and you'll pass the input
4675.92 -> and if error not equal to
nil, nil comma errors dot
4688 -> new error could not Dynamo put
item return ampersand you come on.
4699.6 -> Soon now even my update function is complete
everything looks okay. And all I want to do now
4708.96 -> is run the Gomati command to get all
of the packages that are not there.
4729.04 -> So I think it's taking a while
I can't find my phone anyways.
4734.56 -> So while that's happening in the background, we
can start working on the delete user function.
4744.64 -> So as you can see, it's all installed. I had
a couple of issues actually. As you can see,
4753.92 -> and most of the issues were because I had a couple
of spelling mistakes here instead of SDK added an
4758.24 -> S KD you know, so a small small few mistakes I had
made. Just make sure you get these tight. You can
4766.88 -> easily get them on AWS SDK go documentation or
if I put a mostly I'll put this code on GitHub.
4776.24 -> So you can just pick it up from there. Alright,
make sense? Just pick it up from there instead of
4781.84 -> typing in all yourself because I made a couple
of mistakes. So it was it was taking a while.
4786.48 -> But now it's install all these packages. So then
your user.go file, everything works perfectly
4794.32 -> right? Like we don't know if it works
perfectly but everything looks perfect to me.
4798.72 -> And all the packages are in place. All you need
to do now is work on your read user function,
4807.36 -> which is actually the most actually the like
the easiest function. So it takes request,
4813.6 -> events dot API gateway request, comma
table name, which is of type string client,
4820.88 -> which is a type already know, you already
know that. Dot DynamoDB API. Alright.
4829.6 -> So what you want to put in the function
definition, you want the email of the user, right?
4834 -> So request dot, query string parameters,
and the parameters, email, then you will
4842.56 -> create your input to the function which is of type
DynamoDB. Hen dot, delete item input, item, input
4863.84 -> star DynamoDB dot attribute.
4870.88 -> Value. Basically, you're passing the email, and
then finding the user and deleting the user with
4877.92 -> it associated to that particular email. Right?
Nothing complicated. So you will say AWS dot
4886.56 -> string. And you pass email to that.
4892.56 -> After this, you'll say table name.
AWS dot string, pass the table name.
4904 -> And now that you have your input ready,
just like we've done all other functions,
4907.68 -> you take the data client, you call the DynamoDB
function, which is delete item in this case, and
4916 -> you pass the input to it. And put basically has
your query for deletion, which is the email ID.
4925.2 -> And you get the error. If there was an error
4934.384 -> will return errors dot new error
could not delete item. Perfect.
4947.04 -> Otherwise, we just return
null, nothing. Basically,
4949.12 -> that means that the user has been deleted.
Now, I'm sure there are a lot of errors.
4954.16 -> Because I'm not using any type checking extension
or any go Lang extension, right. So there will be
4959.68 -> a lot of errors here. So I need to start solving
them one by one before I deploy it to the cloud.
4967.2 -> So to find those issues, and to fix them, I'll
head over my terminal. And I'll head over to the
4973.2 -> CMD folder and has a co build main.co and starts
giving me errors, right? So it says on this file,
4986.24 -> line number eight. Yeah, I can see the issue,
it has to be doubled. Right. That's what
4992.16 -> makes it the or operator. So you will run the
command again. And now you will get all these
4999.44 -> nice headers that we were expecting, right? And
now we want to go start solving them one by one.
5005.92 -> So starting from line 37, all the way to line 145
too many errors. So when it says too many errors,
5010.96 -> that means that even after you solve
these, it will give you many more errors,
5015.2 -> right? So this is why I don't really, you know,
use extensions, because Because Golang takes
5022.4 -> care of everything, it tells you which exact line
which part, what you're missing, you don't like
5028.32 -> it's a no brainer, right? You don't have to apply
a lot of brains just solve these issues, just like
5032.72 -> go Lang once you do, and everything will run. So
that's why I'm so chilled out all the time, man.
5039.36 -> So if I go back to your code, on line 37, what
could be the issue is that I have not put a comma
5047.84 -> here and comma here. basic syntax issues, right?
That's what it says it says basic syntax issues.
5053.44 -> Here also you need to put a comma. And let's
keep putting commas wherever you know, I think
5061.92 -> it will need commas so this needs comma here,
which is line 58. In my case, you can check it
5069.12 -> out where you know, it is for you. For CREATE USER
again, I'll just put a comma here just to be sure.
5077.12 -> And I'll put a comma in the input part which is
this. Alright, and in the update user function.
5090.8 -> Again, let's go to the input area. Here I've
put the commas or haven't seen any issues here.
5101.28 -> And for delete, definitely you need to put a
comma here as well as here as well as here. So
5110.96 -> now if we run it, a lot of the errors
have gone away, right? And now you have
5119.36 -> some other errors. There are some syntax
errors also, like for syntax errors, and one.
5126.48 -> This one was that you're not able to
5129.76 -> refer to this function. So let's try
and fix those as well, at the same time.
5138.08 -> So let's hover over back to our code. Let me
see the line first line says 88, line 88, blah,
5146.24 -> blah, blah, blah, blah, yes, M is small, whereas m
should be large. What was I thinking? Am I stupid,
5153.92 -> you know, that I was not able to? That I didn't
make them, you know, large, because obviously, the
5160.72 -> function is martial map with the capital M.
Right? So this just means that no matter how
5165.68 -> stupid you are, go, Lang takes care of everything,
right? So you don't need to be the smartest guy
5169.6 -> on the planet. So let's look at others stupid
mistakes. So 108 comma missing? It's a syntax
5177.2 -> error. Super simple, right? It's even telling
you expecting comma, right? I mean, how obvious
5183.44 -> can edit statements be? And then people, you know,
tell me download this extension? I, I don't have
5190 -> done it an extinction man. Go Lang does everything
for me. And missing statement after label wonder
5196.8 -> if I wonder if I miss you statement after label
blah, blah, blah, blah, blah? Yeah, obviously,
5203.84 -> the physical sign is off. And then 147 147. put a
comma here, right after 147. And then unexpected.
5220.08 -> Yep. Found it. Now let's run it. Now. Let's
see some more errors. Yes, so it found some
5229.04 -> more errors. And now you have to go to Line
Number 66, and 76 and 140. But these are not
5238.56 -> syntax errors. So here, you will have to think a
little bit as to why the there's an error there.
5247.76 -> So head over back to your
code on line. 66. Lines 66.
5255.84 -> Yeah, so it says, let's look at the error it
says, cannot use results dot result or items.
5263.52 -> And something something something
to do with this function called
5267.04 -> on Marshal map. That is because you're receiving
items, not item, you're receiving multiple items,
5273.04 -> right? So you can't use unmarshal map function
here, you'll just see use unmarshal list of maps.
5282.88 -> Super simple, man, super simple. 36, line 76.
Alright, it says blah, blah, blah, blah, blah,
5292.08 -> request dot body. See it says
request dot body undefined.
5296.88 -> And it also says does not have body with capital
B. Right? I mean, you don't, you can be the
5304.88 -> stupidest person on the planet and fix this issue,
because you just had to make this be capital.
5309.52 -> Right? So that's how intuitive go Lang is. And
then you go to Line Number 140. Line Number 140.
5317.36 -> I mean, I can guarantee you that you can't do any
like something like this with any other language,
5321.28 -> right? It says there's a problem with
this function, obviously, because there's
5324.16 -> a spelling mistake here. Parameters.
Everything is fixed now. And now let's
5329.6 -> see. So it gives me another error. It says
unmarshal. Just off map is wrong. Yeah,
5335.92 -> because I made mistake. Again, it should have
been unmarshal list of maps, not map. Awesome.
5346.16 -> So now, now that your user.go file is sorted
as an IT first shows you the syntax errors,
5352.32 -> you've solved them, then you solve the logical
errors. And now it's giving you some issues
5356.96 -> with the handlers file right handles.
It's giving you all these syntax errors,
5360.96 -> we'll solve them and we'll give you some
logical errors. We'll solve them as well.
5364.48 -> And then we're good to go. Right? So we're on
the right path. Now let's go back to our code.
5372.16 -> So whenever your code and start from
line 19, line 19, put a comma here, line
5383.2 -> for it to fall to put a comma here, it was saying
it's accepting expecting a comma from you, right?
5388.24 -> And line 54. Comma, line 59 Blah,
blah, blah, blah, blah Pratama.
5399.28 -> Line 62. 60 and 72 and 66 for comma 32, comma.
All right? Now you start getting the real
5410.88 -> errors, right, the real errors. So, line 22, we
just solved this issue on the other file line 22
5418.88 -> Because the spelling of parameters is
wrong. And now you're going to worry about
5426.88 -> line nine, line nine. So one thing to notice is
that it's line nine, but another file API response
5437.84 -> would go. So open up the API responded, go file.
And here I can see there's an issue. Alright, I've
5449.76 -> fixed the issue. It was basically to do with those
brackets. And now it's starting to show me issues
5456.64 -> with may not go file, which is what I want. I want
to fix the main.go file issues. But on line 44,
5463.44 -> line 44. Let me see what's happening. Okay, yeah,
I can see it, I can see the issue, it's basically
5471.92 -> all the cases have to be together. And by
mistake, I'd written this outside the bracket,
5480.4 -> also the switch bracket, and I've included
inside. So that error should also go away.
5488 -> And now when I do this, it's created the goal
build may not go file for me. So let me see if
5494.4 -> it has Yeah, I can see the
main file, I just have to
5499.04 -> move it here to my build folder. And I've hit the
build file, without any issues, no errors, right.
5506.64 -> So now let's start the deployment process. Before
you do anything else, you need to first create
5517.36 -> a zip file. So you'll just come here it will say
zip minus gr M and build slash main dot zip. From
5528.72 -> build slash main. So build is your folder main is
the build that you've created for any folder, and
5536.24 -> build slash main dot zip will be the zip file
using the zip function. Maybe in your Linux,
5541.12 -> you don't have zip, you'll have to install it
using sudo. apt get install zip. So now if we
5549.76 -> check here, we can see the main dot zip file in
my build folder. And now we ready to kind of start
5557.36 -> uploading it on lambda, or ADA plus lambda. But as
remember, as you remember, I told you that I have
5563.84 -> Windows installed on that I'm running WsL on that
I'm running this open too. And on top of that I've
5569.68 -> built this folder, right? So I need to be
able to access this main dot zip file from my
5577.44 -> windows for my windows to be able to install,
like upload it on my AWS code and lambda lambda
5584.88 -> dashboard. So for that, I'll do something.
5590.72 -> So to in order to help me to do that,
I have to run this command explorer
5598.48 -> dot exe. Dot. Now hopefully it should
open. Yeah, it has it has opened up the
5606.4 -> Explorer at this location
for me, and I'll copy this.
5611.6 -> I'll put this on my desktop. Awesome. And now
I can start to deploy this on my AWS console.
5622.48 -> So you want to start deploying, but there's one
thing I wanted to change is this table name.
5629.52 -> So I'll keep this table name same as my, the
name of my program. Go serverless righty.
5642.16 -> Okay, just for consistency sake, because we'll
have to create this table in DynamoDB. And
5650.24 -> let me just search. If I was using the other table
name, so you'll just control Zed. And we'll just
5657.44 -> see if I was using this table name
anywhere else in any other file.
5664.4 -> This only place there's only one place I was using
it. So here's the table name has to be changed.
5670.48 -> It will say go server less writing. Okay, and
now is when we start deploying. So log into
5680.32 -> your console and head over to lambda. You have
to just create function go server less writing
5691.72 -> server using Golang one point x I think we'll have
to change the execution roles create new role from
5698.96 -> AWS policy demo This option is what you have to
select, and the roll name, go serverless, righty
5708.88 -> execute from the templates, you have to choose
Simple micro service permissions create function
5718.32 -> successfully created, right? Now
you want to change the handler.
5725.92 -> So as you know, our main, the file that we'll
be uploading is called the main file. That's
5730.72 -> what our build is called right. So we'll
have to change the handler to mean upload
5737.36 -> the zip file and upload it, go back to AWS
and go to DynamoDB. Can you will click on
5759.92 -> Create Table Table names table
name is what you selected here
5765.36 -> go server less whitey. Simple, right? Because
we've kept everything the same name so
5775.68 -> and primary key. So it says enter the partition
key name, I think this is the primary key here
5781.493 -> is the primary key. The primary key in our
case is email. Which is string, obviously.
5790.08 -> And everything else is same. And we
can just create the database active,
5794.08 -> it's now active. So now we can proceed to the
next stage, which is configuring your API gateway.
5804.24 -> So head over to your API gateway.
Create API. Now to build a REST API.
5821.76 -> Protocol, let's test select new API here.
And now you want to put the API name,
5830 -> which is cool. Server less ID.
And you then create the API.
5850.72 -> From the Actions to create method, select any.
5865.6 -> And here you'll select integration type
lambda function. And check this use lambda
5872.08 -> proxy integration. And you have the name of the
lambda function here, which is go serverless YT.
5883.92 -> And you have to also have to ensure
this is checked default timeout.
5905.92 -> Now we need to deploy our API.
So from actions deploy API
5918 -> select new stage, stage
name of staging and deploy.
5935.12 -> So this is your URL that you get here.
Which we will be using right now to test.
5947.28 -> So let's test it out. I'm, I'm expecting
some errors to be there. But not a problem.
5955.28 -> Let's clear our screen. And first, we'll have
to build this command. So just give me a second.
5965.2 -> So here are my four commands. And obviously, this
is post which is creating a user this is get all
5974.8 -> users get a particular user by email ID. And this
last command is for update. Now we can use postman
5982.32 -> or you can you just use curl which are the same
thing right? And you set your header header and
5987.12 -> you tell it was the request which is post
and the data that you send which is email
5991.2 -> which is my email address, my name my last name
and this is the the unique link that I just got
5999.68 -> this Link is the unique link that I just got
from my invoke URL. Okay, so I'll post these,
6007.76 -> I'll post this command somewhere, how do I post
it? Now? Okay, so I'll do is I'll upload this
6012.64 -> project on GitHub, and then in the description,
I think I'll just post these commands so that
6016.88 -> you can just copy and paste them quickly. I
think that will be the best option. Or you
6022.24 -> can just use postman when given you have to use
these commands if you don't want to. Alright.
6028.48 -> And similarly, for the update, you say it's
request, but you have the new data is going
6035.04 -> to find email based on that, because email
is our primary key, as you already know,
6039.2 -> and this is my API link will follow
commands, I need one more command, which is
6047.84 -> the Delete command. So I'll change that to this.
6060.24 -> So you will get all these in the and
API gateway documentation on how to
6067.92 -> call these API's, you can get that
also. And so I'm just copying those,
6071.44 -> and I'm just changing those commands. Alright.
So what we'll do now is we'll try and test it.
6079.76 -> I'm pretty sure that we some error
will fail. But let's do it anyway.
6095.44 -> Oh, so it worked. It worked.
Alright. So it created this user,
6099.12 -> which is amazing. Restaurant the second command.
6111.12 -> Sorry, this command
6118.64 -> is not copying and pasting.
6125.12 -> Now returning the get all users command.
So we'll get all the users only one user
6129.76 -> is S, which is getting that. And then we'll
get the particular user. particular user has
6137.28 -> this email id, it will get that user also for
me, because there's only one user right now.
6145.04 -> Yes, so that's also working. And now we will
work on our put function. So sick, it's taking my
6155.28 -> email address and changing my first name to
lalala and last name to blah, blah, blah,
6159.36 -> right? So it's done that you update is working.
And now we have to work on the delete function.
6171.28 -> So if the delete function works, it won't
return anything. So we will check if
6180.08 -> that user is still there, so
we're getting all the users.
6186.4 -> That means delete work, because it's an empty
array, right? That same user is not there anymore.
6191.44 -> Perfect. So that means everything is working. I
hope you enjoyed this tutorial. It's a long video,
6198.72 -> I know there's a lot to follow. There's a lot to
learn there. And I hope you really enjoyed it. I
6203.44 -> hope you learned a lot in this project. And very
soon I'll have I'll have one more project coming
6209.76 -> up with serverless tag, but it's a little more
advanced, we'll have multiple lambda functions,
6213.44 -> we'll have CloudFormation, we'll have you know,
those CloudFormation scripts. So everything will
6218.32 -> be through YAML files, and then AWS CLI. And we'll
also use AWS, Sam for the entire setup. So that's
6225.76 -> going to be really complicated. So make sure
you've done the AWS lambda, you know that video
6231.52 -> and you've done the serverless video. And then
you read a little bit more about how serverless
6235.28 -> works and all the different technologies. And
that will really help you in the next upcoming
6239.6 -> video. There'll be slightly longer actually much
longer, and they'll have like way more complicated
6244.16 -> project, right. So the point of that is where this
is like a monolith serverless project, right? That
6249.92 -> will be serverless microservices project, there'll
be API gateway CloudFormation. They will be a lot
6257.52 -> more technologies. I will use AWS, Sam for all
the writing all the configuration files. Anyhow,
6263.68 -> so I hope you're enjoying it and do subscribe to
the channel if you haven't already. And there are
6267.68 -> hundreds of videos on go Lang on my channel, check
them out. And I also keep sharing some nice advice
6272.96 -> on you know, your development career. So keep
watching that as well. Alright, so see you and
6279.52 -> connect with me on LinkedIn. There's the LinkedIn
link in my description box below. Thank you
Source: https://www.youtube.com/watch?v=zHcef4eHOc8