AWS Lambda framework for building functions using Node.js for API Gateway, IoT applications, and other AWS events.
- Simplifies writing lambda handlers
- Automatically verifies event types
- Powerful input validation
- Works with Serverless
- JSON Web Token (JWT) verification and validation
- JWK support for retrieving keys at startup
- Automatic loading of environment variables from SSM Parameter Store
- Cross Site Request Forgery (XSRF) detection when using JWT
- SQL Injection (SQLi) detection and protection
- Lambda Proxy Resource support for AWS API Gateway
- Handler initialization for allocating resources
- Post handler execution to allow deallocation of resources
- Forces values into correct types
- Handles uncaught exceptions
- Promise support
- Automatically trimmed strings for input event data
- Low startup overhead
- AWS Lambda Node.js 12.x
Install via npm
npm install vandium --save
Vandium creates event specific handlers to reduce the amount of code than one
needs to maintain. The following handler code will response with a message when
executed using the AWS API Gateway with a GET
request:
const vandium = require( 'vandium' );
// handler for an api gateway event
exports.handler = vandium.api()
.GET( (event) => {
// return greeting
return 'Hello ' + event.pathParmeters.name + '!';
});
The framework can process asynchronous responses using promises. The following code returns a User object from a datastore asynchronously:
const vandium = require( 'vandium' );
// our datastore access object
const Users = require( './users' );
// handler for an api gateway event
exports.handler = vandium.api()
.GET( (event) => {
// returns a promise that resolves the User by name
return Users.getUser( event.pathParmeters.name );
});
Additionally, resources can be closed at the end, success or failure, of the handler. Failure to close resources might cause the lambda function to timeout or run for longer than is required. The following code demonstrates closing a cache after the handler has been called:
const vandium = require( 'vandium' );
// our datastore access object
const Users = require( './users' );
// object caching - automatically connects on first access
const cache = require( './cache' );
// handler for an api gateway event
exports.handler = vandium.api()
.GET( (event) => {
// returns a promise that resolves the User by name
return Users.getUser( event.pathParmeters.name );
})
.finally( () => {
// returns a promise that closes the cache connection
return cache.close();
});
Vandium targets specific event types to allow validation and targeting of specific event specific data. The following event types are supported by the framework:
Note: The generic
handler for custom or generic handling of any of the event types if further control or customization is required.
Vandium provides the opportunity for initialization code to be executed on each invocation of your handler. The before()
method is used to
define code that gets called before the handler to do things like open a database connection or connect with a cache instance.
The following example demonstrates how you can use the before()
method to open a cache before the handler is called:
const vandium = require( 'vandium' );
const User = require( './user' );
const cache = require( './cache' );
exports.handler = vandium.api()
.before( (context) => {
return cache.connect();
})
.GET( (event, context) => {
// handle get request
return User.get( event.pathParmeters.name );
})
.POST()
.validation({
// validate
body: {
name: vandium.types.string().min(4).max(200).required()
}
})
.handler( (event) => {
// handle POST request
return User.create( event.body.name );
});
The code inside the before()
method can be:
- Synchronous
- Asynchronous (in the form of
(context, callback)=> {}
) - Promise
And any result returned will be stored in context.additional
and can be accessed in the handler and finally()
methods.
Note: If an exception is thrown in the before()
method, then the finally()
method will not be called.
You can clean up and free resources using the finally()
method on all event handlers. The finally()
method is executed after each
execution of the handler if your code has been executed. If an exception is raised within the finally()
function, it will get logged and
execution will continue.
The following example shows how you can use the finally()
method to free a cache connection after each execution using the api
event
type:
const vandium = require( 'vandium' );
const User = require( './user' );
const cache = require( './cache' );
exports.handler = vandium.api()
.before( (context) => {
return cache.connect();
})
.GET( (event) => {
// handle get request
return User.get( event.pathParmeters.name );
})
.POST()
.validation({
// validate
body: {
name: vandium.types.string().min(4).max(200).required()
}
})
.handler( (event) => {
// handle POST request
return User.create( event.body.name );
})
.finally( () => {
// close the cache if open - gets executed on every call
return cache.close();
});
Note: If an exception is thrown during the validation and verification, such as JWT processing, phase prior to your code
execution, then the code inside finally()
will not get called.
If you would like to specify configuration using a configuration file, you can place a vandium.json
file at the root of your project. The
file is a standard JSON file with the following structure:
{
"jwt": {
"algorithm": "<algorithm-type>",
"publicKey": "<public key>", // if using RS256
"secret": "<secret value>", // if using HS256, HS384 or HS512
"token": "<token path inside event>",
"xsrf": "true | false",
"xsrfToken": "<xsrf token path inside element>",
"xsrfClaim": "<xsrf claim path inside jwt element>"
},
"prevent": {
"eval": "true | false" // prevents the use of eval()
}
}
Vandium can automatically load environment variable values from the AWS SSM Parameter Store. The environment variables are
loaded synchronously and thus will be set before any other code is loaded. To provide the SSM path where the environment variables
are located, set the VANDIUM_PARAM_STORE_PATH
environment variable at deployment time. We recommend using a path-based approach to
storing environment variables using the following convention:
/<group name>/<stage>/env
where the <group name>
might be the name of the service or function name, and the <stage>
would represent "production", "test", etc.
The format is user defined by the path and all values underneath the path will be loaded from SSM.
Note:* Please ensure that your Lambda function has the correct permissions to access the SSM Parameter Store including access to custom KMS keys (if used to encrypt secrets).
If you require support for Node 8, then use Vandium 4.x
The cloudwatch
event has now been renamed to logs
and this will require a source code change.
We'd love to get feedback on how to make this tool better. Feel free to contact us at [email protected]