Using external services

The real power of Lambda functions comes from the ability to easily wire up and call into other services, both those inside AWS and outside it. Here’s a quick check-list for making sure to avoid the most common errors.

1. Plan your execution time

Lambda functions are, by default, limited to 3 seconds. If you plan to call out into external services, make sure to allow for enough time for external calls. You can configure the maximum allowed time by using --timeout option of claudia create, or aws lambda update-function-configuration --timeout for existing functions. Check out the Claudia Create Docs and AWS CLI Docs for more information.

2. Implement a circuit-breaker

Whenever you make an external call, you’re introducing one more component that can get stuck, fail, timeout or delay your workflow, and it’s outside your control. Don’t let Lambda just kill the function with an error, but handle such problems gracefully. Most external call libraries have some sort of a timeout feature, allowing you to stop the call if it takes too long. Remember to make this shorter than the total allowed Lambda execution time, so you have enough time to clean up and respond to users with a sensible error.

3. Use Promises when possible

If you’re using claudia-api-builder or claudia-bot-builder, remember that they both work with Promises for asynchronous calls. If the third party service supports promises, use that to easily work with asynchronous calls. AWS SDK also supports promises, just call the .promise() method after you set up the request. Check out the DynamoDB Example to see this in action.

4. Return a Promise out of the API handler

If you’re using claudia-api-builder or claudia-bot-builder, remember to return a Promise object out of the API handler or your bot function. If you just execute the external call, without returning the promise, Lambda will most likely kill the function before the external service responds. For example, this API won’t work well:

api.post('/user', function (request) {
	dynamoDb.put({
		TableName: request.env.tableName,
		Item: {	userid: request.body.userId }
	}).promise();
}); 

This call will work well – hint: check out the return keyword before dynamoDb.put

api.post('/user', function (request) {
	return dynamoDb.put({
		TableName: request.env.tableName,
		Item: {	userid: request.body.userId }
	}).promise();
}); 

5. Clean up before responding to users

Since version 1.5.1, claudia-api-builder asks Lambda to kill the container immediately after the function ends. This improves container reuse and responsiveness for future calls. At the same time, this means that you need to clean up and release resources before the final Promise resolves. Any pending cleanup tasks, still in the Node.js event loop after your Promise resolves, will likely will not be executed. If the third-party service has cleanup tasks which stay in the Node.js event loop after the call ends, you may want to reconfigure the API. Check out the 1.5.1 Release Notes for more information.

6. Set up IAM access privileges

Lambda executes your function under a configured IAM role. By default, Claudia creates a new role for each function, without access to any other AWS services. If you want to access any resources on AWS, you have to explicitly allow your function to do that.

If you’d like to access other AWS resources with the privileges of the caller, or a specific IAM user/role different from the role of the Lambda function, check out how to Override access credentials.

7. Configure external access keys with environment variables or stage variables

If you plan to use third-party services that require authentication, consider storing the access keys in API stage variables or environment variables of your Lambda function. Check out Managing Lambda Versions for information on how to create different stages and assign variable values.

Did you like this tutorial? Get notified when we publish the next one.

Once a month, high value mailing list, no ads or spam. (Check out the past issues)