Use Jersey and Spring in AWS Lambda

AWS Lambda is actually made to be used by implementing small functions which can be started quickly. So your code artifact should be as small as possible for a fast startup time. However, in the Java world there are nice frameworks like Jersey and Spring which can help you writing code for an API a lot! Unfortunately these frameworks can take up to a few MB and blow up your artifact, but you might have your reasons to use them in AWS Lambda, e.g. because you’re migrating an existing project to AWS Lambda. So let’s see, how you can use Jersey and Spring together in AWS Lambda! The code can be found in my GitHub repository lambda-jersey-spring-example.

A good starting point is the aws-serverless-java-container project on GitHub. It provides Maven modules to support Jersey, Spring and Spark framework. Nice, so let’s get started and include the relevant Maven dependencies:

(As you can see, this also includes the dependencies to write AWS Lambda functions in Java)

The next step is to add a Lambda function using RequestHandler interface of aws-lambda-java-core from aws-lambda-java-libs on GitHub.

This is the most important part where Jersey and Spring are glued together. So, what’s done here? There are three simple things:

  1. A Spring context is created using an annotation based config.
  2. A bean of a custom Jersey configuration class JerseyResourceConfig is retrieved from the Spring context. The class registers the actual Jersey resources (see below) which are also available in the Spring context.
  3. The Jersey configuration bean is used to handle all incoming requests.

Now, let’s take a look at the JerseyResourceConfig and how the resources are registered:

Quite simple, isn’t it? Ok, so the following snippets show the code for a simple Spring annotation config and one of the sample Jersey resources.

Nothing special here as you can see. It’s just using another DefaultService to prove that autowiring a bean works as expected. In order to complete the example, the following listing shows you a sample YAML CloudFormation configuration for the Lambda function.

Please consider that in case you’re using another Api path for your Lambda function, e.g. /api/{proxy+}, you must call handler.setBasePath("/api") in JerseySpringHandler so that the path matching will work for Jersey. Another point worth noting is that such a simple example is using about 12 MB for the target JAR file. This is huge compared to what you get when accomplishing the same using NodeJS, so use these frameworks with care! In my opinion you don’t need a Spring or Jersey framework if you’re developing a real Lambda function.

That’s it! You’re done and can add more Jersey resources if you have to. If you are interested in more AWS Lambda content, please take a look at other examples about AWS Lambda and my top 5 tips on writing a Lambda function.