Skip to content
This repository was archived by the owner on Jun 23, 2021. It is now read-only.

AWS Lambda

James Hood edited this page Oct 13, 2019 · 6 revisions

This application uses AWS Lambda for executing application logic. This page includes patterns and best practices for working with Lambda that are used in this application.

Use AWS::Serverless::Function to define Lambda functions in CloudFormation

AWS::Serverless::Function is a special resource type provided by AWS SAM, which simplifies configuration of Lambda functions and related resources such as IAM roles, permissions, and event source mappings. When using AWS::Serverless::Function, there are additional best practices:

  1. If your organization allows you to create your own IAM roles within your CloudFormation templates, use SAM policy templates to simplify Lambda function permissions while maintaining least privilege best practices.
  2. For Lambda functions that will synchronously process API requests, enable gradual code deployment via AWS CodeDeploy in production with rollback triggers on API CloudWatch alarms. AWS SAM makes this configuration very simple.

Examples in this project:

  1. Using AWS::Serverless::Function to define the API Lambda function.
  2. Simplifying Lambda function permissions using SAM policy templates.
  3. Enabling gradual code deployment. Note, a conditional is used so deployment is gradual in production, but fast in development and test environments. Gradual code deployment is configured to automatically fail the deployment and rollback if configured API alarms go into alarm state during the gradual code deployment.

Use a serverless API router library

For Lambda functions that service API requests from Amazon API Gateway, we've found it best to use a library to automatically route API requests to the right handler method within your Lambda function code. Popular examples of serverless API router libraries are aws-serverless-java-container (Java) and aws-serverless-express (Node.js).

Whether all API operations should be handled by a single Lambda function or separate Lambda functions is still a heated topic within the serverless community. However, we've found using an API router library gives you the flexibility to choose either option or something in between, without having to change your Lambda function code.

Examples in this project:

  1. This project uses aws-serverless-java-container for Jersey. Jersey is an implementation of JAX-RS, the Java API for RESTful Web Services.
  2. The swagger-codegen-maven-plugin is configured to generate API model classes based on the OpenAPI API definition. At build time, this generates Java classes for all API request and response objects as well as a JAX-RS annotated Java interface for the API itself.
  3. The ApplicationService class implements the generated interface and supplies the business logic of each API operation. For example, it provides the business logic of the CreateApplication operation.
  4. Within the Lambda handler class for the API Lambda function, the Jersey application is configured and passed to a JerseyLambdaContainerHandler handler instance provided by the aws-serverless-java-container library. All Lambda requests are passed to the handler, which routes the request to the right method in the ApplicationsService class.

Optimize the AWS Java SDK for better coldstart performance

Use best practices around configuring the AWS Java SDK for use in Lambda environments:

  1. Use the AWS Java SDKv2 with suggested optimizations for Lambda.
  2. Add dependencies on only the specific service clients needed for the project to minimize overall size of the Lambda binary.
  3. Customize SDK timeout and retry configuration for your application. The default SDK timeout and retry values may not make sense for the AWS service being called or the constraints of the backend service environment. In the worst case, the default settings can result in high latencies and/or availability risks to the backend service.

Examples in this project:

  1. Adding dependencies on the minimum AWS Java SDKv2 components needed by the backend: url-connection-client, DynamoDB, and KMS.
  2. Following suggested SDK configuration for Lambda environments.
  3. Customizing timeout and retry policy for DynamoDB client. Rationale: DynamoDB requests should normally have single digit millisecond response times so allow many retries, but cap the total request duration at 1 second to ensure API latency doesn't get out of control if the service is taking longer than usual to respond.
Clone this wiki locally