Introduction to Claudia.js

Serverless architecture and serverless applications are rapidly gaining momentum. In a couple of previous blog posts I have showed simple examples of how RESTful APIs can be deployed using AWS API Gateway and AWS Lambda. In one blog post CloudFormation’s native resources were used to create the entire stack, including the RESTful API. In another blog post a different approach was used where some resources remained in Lambda, but Swagger was used to define the RESTful API and the API Gateway mappings. Both alternatives provided full control of your stack, but the configurations were quite verbose even for simple sample projects. This time, we will re-implement the same application yet again, but instead of using CloudFormation we will take a look at what Claudia.js has to offer. The full source code is available in my GitHub sample project.

tl;dr

Claudia makes it easy to develop serverless applications that can be deployed to AWS. Execute the following steps in order to create a RESTful service that uses AWS API Gateway for HTTP request mapping and AWS Lambda for business logic:

  1. Install Claudia as a global dependency by executing $ npm install claudia --global.
  2. Execute $ npm init in an empty directory to create a new npm project (enter appropriate answers for your project when prompted).
  3. Add Claudia API Builder as project dependency by executing $ npm install claudia-api-builder --save.
  4. Create a new file called index.js in the project root folder with the following content:

    'use strict';
        
    const ApiBuilder = require('claudia-api-builder');
    const api = new ApiBuilder();
        
    module.exports = api;
        
    api.get('/greeting', (request) => {
        console.log('Event:', JSON.stringify(request));
        const name = request.queryString.name || 'World';
        return {greeting: `Hello, ${name}!`};
    });
    
  5. Deploy your application to AWS $ claudia create --region eu-west-1 --api-module index (this step requires that you have an AWS account and that you have configured your access key ID and secret access key).
  6. That’s it! That is all that is required to create an API Gateway backed by Lambda. To verify that it is working copy the url from the output of the previous command, append /greeting to it and make a request:

    $ curl https://[api-gateway-id].execute-api.eu-west-1.amazonaws.com/latest/greeting
    {"greeting":"Hello, World!"}
    
  7. Deployed and verified, wait for customers to start using your incredible greeting service. :-)

Claudia.js

At its core, Claudia.js is a deployment tool. The following lines have been copied from the project homepage:

Claudia makes it easy to deploy Node.js projects to AWS Lambda and API Gateway. It automates all the error-prone deployment and configuration tasks, and sets everything up the way JavaScript developers expect out of the box.

In addition, there is the Claudia API Builder that takes of the API Gateway generation, request and response mapping, etc:

Claudia API Builder is an extension library for Claudia.js that helps you get started with AWS API Gateway easily, and significantly reduces the learning curve required to launch web APIs in AWS. Instead of having to learn Swagger, manually managing request and response transformation templates, manually linking gateway methods to Lambda functions, you can just write the code for your API handlers, and Claudia API Builder takes care of the rest

Behind the scenes, the AWS JavaScript SDK is used to handle the deployment. By executing just a few commands, Claudia will create an application stack that comprises not only the API Gateway and the Lambda function in addition to the Lambda Proxy Integration which glues the two together. Moreover, the required IAM role and the permission required for the API Gateway to invoke the Lambda are also created as part of the process.

CLI Tool

In order to work with Claudia, the CLI tool need to be installed. It can be installed as a global npm module, e.g. $ npm install claudia --global or you can install it as a test dependency $ npm install claudia --save-dev and then add the local node_modules/.bin directory to your $PATH. Verify by executing claudia --version. For a full list of the available command line args see the Command Args documentation or execute $ claudia --help. As an alternative (or rather as a complement) to the CLI tool, one can also write some deployment scripts by adding a few lines to the script part of the package.json file:

"scripts": {
    "create-app": "claudia create --region eu-west-1 --api-module index",
    "update": "claudia update"
}

The create-app script calls claudia create command (see link for details) and similarly the update script calls the claudia update command. To learn more about npm scripts, please read the blog Running scripts with npm authored by my colleague Anders Janmyr.

