How to Create a Websocket API using Amazon API Gateway and AWS Lambda - full tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
do you want to learn how you can set up a platform that accepts WebSocket connections using just API gateway lambdas and dynamo DB in this video that is exactly what I'm gonna show you how to do hi guys my name is Sam with complete coding and in this video we're going to be learning how we can set up a platform that accepts WebSocket connections and handles them through API gateway lambda and storing the session data in dynamo dB WebSockets are great as it allows a two-way connection between parties unlike api's which typically are a single request followed by a single response both sides of the WebSocket connection can send multiple messages down the WebSockets at any point during the connection this is great as it allows you to send updates whenever things happen on your system as well as the user to respond with messages at any points without having to wait to respond to one of the requests so now we're going to jump into the code and see how we can set up this whole platform before we start creating the code that is going to enable us to create a lambda WebSocket we're going to do some cleaning up inside this project so that we have a nice clean folder system to start from the first thing we're going to do is go into endpoints select all of the endpoints and delete them we're going to keep the common code as that may be useful in the future the next thing we're going to do is delete the upload data folder as well as the handler dealt j/s the last thing we're going to do is delete the web pack config we won't be using webpack for the rest of these functions now we can go into our service Yama file and we're going to change a couple of things we're going to update the service name to my service project - we're still using a doe s but this time we're going to be using the newest version of node which is node 12 point X we're using the same profile and region as before but we can remove the environment and I am roles statements in terms of plugins we can delete all of the plugins and also this package configuration we can then also delete the custom information just like that and we can also remove all of the functions as well as all of the resources this may look like a very bare surface yanil configuration file but that is exactly what we want as it means it's easier to create new functions now that we've got a nice clear folder structure inside our project we can start building the code for our WebSocket lambdas WebSocket lambdas with API gateway work by AWS creating a WebSocket connection and then hitting one of your lambdas every time one of our functions is called this might be on a connection on a disconnection or on a message being sent down the WebSocket so what we're going to do is we're going to create those lambdas these aren't common lambdas and these aren't endpoints so we're going to create a new folder and we're going to call this folder WebSockets inside here we're going to create a couple of new files I'm going to use the terminal so I'm going to CD insert lambda's slash WebSockets and I'm going to make a connect dot J s I'm gonna make a default dot J s a disconnect j s and finally a message dot J s so now if we look inside our WebSockets folder we can see that we have each of those we're going to start with the connect j s and this is going to be an api which is called every time someone connects to our web socket we're going to start very simply the first thing we're going to do is having a handler so exports dot handler here's an async function that takes an event inside here the first thing we're going to do is console log out the event we're then going to return a current 200 response of connected so here we're going to return responses dots underscore 200 passing a message of connected here responses isn't defined because that is one of our common functionality so what we need to do is require that in at the top so Const responses equals require dot slash common slash API responses so this means that when we get a new connection we're going to log it out and return a 200 what we're now going to do is copy this into the default disconnect and message lambdas and adjust the functionality slightly for each of those so here we're going to send a message of defaults disconnected and finally in here message of got a message this is because this is the backbone of what we are going to be doing back in our connect dot JS we're going to add some extra functionality so what we actually want to do is when a user can it create a WebSocket connection to our API we want to store them in a database we want to store some information about them regarding their connection and a list of messages that they have sent to us to do this we first need to get some sort of unique identifier luckily when a WebSocket is connected they give us a connection ID so we can D structure that off the event request so const connection ID i'm just going to rename this to connection ID capital because that is the format i like to have things in equals event dot for a quest context so now we have a connection ID we want to store some data into dynamo we already have a dynamo right so const data equals an object an ID of connection ID we want to set the date to be date dot now and finally we want to have an array of messages which for now is going to be empty now what we need to do is we need to write that to dynamo so here we can await a dynamo dot right and in here we need to pass in the data and a table name the data we already have but the table name as well as dynamo needs to be brought into this file the first thing will be dynamo so const dynamo equals require going down into the common folder and then dynamo which we can see here has a get and a right so the only thing we now need is a table name as we've done before we're going to be getting this from environment variables so const table name equals process dot n dot table name this will be a parameter that we pass through inside the environment variables from serverless the next thing we need to do is a disconnect so in a disconnect we want to do something similar to what we've done with the connection but we actually want to delete the ID from the dynamo table so the first thing we need to do is get the connection ID so const connection ID of and we're gonna rename that again to connection ID equals event dot request context now that we have that we can await dynamo dot delete passing in a connection ID and a table name we have the connection ID but we need the table name and we also need dynamo so I'm going to go back into our connect j/s and copy those over into our disconnect folder so some of you may have picked up on this but dynamo doesn't currently have a delete function on it so we're going to go into dynamo dot j s and scroll down to the bottom and add our own delete function so this delete function needs to do one thing which is make a delete request on AWS DynamoDB tables it will be an asynchronous request that needs an ID and a table name what we need to do is create some parameters that were passed into our document clients delete so Const params it was an object this object has a table name as well as a key which has an object with an ID in it after this we then need to make the request so we're going to do document client document client dot delete this takes the parameters and we can add dot promise on the end to make sure that it returns a promise and we can return this if we save that we now have a delete functionality that will work with dynamodb inside our disconnect this now means that if there is a delete passed up because there's been a disconnection at the WebSocket it will delete it from the table and return 200 of disconnected the last thing we need to do is go into our messages and create some extra data in here again we're going to be getting the connection ID but we're also going to be passing the body so Const connection ID which we're gonna rename to connection ID equals event top request context and we're going to define the body equals Jason de Paz of event dot body so this is where we're going to be receiving a message on the body that we want to store in that array that we created on the connection to do this we need to update a record the way we're going to do it here is we're going to update it by getting the record changing it and then rewriting over the existing record so inside this we're actually going to use a try-catch so that we can wrap multiple requests in one error handling method so try and here we're going to be getting the first record so constant record equals a weight dynamo dot get and we're going to be passing in the connection ID and a table name as we did before we need to include the table name and dynamo inside this file so I'm going to paste those in at the top so now that we have the record what we need to do is we need to manipulate this so that the messages have an extra message which has been received added on to it so const messages equals record dot messages and then we're going to push a new message on so messages dots push and we're going to be pushing on body dot message this now means that the message array will have whatever we pass up inside the message field on the body of the request down the websocket the next thing we're going to do is we need to write this back into dynamo DB so const data equals an object now most of the record is going to be the same so what we're going to do is we're going to spread the record which means every single one of the fields on the record object will be put as if they are fields in the data object but what we can do now is we can overwrite them by writing a new field with the same name over the top so we're going to pass in our new messages which has been pushed with the message we got down the websocket this may seem a little bit complicated but for now this is the way that we're going to have to do it now that we've done that we can just simply write this back to dynamo so a weight dynamo dot write writing up the data and table them and we're going to return the response of 200 got a message because this is a try-catch we actually need to implement our couch so if there is an error we need to handle it within here we're going to handle it by returning a 400 response and this is going to have a message of message could not be received and that is now our message is completed this is actually all of the code completed so now what we need to do is set it up inside service so inside service we need to do a couple of things the first one is we're going to be defining an environment variable which is then going to be used in all of our files and that has a name of table name as we've done in previous lessons we're going to be using a custom value here so self : custom dot table name which means we need to define that down here so custom has a table name and I'm gonna call this WebSocket users as well as that we are writing to a DynamoDB table so we need to give permissions to our lambdas to read and write from dynamo this is done with an I am role statements here we're gonna have a a statement of an effect of allow it's gonna have an action which is an array and on this one we're gonna be doing a dynamo DB : star which means we can read and write to dynamo and finally the resources sorry guys there's a bit of a typo just here it's meant to be resource not resources we all make typos occasionally so this will allow us to read rights and update those records as well as delete them so those have all been configured in that is the setup for every single lambda so now we actually need to create those lambdas as well as specify that they are triggered via WebSocket first one I'm going to create is a WebSocket connection so web socket - connect this has a handler which is lambdas slash web sockets slash connect dots Handler and with the events which trigger it this is a little bit different to what we've done previously with HTTP requests this has an event of WebSocket and this has a parameter of root so roots are the way that API gateway decides which of the lambdas should be run depending on what has happened to the WebSocket in this case it's a connection so it is a value of dollar sign connect so this will say create a new lambda that whenever a WebSocket connects it triggers this lambda we're going to copy all of this as the setup is very similar for the rest of the functions the next one is WebSocket disconnects so changing its the lambda to be called WebSocket disconnect the handler is lambdas WebSockets disconnects dot Handler and the root is dollar sign disconnect the third one is WebSocket default I'm using vs code and it has a really useful hint where you can press ctrl or command and then D to select the next word that is the same which means you can edit them all at the same time this allows me to change all of these so it's WebSocket default lambdas WebSockets default handler and the root is dollar sign default the last one we need to do is WebSocket message so we have WebSocket message which is the message handler this time though we don't need the dollar sign this is because connect/disconnect and default are all inbuilt routes whereas message is not an in Bill route with this we actually have to pass up a route identifier so that it knows which of the lambdas to send it to so if we save this we've now defined all of our functions because we are saving to dynamo we do also need to create our dynamo DB table so to do that as we've done in previous lessons we're going to create a new resource so resources resources and inside here we're gonna have a WebSocket user table it's gonna have a type of AWS : : dynamo DB : : table it's gonna have some properties which are a table name so we've already defined the table name up in our custom values so we're going to be using that so back in our resource definition the table name is dollar sign curly braces self : custom table name we also have an attribute definitions so the only attribute we're going to define is an ID so attribute name of ID and attribute type of strength so dressed s and we also need to define the key schema for this so key schema attribute name of ID and a key type of hash the last thing I need to do is define the billing type so billing mode and we're going to be going with paper request because setting up auto scaling with this is a lot more complicated so this paper request means that we only pay when we actually use it but it automatically does scale up without without charging as when we're not using it so once we've saved all of that and scroll back up at the top we can now get ready to to redeploy this at the moment we are in the WebSockets folder so we need to CD into the root folder with dot dot slash dot dot slash to get back into the my service project folder and now we can run SLS deploy which will deploy our application this takes a little while to do so I'll get back to you when that is done do hellas lady'll now that this has finished deploying we can see that we have the four functions as well as an endpoint which this time starts with WS s defining that it is actually a WebSocket so what we can do is we can copy this URL unfortunately we can't test this using something like postman but there is a useful website out there to do it so I'm going to head over into my browser and go to WebSocket dot org slash echo dot HTML which is a site where you can test out web sockets we're going to do this by changing the URL and pasting in ours and hitting connect here it is logged out that we have connected so to test this we need to go into our a degress account and see what has happened inside our AWS account we can search for dynamo DB inside here if we go to tables and web socket users inside the items we can see that there was a user connected they have a date and zero messages this is great as we have added this user when the user connected to our web socket if we now go back into this test facility and hit disconnect it says it's disconnected so go back into dynamo DB refresh it and you can see that it has been deleted this means that both our connect and our disconnect lambdas are working perfectly the last one we need to test is the message one so if we connect one more time go back into dynamo and see that we now have a new user inside our web socket we need to change this message so we need to change this message to be an object so and this object needs to have two properties the first property is the message that we want to send which I'm going to set up a message of hey this is a WebSocket message as well as one other parameter if we go into our AWS account and search for API gateway we can see that we have our dev my service project - - WebSocket which is a WebSocket connection and this is the endpoint that we created inside here you can see the routes that we created and there is a route selection expression this means that if we want to hit this message endpoints we need to specify it in the body dot action so if we go back to our echo test we have our message but we also need to have an action which specifies route that we want to go down in this case message finish the object off and hit send and we are sending that message if we now go into dynamodb and refresh the page we can see that this account now has a message of hey this is a WebSocket message this means it has been added to our account and added into this dynamo DB message array if we go back into our echo test and change the message slightly so this is a WebSocket message - and hit Send back in dynamo DB refresh it open it up and we now have two separate messages now that we've created a platform that can receive a WebSocket connection and save messages into a dynamic table we want to be able to reply with messages back down that WebSocket do this we need to make some changes to our code in our code there are a couple of things we need to do to send messages back down the WebSocket we need to store a domain name and a stage so that we can send them to the correct WebSocket and then we need to set up a way of sending those messages the first path is relatively simple if we go into the connect dot j s on this request context there are actually a couple more parameters that we need so we're going to extract those here and they are domain name and stage with these values we're going to add them to the connection data that we store in dynamo dB so domain name and stage so that is all that we need to do inside this file as we won't be sending any messages from here well we will be sending messages is from the message function in here what we're going to do is we're going to reply to any messages that we get to do this we need to add some code after we've written the records back to dynamo and in here we're going to await a WebSocket sending so a weight WebSocket send and we're going to pass in the domain name the stage the connection ID as well as a message this message as it's going to be the first message is this is a flight your message and the other thing that we need to do is get the domain name and the stage off the record the way that we're going to do that is by refactoring this bit just here a little bit instead of it just getting the message off the record we're going to get the record and we're going to D structure message as well as domain name and stage these should be on the record as they were stored when the record when the WebSocket connected so the one thing we now need to do is create this WebSocket send functionality so in our common library where they're going to add a new file and we're going to call it web socket message dot J's and we're going to jump into that file in this file we're going to be using a dresses SDK so we need to import that Const Adel yes equals choir AWS - SDK so there are two parts to sending a message back down our web sockets we need to set up and configure the web socket API gateway management and then we actually need to post the message to the connection the first thing we're going to do is create that connection so it Const create equals a function that takes a domain name at a stage and inside this function we first need to create an endpoint so endpoint equals and this is a malgal nation of the domain name on the stage so I'm going to use string templates and it is domain name forward slash stage so this is going to generate a URL for us and then we need to return a new address dot a lowercase P I gateway management API and we need to create this with some parameters the first parameter is the API version which for us is going to be 28 10 - 11 - 29 as well as the endpoint so this is going to set up the API gateway API management which will allow us to send messages down the WebSocket with this domain name and this stage now that we have that set up we actually want to be able to add some functionality to send the message down that WebSocket so conce send it's going to be a function again and this is going to accept a couple of parameters the domain name the stage a connection ID as well as a message to create a what the WebSocket we're going to actually call the create function so Const WS short for WebSocket equals create and pass in the domain name and the stage just like that now that we have the WebSocket created we need to create the parameters that we're going to be using to pass into AWS so Const post params equals an object the object has data which is just going to be our message and it has a connection I D make sure it's capital I lowercase D equals the connection ID now what we're going to do is we're going to post that to AWS so we're going to return WS dot post - connection passing in the host parameters and we're going to use don't promise to turn that into a promise and an asynchronous request now that we have this send functionality we need to export it's out of this file so that is module dot exports and instead of just exporting this one file we're going to export an object which contains the send function this means we could extend this in the future so that we could do something like send an array of messages and create a new function that doesn't that so we're going to save this file and head back into our message endpoint code as we need to import that into this file so const WebSockets equals require dot slash to get down to the common folder and inside common it is the WebSocket message file so now WebSocket message has a function of send on it which allows us to pass in the devayne name stage connection ID and this message so that we can send it all now this is done we can save this file and run SLS deploy one more time and this will deploy all of these new changes so that we're sending a message down the WebSocket now that this has finished deploying we can head back over to our browser to the WebSockets connection and we can try a new connection so if we hit connect this will connect a WebSocket and now we can try sending a message again and as we see we have sent this message but then received the reply from our WebSocket we can add this send message code anywhere we want in our code and to be honest anywhere that you have access to that DynamoDB database you have access to the domain name and the stage and therefore you can send a message from wherever you like this could be triggered by an event that happens in your software where you need to send a notification such as a message in facebook Messenger or you could send a message down of WebSockets if an event has happened in a game or something similar to that in this video we have learned how we can set up a platform that allows us to accept WebSocket connections we've used API gateway lambda and dynamo DB where we stored all of the session data inside those Dynamo tables we've seen how we can connect a WebSocket to our platform send messages and then receive messages back down the WebSocket this can be used in a huge number of applications from messaging services to notification platforms and many many more things if you've learned something in this video but it would be a massive favor if you hit that like button because it really helps the YouTube algorithm show this video to more users and more developers like yourselves and if you want to know about more videos coming up make sure to hit that subscribe button and turn on the Bell notification so you get notified the next time I upload a video thank you and I'll see you again next time
Info
Channel: Complete Coding
Views: 24,266
Rating: undefined out of 5
Keywords:
Id: DzpGfyB0iKk
Channel Id: undefined
Length: 44min 14sec (2654 seconds)
Published: Sun Jan 12 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.