Quarkus - Amazon Lambda with RESTEasy, Undertow, or Vert.x Web

With Quarkus you can deploy your favorite Java HTTP frameworks as Amazon Lambda’s using either the AWS Gateway HTTP API or AWS Gateway REST API. This means that you can deploy your microservices written with RESTEasy (JAX-RS), Undertow (servlet), Vert.x Web, Funqy HTTP or any other Quarkus HTTP framework as an AWS Lambda.

You can deploy your Lambda as a pure Java jar, or you can compile your project to a native image and deploy that for a smaller memory footprint and startup time. Our integration also generates SAM deployment files that can be consumed by Amazon’s SAM framework.

Quarkus has a different extension for each Gateway API. The HTTP Gateway API is implemented within the quarkus-amazon-lambda-http extension. The REST Gateway API is implemented within the quarkus-amazon-lambda-rest extension. If you are confused on which Gateway product to use, Amazon has a great guide to help you navigate this decision.

This technology is considered preview.

In preview, backward compatibility and presence in the ecosystem is not guaranteed. Specific improvements might require to change configuration or APIs and plans to become stable are under way. Feedback is welcome on our mailing list or as issues in our GitHub issue tracker.

For a full list of possible extension statuses, check our FAQ entry.


To complete this guide, you need:

Getting Started

This guide walks you through generating an example Java project via a maven archetype. Later on it walks through the structure of the project so you can adapt any existing projects you have to use Amazon Lambda.

Installing AWS bits

Installing all the AWS bits is probably the most difficult thing about this guide. Make sure that you follow all the steps for installing AWS SAM CLI.

Creating the Maven Deployment Project

Create the Quarkus AWS Lambda maven project using our Maven Archetype.

If you want to use the AWS Gateway HTTP API, generate your project with this script:

mvn archetype:generate \
       -DarchetypeGroupId=io.quarkus \
       -DarchetypeArtifactId=quarkus-amazon-lambda-http-archetype \

If you want to use the AWS Gateway REST API, generate your project with this script:

mvn archetype:generate \
       -DarchetypeGroupId=io.quarkus \
       -DarchetypeArtifactId=quarkus-amazon-lambda-rest-archetype \

Build and Deploy

Build the project using maven.

./mvnw clean install

This will compile the code and run the unit tests included within the generated project. Unit testing is the same as any other Java project and does not require running on Amazon. Quarkus dev-mode is also available with this extension.

If you want to build for native too, make sure you have GraalVM installed correctly and just add a native property to the build

./mvnw clean install -Dnative
If you are building on a non-Linux system, you will need to also pass in a property instructing quarkus to use a docker build as Amazon Lambda requires linux binaries. You can do this by passing this property to your Maven build: -Dnative-image.docker-build=true, or for Gradle: --docker-build=true. This requires you to have docker installed locally, however.
./mvnw clean install -Dnative -Dnative-image.docker-build=true

Extra Build Generated Files

After you run the build, there are a few extra files generated by the quarkus lambda extension you are using. These files are in the the build directory: target/ for maven, build/ for gradle.

  • function.zip - lambda deployment file

  • sam.jvm.yaml - sam cli deployment script

  • sam.native.yaml - sam cli deployment script for native

Simulate Amazon Lambda Deployment

The AWS SAM CLI allows you to run your lambda’s locally on your laptop in a simulated Lambda environment. This requires docker to be installed (see their install docs). After you have built your maven project, execute this command

sam local start-api --template target/sam.jvm.yaml

This will start a docker container that mimics Amazon’s Lambda’s deployment environment. Once the environment is started you can invoke the example lambda in your browser by going to

In the console you’ll see startup messages from the lambda. This particular deployment starts a JVM and loads your lambda as pure Java.

Deploy to AWS

sam deploy -t target/sam.jvm.yaml -g

Answer all the questions and your lambda will be deployed and the necessary hooks to the API Gateway will be set up. If everything deploys successfully, the root URL of your microservice will be output to the console. Something like this:

