Serverless microservices on AWS Lambda using serverless framework w/NodeJS
Many of us cringe at the cost of our cloud hosting fees. At Dermveda we have started a migration over to micro-services to break down our monolithic API. This helps us build smaller teams that can work on scoped functionality of our website with clear lines of communication between services. A side effect of micro-services are that you need many additional servers running your services. This not only increases your cost but also your chances of problems when it comes to reliability. Solution: Server-less micro-services! Server-less architecture gives you the advantage of reliability and low cost. Through AWS Lamba, you currently only get charged per Lamba execution. When writing this article AWS is charging ‘$0.20 per 1 million requests thereafter ($0.0000002 per request)’. The key point here is ‘per request’. This is killer when it comes to low traffic services. This is a short guide to show you how to create your first server-less service. Download github project here.
server-less: The general design architecture.
serverless: The library built around managing AWS Lambda development and deployment.
I know it is confusing…
Server-less architecture has come a long way and has some awesome pros but it also has some potentially fatal flaws. Many of us know that writing software is not just about a great product, but also about scalability and writing applications that are easy for other developers to understand, debug, and build on top of. I love where server-less architecture takes us but building a server-less application is just half the battle, we need to make sure we can write applications that do not make developers lives harder. Server-less applications have unfortunate dependencies on cloud services and do not always help with identifying the relationships between our code. I chose to work with a new product called ‘serverless’ that essentially makes organization and fluidity that much easier. I believe this product is the glue that holds together readability and fluidity of server-less applications and I am excited where they are heading.
Now that positions and opinions are out of the way let’s build something. As stated before we will being using serverless cli to build our service. This project also requires an AWS account and NodeJS installed on your machine. For NodeJS installation your can follow the steps here.
Once you have an AWS account and NodeJS is install you will need to finally install serverless globally.
npm install -g serverless
Now that serverless is installed we will need to create a AWS IAM key serverless to work. If you are unfamiliar with this process you will need to go to HOME>IAM>USERS>ADD USER
From here we can click next on Review and Complete. Once completed you will access to this new user’s Access key ID & Secret access key and you can run this command below:
serverless config credentials --provider aws --key EXAMPLEKEY --secret EXAMPLESECRET
This sets up our configuration for our new Key and Secret which serverless will use to deploy our service. From here we can tell serverless to scaffold our application and cd into the new project.
$ serverless create --template aws-nodejs --path my-service
$ cd my-service
Next open the project in your favorite code editor and you will see two files.
We will need a User model use when getting and saving users to and from our database. Make sure to also install mongoose via npm.
npm install mongoose --save
I used mongoose in this example and created a very simple user.js file below.
The serverless.yml file is used by the serverless library to handle setting up and structuring your server-less configuration in AWS. This file can do a whole bunch or really cool things but we will be using it to create our AWS Lambda functions and setting up our API Gateway. Delete the current content of serverless.yml and paste in the code below:
We are creating two functions that will get a user and save a new user, I have named them ‘user’ & ‘getUser’. I have also attached handler functions that we will create in the next steps.
This is your main source file for all your AWS Lambda functions. Remove any boilerplate code and add the two functions in the code below:
You will notice that we create a connection to our MongoDB instance in each function. This is because we need to make sure we have an active connection each time our function runs.
This function merely checks our MongoDB for any users with matching email to the parameter passed through the url.
This function is for saving new users. By sending a POST to function we can pass in a new email and our Lambda function will create a new user in the database.
Above you will notice this very important line of code:
context.callbackWaitsForEmptyEventLoop = false;
This is a needed function that is required for AWS to terminate itself on:
I recommend you do some more reading here to fully understand why we need this.
This is the most streamlined part of this build, just run:
serverless deploy -v
This publishes your entire project everything time however, you can re-publish on only a function level using something like this:
serverless deploy function -f getUser
Testing can be done in either the AWS Lambda GUI or API Gateway in AWS or through the terminal using serverless. Using ‘ — path’ or ‘’— data’ to pass data to your function.
serverless invoke local --function getUser --path data.json
Here is some documentation on this process.
Currently debugging is not so elegant. I have found that using AWS Lambda console logs work for most cases. Luckily serverless has a great feature of retrieving current logs and future logs (live feed) for a specified function. I have listed an example for requesting logs for a specific function below.
serverless logs -f getUser
This example has been quite a simple one but I hope it gives you the foundation to use serverless to build your own applications. Be sure to read more of serverless documentation and checkout more examples to see all it’s true potential!
Want more? Checkout a recent video tutorial I did on Serverless framework and micro-services.