Skip to content

Quick start Jersey

Dennis Kieselhorst edited this page Apr 8, 2024 · 27 revisions

You can use the aws-serverless-java-container library to run a JAX-RS Jersey application in AWS Lambda. You can use the library within your Lambda handler to load your Jersey application and proxy events to it.

In the repository we have included a sample Jersey application to get you started.

The current version of the Serverless Java Container (2.x) supports applications using Jersey 3.x (with Jakarta EE platform 9 therefore using the jakarta.* namespace). For applications using Jersey 2.x (2.26 or higher), you need to use Serverless Java Container version 1.x.

Maven archetype

You can quickly create a new serverless Jersey application using our Maven archetype. First, make sure Maven is installed in your environment and available in your PATH. Next, using a terminal or your favorite IDE create a new application, the archetype groupId is com.amazonaws.serverless.archetypes and the artifactId is aws-serverless-jersey-archetype:

mvn archetype:generate -DgroupId=my.service -DartifactId=my-service -Dversion=1.0-SNAPSHOT \
       -DarchetypeGroupId=com.amazonaws.serverless.archetypes \
       -DarchetypeArtifactId=aws-serverless-jersey-archetype \
       -DarchetypeVersion=2.0.1

The archetype sets up a new project that includes a pom.xml file as well as a build.gradle file. The generated code includes a StreamLambdaHandler class, the main entry point for AWS Lambda; a resource package with a /ping resource; and a set of unit tests that exercise the application.

The project also includes a file called template.yml. This is a SAM template that you can use to quickly test your application in local or deploy it to AWS. Open the README.md file in the project root folder for instructions on how to use the SAM CLI to run your Serverless API or deploy it to AWS.

Manual setup / Converting existing projects

1. Import dependencies

The first step is to import the Jersey implementation of the library:

<dependency>
    <groupId>com.amazonaws.serverless</groupId>
    <artifactId>aws-serverless-java-container-jersey</artifactId>
    <version>2.0.1</version>
</dependency>

This will automatically also import the aws-serverless-java-container-core and aws-lambda-java-core libraries.

2. Create the Lambda handler

In your application package declare a new class that implements Lambda's RequestStreamHandler interface. If you have configured API Gateway with a proxy integration, you can use the built-in POJOs AwsProxyRequest and AwsProxyResponse.

The next step is to declare the container handler object. The library exposes a utility static method that configures a JerseyLambdaContainerHandler object for AWS proxy events. The method receives an initialized ResourceConfig object. The handler object should be declared as a class property and be static. By doing this, Lambda will re-use the instance for subsequent requests.

The handleRequest method of the class can use the handler object we declared in the previous step to send requests to the Jersey application.

public class StreamLambdaHandler implements RequestStreamHandler {
    private static final ResourceConfig jerseyApplication = new ResourceConfig()
                                                             .packages("com.amazonaws.serverless.sample.jersey")
                                                             .register(JacksonFeature.class);
    private static final JerseyLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler
            = JerseyLambdaContainerHandler.getAwsProxyHandler(jerseyApplication);
    // If you are using HTTP APIs with the version 2.0 of the proxy model, use the getHttpApiV2ProxyHandler
    // method: 
    // JerseyLambdaContainerHandler<HttpApiV2ProxyRequest, AwsProxyResponse> handler = 
    //        JerseyLambdaContainerHandler.getHttpApiV2ProxyHandler(jerseyApplication);

    @Override
    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context)
            throws IOException {
        handler.proxyStream(inputStream, outputStream, context);
    }
}

In our sample application, resource classes are declared in the com.amazonaws.serverless.sample.jersey package.

3. Servlet injection

The aws-serverless-java-container-jersey includes Jersey suppliers and HK2 factory classes to inject HttpServletRequest, HttpServletResponse, and ServletContext objects for your methods.

If you initialize the JerseyLambdaContainerHandler with a Jersey ResourceConfig object, the suppliers are registered automatically and you'll be able to use the @Context annotations to inject the servlet object in your methods without any additional code.

@Path("/my-servlet") @GET
public String echoServletHeaders(@Context HttpServletRequest context) {
    Enumeration<String> headerNames = context.getHeaderNames();
    while (headerNames.hasMoreElements()) {
        String headerName = headerNames.nextElement();
    }
    return "servlet";
}

If you have created a custom Jax RS Application object, you will need to manually register the suppliers. With Jersey, you can use the code below to register a new AbstractBinder().

ResourceConfig app = new ResourceConfig()
    .packages("com.amazonaws.serverless.proxy.test.jersey")
    .register(new AbstractBinder() {
        @Override
        protected void configure() {
            bindFactory(AwsProxyServletContextSupplier.class)
                .to(ServletContext.class).in(RequestScoped.class);
            bindFactory(AwsProxyServletRequestSupplier.class)
                .to(HttpServletRequest.class).in(RequestScoped.class);
            bindFactory(AwsProxyServletRequestSupplier.class)
                .to(HttpServletResponse.class).in(RequestScoped.class);
        }
    });

4. Publish your Lambda function

You can follow the instructions in AWS Lambda's documentation on how to package your function for deployment.