Key                 LambdaHttpApi
Description         URL for application
Value               https://234asdf234as.execute-api.us-east-1.amazonaws.com/

The Value attribute is the root URL for your lambda. Copy it to your browser and add hello at the end.

Responses for binary types will be automatically encoded with base64. This is different than the behavior using quarkus:dev which will return the raw bytes. Amazon’s API has additional restrictions requiring the base64 encoding. In general, client code will automatically handle this encoding but in certain custom situations, you should be aware you may need to manually manage that encoding.

Deploying a native executable

To deploy a native executable, you must build it with Graal.

./mvnw clean install -Dnative

You can then test the executable locally with sam local

sam local start-api --template target/sam.native.yaml

To deploy to AWS Lambda:

sam deploy -t target/sam.native.yaml -g

Examine the POM

There is nothing special about the POM other than the inclusion of the quarkus-amazon-lambda-http extension (if you are deploying an AWS Gateway HTTP API) or the quarkus-amazon-lambda-rest extension (if you are deploy an AWS Gateway REST API). These extensions automatically generate everything you might need for your lambda deployment.

Also, at least in the generated maven archetype pom.xml, the quarkus-resteasy, quarkus-vertx-web, and quarkus-undertow dependencies are all optional. Pick which http framework(s) you want to use (JAX-RS, Vertx Web, and/or Servlet) and remove the other dependencies to shrink your deployment.

Examine sam.yaml

The sam.yaml syntax is beyond the scope of this document. There’s a couple of things that must be highlighted just in case you are going to craft your own custom sam.yaml deployment files.

The first thing to note is that for pure Java lambda deployments require a specific handler class. Do not change the Lambda handler name.

        Handler: io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequest
        Runtime: java11

This handler is a bridge between the lambda runtime and the Quarkus HTTP framework you are using (JAX-RS, Servlet, etc.)

If you want to go native, there’s an environment variable that must be set for native GraalVM deployments. If you look at sam.native.yaml you’ll see this:


This environment variable resolves some incompatibilities between Quarkus and the Amazon Lambda Custom Runtime environment.

Finally, there is one specific thing for AWS Gateway REST API deployments. That API assumes that HTTP response bodies are text unless you explicitly tell it which media types are binary through configuration. To make things easier, the Quarkus extension forces a binary (base 64) encoding of all HTTP response messages and the sam.yaml file must configure the API Gateway to assume all media types are binary:

      EndpointConfiguration: REGIONAL
        - "*/*"

Injectable AWS Context Variables

If you are using Resteasy and JAX-RS, you can inject various AWS Context variables into your JAX-RS resource classes using the JAX-RS @Context annotation.

For the AWS HTTP API you can inject the AWS variables com.amazonaws.services.lambda.runtime.Context and com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPEvent. Here is an example:

import javax.ws.rs.core.Context;
import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPEvent;

public class MyResource {
    public String ctx(@Context com.amazonaws.services.lambda.runtime.Context ctx) { }

    public String event(@Context APIGatewayV2HTTPEvent event) { }

    public String requestContext(@Context APIGatewayV2HTTPEvent.RequestContext req) { }


For the AWS REST API you can inject the AWS variables com.amazonaws.services.lambda.runtime.Context and io.quarkus.amazon.lambda.http.model.AwsProxyRequestContext. Here is an example:

import javax.ws.rs.core.Context;
import io.quarkus.amazon.lambda.http.model.AwsProxyRequestContext;

public class MyResource {
    public String ctx(@Context com.amazonaws.services.lambda.runtime.Context ctx) { }

    public String req(@Context AwsProxyRequestContext req) { }


Tracing with AWS XRay and GraalVM

If you are building native images, and want to use AWS X-Ray Tracing with your lambda you will need to include quarkus-amazon-lambda-xray as a dependency in your pom. The AWS X-Ray library is not fully compatible with GraalVM so we had to do some integration work to make this work.