Lambda Function

Before looking at the Lambda implementation, we create a new npm project by executing $ npm init and provide some good answers. Add the claudia-api-builder to the project, e.g. $ npm install claudia-api-builder --save. Now, we can copy / paste the following lines to an index.js file in the project root:

'use strict';
    
const ApiBuilder = require('claudia-api-builder');
const api = new ApiBuilder();

module.exports = api;

api.get('/greeting', (request) => {
    console.log('Event:', JSON.stringify(request));
    const name = request.queryString.name || 'World';
    return {greeting: `Hello, ${name}!`};
});

The API builder is used to define a /greeting resource that expects a GET request. If the string contains a query string parameter called name it is used as part of the response, otherwise Hello, World! is returned as the greeting response. The request object contains all information that was passed from the client, e.g. HTTP headers, request body, the Lambda context object, the API Gateway context, etc. The return value can either be a simple JavaScript object as exemplified above, but it can also be a Promise or more complex data structures, dynamic response, custom response headers and so on, see the documentation for details. In contrast to the native CloudFormation API Gateway implementation (and the CloudFormation Swagger configuration for that matter) the Claudia API Builder maps all API Gateway resources automatically to a single Lambda function. If you would like to have a richer REST api, you simply register more http handlers with their paths by calling get, put, post or delete, very similar to how you would when you are developing a Node app that uses the Express web framework. In fact, with very little effort you can port an existing Express app to Claudia by just changing a couple of lines in the source code and importing the aws-serverless-express module, see Running Express Apps in AWS Lambda for details.

Deployment

Now we are ready to deploy. We do so by either calling the claudia create command. As a result, we will see the details of the resource that were created:

$ claudia create --region eu-west-1 --api-module index
[...]
saving configuration
{
    "lambda": {
    "role": "claudiajs-demo-executor",
    "name": "claudiajs-demo",
    "region": "eu-west-1"
    },
    "api": {
    "id": "[api-gateway-id]",
    "module": "index",
    "url": "https://[api-gateway-id].execute-api.eu-west-1.amazonaws.com/latest"
    }
}

where [api-gateway-id] is the id of your API Gateway. Alternatively we can use the npm script mentioned earlier with a similar result:

$ npm run create-app
[...]
saving configuration
[...]

After the deployment, we can verify that the API Gateway and Lambda function has been deployed successfully:

$ curl https://[api-gateway-id].execute-api.eu-west-1.amazonaws.com/latest/greeting
{"greeting":"Hello, World!"}
[...]
$ curl https://[api-gateway-id].execute-api.eu-west-1.amazonaws.com/latest/greeting?name=Superman
{"greeting":"Hello, Superman!"}

Considerations

  • There are other tools that can help with API Gateway and Lambda configuration and deployment such as Serverless and Seneca that you may find interesting. Start by reading the comparison guide in the Claudia FAQ for a brief overview. There is also the aws-serverless-express library from AWS Labs.
  • A claudia.json file will be created after the initial call to claudia create. This file contains your project specific Claudia configuration and should typically be added to version control so that your team mates and build server work against the same environment.
  • If you need to start over (or shut down the application), there is the claudia destroy command.
  • As mentioned Claudia is a deployment tool that uses the AWS JavaScript SDK. It does not use CloudFormation and thus you cannot use CloudFormation to track your resources.
  • Another consequence of not using CloudFormation is that you need to think twice about how you configure the Lambda functions when calling external services such as DynamoDB. The Claudia documentation provides a checklist for integration tips, including guidelines for setting up IAM privileges and using stage variables for differentiation between environments. You can use a similar approach to detect the environment configuration without API Gateway.
  • If you do not fancy the claudia-api-builder, you can still create a proxy Lambda function using Claudia. This can be useful if your clients use the Lambda API of an AWS SDK instead of a REST client when communicating with your backend.

More Resources

More information and links are available at the Claudia.js website, for example:

Updated: