Building serverless API with Claudia API Builder
Writing a scalable API is something that we're struggling with every day. We want an API can scale and be always online. If you're like me, you don't want to think about server infrastructure, downtimes and you want to have an easy way to deploy changes and updates.
Now you probably ask "Is there some great service that can help us achieve what we want?". Yes, there is, welcome to serverless architecture, welcome to the era of AWS Lambda!
About AWS Lambda
AWS Lambda is a service that lets you run code without provisioning or managing servers. It runs your code when you need it and it scales automatically (yeah, no more headaches and downtimes). Lambda is designed to process as much request as you have. The most important thing is that you pay when your code runs and there is no charge when your code is not running. Amazon also gives you 1.000.000 requests for free each month, which is enough for testing and practicing (and even starting with some smaller apps).
How it works?
Writing code for AWS Lambda is very simple. It provides support for Node.js, Java, C# and Python.
Lambda uses handlers and you can read more about them here: http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html
NodeJS code for Lambda would look like this:
exports.myHandler = function(event, context, callback) {
...
}
After writing code, you need to go to AWS Lambda console, then manually create Lambda function from AWS console, set up everything, then package code and deploy. Each time you make some change, you will need to package code and deploy it manually (yeah, login to AWS console and upload file...). There is one great video tutorial that shows you everything: https://www.youtube.com/watch?v=PEatXsXIkLc
I think that you agree that this is a very boring process and takes some time. You will also need to do some configuration and package code every time you want to deploy code: http://docs.aws.amazon.com/lambda/latest/dg/nodejs-create-deployment-pkg.html
Claudia.js
Today I want to present you Claudia.js, great NPM module that gives us the ability to easily deploy code to AWS Lambda and API Gateway and does all setup for us.
Claudia.js comes with CLI and couple commands. For this tutorial, we will need to install it. You can setup Claudia.js on your local machine in two steps:
- Install AWS-CLI and enter your credentials: http://docs.aws.amazon.com/cli/latest/userguide/installing.html
- Install Claudia.js with NPM command:
npm install claudia -g
That's all. Claudia will automatically find your credentials from AWS-CLI and be ready for new deployment.
If you need more info about installation and configuration, check official documentation: https://claudiajs.com/tutorials/installing.html.
Claudia API Builder
Here we are. Now that we have installed Claudia.js, we are ready to start with Claudia API Builder. Claudia API Builder is an extension library for Claudia.js that helps you get started with AWS API Gateway and AWS Lambda easily.
If you have worked with Express or some other NodeJS web framework, you will know how to use Claudia API Builder.
I have already prepared code and we will now go through the process of writing code and deployment on AWS Lambda. You can find code on Github: https://github.com/IvanJov/claudia-api-builder-example
Setting up project
As always, we will need to initialise our NodeJS project:
npm init
When you have created the project, we will need to install dependencies:
npm install claudia-api-builder --save
That's all! We are now ready to write some code.
Main logic
Let's create index.js
and init our api:
var ApiBuilder = require('claudia-api-builder'),
api = new ApiBuilder();
module.exports = api;
We have initialized our api
variable and we are also exporting it.
Claudia API Builder comes with 5 main handlers:
get
post
put
delete
any
(handler for any of 4 above)
They accept callback function and pass request
object with many useful properties from a request. You can check here what properties are sent: https://github.com/claudiajs/claudia-api-builder/blob/master/docs/api.md#the-request-object
Let's create our first GET request handler:
api.get('/', function () {
'use strict';
return 'Hello World';
});
Great! Now we have our API that simply returns Hello World
when we send GET
request to the main endpoint.
Setting up AWS Lambda and API Gateway
It's time to put our API on AWS Lambda and test how it works. Claudia.js gives us an ability to do that with just one command:
claudia create
It accepts a lot of options, but now we are going to use just a couple of them:
--region
: AWS region where to create the lambda--api-module
: optional The main module to use when creating Web APIs--name
: lambda function name
For more options, please check official documentation: https://github.com/claudiajs/claudia/blob/master/docs/create.md
For this example, we are going to use this command:
claudia create --name claudia-api-builder-example --region us-east-1 --api-module index
After running it, you should see this response:
{
"lambda": {
"role": "claudia-api-builder-example-executor",
"name": "claudia-api-builder-example",
"region": "us-east-1"
},
"api": {
"id": "yw5awjdbul",
"module": "index",
"url": "https://yw5awjdbul.execute-api.us-east-1.amazonaws.com/latest"
}
}
Claudia.js will also deploy our code and prepare everything for running.
From the example above, you can see that main API URL is https://yw5awjdbul.execute-api.us-east-1.amazonaws.com/latest. Let's send GET request to that URL. Simply open it in the browser and you should see Hello World
.
Re-deploying API
Let's image that you changed something it the code (as we are going to do later) and you want to re-deploy code. That's very simple and Claudia.js has a solution for that. When you have created your project using claudia create
, it made claudia.json
file with some information inside. That file tells Claudia where is your project set, what's its ID and module.
For re-deploying API, we will use:
claudia update
That's all. When the command finishes its execution, your API is re-deployed.
In my projects I like to set commands in package.json
and I advise you to do that too:
"scripts": {
"start": "claudia create --name claudia-api-builder-example --region us-east-1 --api-module index",
"deploy": "claudia update"
}
Calling scripts will look like:
- Starting:
npm run start
- Deploying:
npm run deploy
Handling parameters
In next example, we are going to see how to handle parameters in Claudia API Builder. It's very simple, check the code bellow:
api.get('/people/{name}', function (request) {
'use strict';
return request.pathParams.name + ' is cool!';
});
You can define params in URL by putting it in curly brackets like we did above: {name}
. All parameters will be available in request.pathParams
object.
Let's test this. Deploy app and open page: https://yw5awjdbul.execute-api.us-east-1.amazonaws.com/latest/people/John
You should see John is cool!
Returning JSON
Returning JSON is very simple! Just return the object/array and it will be automatically converted and served as JSON:
api.get('/json', function (request) {
'use strict';
return {
name: 'John',
surname: 'Doe',
email: 'johndoe@example.com'
};
});
Handling POST requests
For handling POST requests, Claudia API Builder has post
method.
api.post('/echo', function (request) {
'use strict';
return request.body;
});
The example above will return the body of the POST request. If you send the request with Content-Type: application/json
, request.body
will be parsed and an object will be returned (and you will still be able to get raw body string using body.rawBody
).
You can test above example by sending a POST request to https://yw5awjdbul.execute-api.us-east-1.amazonaws.com/latest/echo. You should get request body as a response.
All code for index.js
Bellow is full code in index.js
file:
var ApiBuilder = require('claudia-api-builder'),
api = new ApiBuilder();
module.exports = api;
api.get('/', function () {
'use strict';
return 'Hello World';
});
api.get('/people/{name}', function (request) {
'use strict';
return request.pathParams.name + ' is cool!';
});
api.get('/json', function (request) {
'use strict';
return {
name: 'John',
surname: 'Doe',
email: 'johndoe@example.com'
};
});
api.post('/echo', function (request) {
'use strict';
return request.body;
});
Conclusion
Claudia.js and Claudia API Builder are awesome modules for building scalable and serverless API on AWS Lambda and API Gateway. It's so easy to setup, has a developer-friendly code, and can also be connected with other AWS services, such as S3 or DynamoDB. You can deploy your API and stop worrying about downtimes and overload.