Introdução
Bem-vindo a esta série de artigos, um guia prático para construir uma aplicação serverless moderna com Java. Nosso objetivo é usar a combinação de Quarkus (com compilação nativa GraalVM) e AWS SAM para enfrentar desafios comuns do Java no ambiente serverless, como o tempo de inicialização (cold starts) e o consumo de memória.
Ao longo desta série, vamos cobrir o ciclo completo de desenvolvimento, desde a fundação até a segurança e a persistência de dados. O nosso roteiro será:
- Nesta Parte 1 (o artigo atual), focaremos nos fundamentos: a configuração do projeto, a criação de múltiplas funções Lambda e o deploy automatizado na AWS.
- Na Parte 2, adicionaremos uma camada de segurança, integrando nossa aplicação com o Amazon Cognito para gerenciar a autenticação e usando as Lambdas para interagir com a API de usuários.
- Na Parte 3, implementaremos a persistência de dados, adicionando uma tabela do Amazon DynamoDB à nossa infraestrutura e manipulando os dados através das Lambdas.
O nosso objetivo hoje é deixar a estrutura básica pronta e funcionando na nuvem. Vamos cobrir:
- A criação e estruturação de um projeto Java com Quarkus.
- A implementação das nossas primeiras funções Lambda.
- O deploy automatizado de toda a estrutura na AWS.
Pré-requisitos
Para acompanhar este tutorial da melhor forma, é ideal que você tenha um ambiente de desenvolvimento preparado. Não vamos cobrir a instalação detalhada de cada ferramenta, mas aqui estão os links e os comandos para você verificar se está tudo pronto para começar.
-
Java (JDK 21): Essencial para rodar o Quarkus e compilar o código. Neste tutorial, usamos a versão 21.
-
Verifique sua versão com:
java --version
-
Verifique sua versão com:
-
Gradle (8.5+): Usado para gerenciar as dependências e o build do projeto.
-
Verifique sua versão com:
gradle --version
- Não tem? Siga o: Guia Oficial de Instalação do Gradle
-
Verifique sua versão com:
-
AWS CLI v2: A ferramenta de linha de comando para interagir com a AWS. É importante que ela esteja configurada com suas credenciais.
-
Verifique sua versão com:
aws --version
- Não tem? Siga o: Guia Oficial de Instalação da AWS CLI
-
Verifique sua versão com:
-
AWS SAM CLI: A ferramenta principal que usaremos para o build e deploy da nossa aplicação serverless.
-
Verifique sua versão com:
sam --version
- Não tem? Siga o: Guia Oficial de Instalação da SAM CLI
-
Verifique sua versão com:
-
Container Runtime (Docker ou Podman): Requisito indispensável em nosso fluxo. Embora seja possível compilar uma imagem nativa instalando o GraalVM diretamente na sua máquina, neste tutorial usaremos a abordagem de build via contêiner. Isso garante que o executável seja gerado em um ambiente Linux consistente e compatível com o da AWS Lambda, evitando problemas de compatibilidade entre sistemas operacionais.
Precisaremos de um contêiner por dois motivos:
- Para o build nativo do Quarkus, usando a flag
-Dquarkus.native.container-build=true
. - Para o AWS SAM CLI, que o utiliza para simular o ambiente da AWS Lambda localmente.
-
Verifique se está rodando com:
docker info
oupodman info
- Opções de Instalação: Docker Desktop (mais comum) ou Podman (alternativa).
- Para o build nativo do Quarkus, usando a flag
-
Noções de Quarkus: Este guia presume uma familiaridade básica com os conceitos do Quarkus (como injeção de dependência com CDI e anotações JAX-RS para endpoints).
- Precisa de uma introdução? Confira os: Guias "Getting Started" do Quarkus
Criando o Projeto com Quarkus
Existem várias maneiras de se iniciar um projeto Quarkus, cada uma adequada a um estilo de trabalho diferente. As principais são:
- Via Linha de Comando (CLI): Para desenvolvedores que preferem o terminal, é possível usar a CLI oficial do Quarkus ou o próprio wrapper do Gradle para criar o projeto. É uma abordagem rápida e excelente para automação.
-
Via Gerador Web (
code.quarkus.io
): Uma interface web interativa onde você pode selecionar visualmente as dependências e configurações do seu projeto. É a maneira mais fácil e visual para começar.
Para este tutorial, seguiremos o caminho mais simples e intuitivo, que não exige a instalação de nenhuma ferramenta de linha de comando adicional: o site code.quarkus.io.
Se você já usou o Spring Initializr, a experiência será muito familiar. Ele nos permite configurar tudo visualmente e, ao final, baixar um arquivo .zip
com o projeto pronto para ser aberto na sua IDE preferida.
Vamos configurar nosso projeto com as seguintes especificações:
- Build Tool: Gradle
- Java Version: 21
-
Group: (use o de sua preferência, ex:
br.com.seudominio
) -
Artifact: (use o de sua preferência, ex:
sam-quarkus-app
)
Em seguida, adicione as seguintes extensões (dependências), que são a base para nossa aplicação serverless:
-
quarkus-amazon-lambda
: A extensão principal que adapta a aplicação Quarkus para ser executada como uma função AWS Lambda. -
quarkus-rest
(anteriormente RESTEasy Reactive): Fornece o framework JAX-RS para a criação de endpoints REST. -
quarkus-rest-jackson
: Adiciona o suporte para serialização e desserialização de objetos Java para JSON usando a biblioteca Jackson.
Após selecionar essas opções, clique em "Generate your application" para baixar o .zip
com o projeto. Descompacte-o e abra na sua IDE preferida.
Criando nossas primeiras Lambdas
Com o projeto devidamente configurado em nossa IDE, é hora de escrever o código que dará vida às nossas funções. O ponto central da nossa implementação girará em torno de duas dependências essenciais que já adicionamos via code.quarkus.io
.
A primeira e mais importante é a io.quarkus:quarkus-amazon-lambda
. É ela que faz a ponte entre o ecossistema Quarkus e o runtime da AWS Lambda. Essa extensão é a responsável por nos permitir criar classes que atuam como handlers e nos dá acesso direto às interfaces cruciais da AWS, como RequestHandler
, APIGatewayProxyRequestEvent
(para receber dados do API Gateway) e APIGatewayProxyResponseEvent
(para formular a resposta).
A segunda peça-chave é a io.quarkus:quarkus-rest-jackson
. No contexto de uma API, nossos dados trafegam em formato JSON. Esta biblioteca nos fornece o poder da serialização e desserialização de forma transparente. Com ela, conseguimos facilmente converter um JSON recebido no corpo da requisição em um objeto Java (um DTO, por exemplo) e, no caminho inverso, transformar nossos objetos de resposta em uma string JSON válida para o cliente.
Com essas duas ferramentas em mãos, estamos prontos para estruturar nosso código.
Criando nossos primeiros handlers
Com o projeto estruturado, vamos criar e analisar nossas classes Handler. Começaremos com um exemplo mínimo e depois avançaremos para um que manipula dados de entrada e saída em JSON.
Exemplo 1: Um "Olá, Mundo" Simples (GreetingsHandler
)
Nosso primeiro handler é o mais básico possível: ele não recebe dados de entrada e retorna uma mensagem de texto simples.
// Em: src/main/java/.../handler/GreetingsHandler.java
@ApplicationScoped
@Named("greetingsHandler")
public class GreetingsHandler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
@Override
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) {
// Lógica para criar e retornar uma resposta HTTP 200 OK
APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
response.setStatusCode(200);
response.setHeaders(Collections.singletonMap("Content-Type", "text/plain; charset=utf-8"));
response.setBody("Olá do Quarkus Lambda!");
return response;
}
}
Vamos nos concentrar nos três pontos fundamentais que já discutimos:
- Gerenciamento com CDI (
@ApplicationScoped
): Integra o handler ao Quarkus, transformando-o em um bean gerenciável. - A Identidade da Lambda (
@Named("greetingsHandler")
): Atribui um ID único que usaremos notemplate.yaml
para conectar a infraestrutura a esta classe específica. - O Contrato com a AWS (
RequestHandler
): Define a classe como um ponto de entrada de Lambda, especificando os tipos de evento de entrada e saída do API Gateway.
Exemplo 2: Uma Lambda com Lógica e JSON (CalculatorHandler
)
Agora, vamos criar um exemplo mais prático. O CalculatorHandler
receberá um JSON com dois números, fará uma soma e retornará o resultado em outro JSON.
Definindo as Estruturas de Dados (DTOs)
Primeiro, precisamos de classes para modelar os dados de entrada (CalculationRequest
) e saída (CalculationResponse
). Crie estes dois arquivos no seu pacote dto
.
// Em: src/main/java/.../dto/CalculationRequest.java
package br.com.seudominio.samquarkusapp.dto;
import io.quarkus.runtime.annotations.RegisterForReflection;
@RegisterForReflection
public class CalculationRequest {
private double number1;
private double number2;
// Getters e Setters
public double getNumber1() { return number1; }
public void setNumber1(double number1) { this.number1 = number1; }
public double getNumber2() { return number2; }
public void setNumber2(double number2) { this.number2 = number2; }
}
// Em: src/main/java/.../dto/CalculationResponse.java
package br.com.seudominio.samquarkusapp.dto;
import io.quarkus.runtime.annotations.RegisterForReflection;
@RegisterForReflection
public class CalculationResponse {
private double result;
private String operation;
public CalculationResponse(double result, String operation) {
this.result = result;
this.operation = operation;
}
// Getters e Setters
public double getResult() { return result; }
public void setResult(double result) { this.result = result; }
public String getOperation() { return operation; }
public void setOperation(String operation) { this.operation = operation; }
}
Ponto de Atenção: @RegisterForReflection
Esta anotação é essencial para a compilação nativa com GraalVM. A biblioteca Jackson usa reflexão para criar instâncias dessas classes a partir de um JSON e para ler seus campos ao gerar um JSON. Na compilação nativa, o GraalVM elimina qualquer código que ele acha que não é usado. A anotação @RegisterForReflection
avisa ao Quarkus para preservar as informações dessas classes (construtores, getters, setters), garantindo que o Jackson consiga usá-las em tempo de execução.
Implementando o Handler
Agora, crie a classe CalculatorHandler
no pacote handler
.
// Em: src/main/java/.../handler/CalculatorHandler.java
@ApplicationScoped
@Named("calculatorHandler")
public class CalculatorHandler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
// Para fins didáticos, mas a injeção de dependência é preferível.
private static final ObjectMapper objectMapper = new ObjectMapper();
@Override
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) {
try {
// 1. pega o corpo da requisição (que é uma string json)
String body = input.getBody();
// 2. desserializa a string JSON em um objeto Java
CalculationRequest data = objectMapper.readValue(body, CalculationRequest.class);
// 3. executa a lógica de negócio
double sum = data.getNumber1() + data.getNumber2();
context.getLogger().log(String.format("Calculando: %f + %f = %f",
data.getNumber1(), data.getNumber2(), sum));
// 4. cria o objeto de resposta
CalculationResponse responsePayload = new CalculationResponse(sum, "soma");
// 5. serializa o objeto de resposta de volta para uma string JSON e retorna
return new APIGatewayProxyResponseEvent()
.withStatusCode(200)
.withHeaders(Map.of("Content-Type", "application/json"))
.withBody(objectMapper.writeValueAsString(responsePayload));
} catch (Exception e) {
context.getLogger().log("Erro ao processar: " + e.getMessage());
return new APIGatewayProxyResponseEvent()
.withStatusCode(400) // Bad Request
.withHeaders(Map.of("Content-Type", "application/json"))
.withBody("{\"message\":\"Corpo da requisição inválido.\"}");
}
}
}
Este handler segue o mesmo padrão, mas sua lógica interna é mais rica:
- Ele recebe o corpo da requisição, que esperamos ser um JSON como
{"number1": 10, "number2": 20}
. - Usa o
objectMapper.readValue
para converter essa string em um objetoCalculationRequest
. - Executa a soma.
- Cria um objeto
CalculationResponse
. - Usa o
objectMapper.writeValueAsString
para converter o objeto de resposta em uma string JSON antes de enviá-lo de volta com um status200 OK
.
Buildando nosso executável nativo
Com nosso handler Java pronto, o próximo passo é compilá-lo. No entanto, este não é um build comum que gera um .jar
; nosso objetivo é criar um executável nativo para Linux, a chave para obtermos a performance excepcional que o Quarkus com GraalVM promete.
Lembre-se que, como definimos nos pré-requisitos, este processo exige um container runtime (como Docker ou Podman) ativo, pois usaremos a estratégia de build dentro de um contêiner para garantir total compatibilidade com o ambiente da AWS Lambda.
Temos duas maneiras principais de executar o build. Ambas chegam ao mesmo resultado.
Opção 1: Usando o Gradle Wrapper (Recomendado)
Esta é a forma mais direta, pois não exige a instalação de nenhuma ferramenta adicional, utilizando apenas o Gradle que já vem configurado no projeto.
Abra seu terminal na raiz do projeto e execute o comando:
./gradlew build -x test "-Dquarkus.native.enabled=true" "-Dquarkus.native.container-build=true" "-Dquarkus.package.jar.enabled=false"
Vamos entender cada parte:
-
./gradlew build
: O comando padrão para iniciar o build com o Gradle. -
-x test
: Um comando do Gradle para pular a execução dos testes, agilizando o processo de build. -
"-Dquarkus.native.enabled=true"
: A chave que liga o "modo nativo", instruindo o Quarkus a iniciar a compilação com GraalVM. -
"-Dquarkus.native.container-build=true"
: Informa ao Quarkus para realizar o build dentro de um contêiner. Isso garante que o executável seja gerado em um ambiente Linux consistente e compatível com o da AWS. -
"-Dquarkus.package.jar.enabled=false"
: Uma pequena otimização. Como nosso foco é 100% no executável nativo, dizemos ao Quarkus para não se preocupar em gerar os.jar
s tradicionais.
Opção 2: Usando a Quarkus CLI
Para quem prefere uma linha de comando mais limpa e tem a CLI do Quarkus instalada, o comando é um pouco mais enxuto:
quarkus build --native --no-tests "-Dquarkus.native.container-build=true"
As flags --native
e --no-tests
são atalhos para as propriedades equivalentes que vimos no comando do Gradle.
O Resultado
Independentemente do comando escolhido, o processo será o mesmo. Você verá o terminal exibir bastante informação, incluindo o download da imagem do builder (na primeira vez) e os passos da compilação GraalVM. Este processo pode levar alguns minutos!
Ao final, se tudo correu bem, você terá o nosso tão esperado artefato pronto para o deploy no seguinte caminho:
build/function.zip
Este arquivo .zip
contém nosso executável Linux (bootstrap
) pronto para ser executado na AWS Lambda. É este o artefato que, na próxima seção, diremos ao AWS SAM para usar.
A Receita da Nossa Infraestrutura: O template.yaml
Com nosso código Java agora contendo dois handlers, precisamos atualizar nosso arquivo de manifesto, o template.yaml
, para dizer à AWS como expor ambas as funções.
Pense neste arquivo como a planta da nossa aplicação serverless. É um documento que descreve, de forma declarativa, toda a infraestrutura que a AWS deve construir e gerenciar para nós. Agora, ele descreverá duas funções Lambda e seus respectivos endpoints de API.
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Globals:
Function:
Runtime: provided.al2023
Handler: io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequest
Architectures: [ x86_64 ]
MemorySize: 128
Timeout: 15
CodeUri: build/function.zip
Environment:
Variables:
DISABLE_SIGNAL_HANDLERS: "true"
Resources:
GreetingsFunction:
Type: AWS::Serverless::Function
Properties:
Environment:
Variables:
QUARKUS_LAMBDA_HANDLER: greetingsHandler
Events:
GetGreetings:
Type: Api
Properties:
Path: /greetings
Method: get
CalculatorFunction:
Type: AWS::Serverless::Function
Properties:
Environment:
Variables:
QUARKUS_LAMBDA_HANDLER: calculatorHandler
Events:
PostCalculate:
Type: Api
Properties:
Path: /calculator/sum
Method: post
Outputs:
ApiUrl:
Description: "URL do endpoint do Api Gateway:"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/"
Pode parecer complexo, mas é bastante lógico. Vamos analisar cada bloco.
Globals
: Os Padrões da Construção
A seção Globals
nos ajuda a não repetir código. As configurações definidas aqui valem como padrão para todas as funções do nosso projeto, o que é especialmente útil agora que temos duas.
-
Runtime: provided.al2023
: Como nosso build com GraalVM gera um executável Linux autossuficiente, usamosprovided
para dizer à AWS: "nós estamos fornecendo nosso próprio executável". A imagemal2023
garante a presença de bibliotecas essenciais, como aglibc
, que nosso executável nativo precisa. -
Handler: io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequest
: Este é o "roteador" genérico do Quarkus. A AWS sempre chamará este ponto de entrada, que por sua vez se encarregará de direcionar a requisição para o nosso bean@Named
correto. -
CodeUri: build/function.zip
: Aponta para o arquivo.zip
que contém nosso executável nativo. Note que ambas as funções usam o mesmo artefato de código. -
Environment -> DISABLE_SIGNAL_HANDLERS: "true"
: Uma variável de ambiente crucial para a execução nativa, que resolve incompatibilidades entre o Quarkus e o ambiente Custom Runtime da AWS.
Resources
: Desenhando a Estrutura Principal
Agora, definimos dois componentes na nossa infraestrutura.
A primeira função: GreetingsFunction
-
GreetingsFunction:
: O nome lógico da nossa primeira função Lambda. -
Type: AWS::Serverless::Function
: Especifica que estamos criando uma função Lambda. -
Properties
: As configurações específicas deste "cômodo".-
Environment -> Variables -> QUARKUS_LAMBDA_HANDLER: greetingsHandler
: O valorgreetingsHandler
é o mesmo que usamos na anotação@Named("greetingsHandler")
. É assim que o roteador do Quarkus sabe qual classe Java executar.
-
-
Events:
: Define a "porta de entrada" da função.-
Path: /greetings
eMethod: get
: Mapeia a função para ser acionada por uma requisiçãoGET
no caminho/greetings
.
-
A segunda função: CalculatorFunction
Observe como a definição da nossa segunda função segue exatamente o mesmo padrão. Uma vez que a estrutura está montada, adicionar novas funções se torna uma tarefa simples de "copiar, colar e ajustar".
-
CalculatorFunction:
: O nome lógico da nossa nova função de cálculo. -
Properties
:-
QUARKUS_LAMBDA_HANDLER: calculatorHandler
: E aqui está a conexão para o nosso segundo handler. O valorcalculatorHandler
corresponde exatamente à anotação@Named("calculatorHandler")
da nossa classeCalculatorHandler.java
.
-
-
Events:
:-
Path: /calculator/sum
eMethod: post
: Mapeamos esta função para um caminho diferente (/calculator/sum
) e um método HTTP diferente (post
), ideal para enviar dados no corpo da requisição.
-
Outputs
: Recebendo o Endereço Final
Esta seção não muda. Ela instrui o SAM a nos mostrar a URL base da nossa API, que agora servirá de ponto de entrada para os dois endpoints que criamos.
-
ApiUrl
: Define uma saída de informação com a URL base da API.
Fazendo o deploy da nossa aplicação serverless
Com nosso executável nativo empacotado no function.zip
e a planta da nossa infraestrutura definida no template.yaml
, temos todas as peças do quebra-cabeça. Agora, vamos usar o AWS SAM CLI para montar tudo na nuvem.
Pré-requisitos para o Deploy
Antes de prosseguirmos, é crucial garantir que seu ambiente de linha de comando consegue se comunicar com sua conta da AWS. Verifique se você cumpriu os seguintes pontos, que mencionamos no início do artigo:
-
AWS CLI configurada e autenticada: O SAM CLI usa as credenciais configuradas na AWS CLI. Você precisa estar autenticado em uma conta da AWS.
- O caminho mais direto para este tutorial é configurar a CLI com uma Access Key e Secret Key de um usuário IAM.
- Usuários mais avançados podem usar outros métodos, como o
aws sso login
, que foi o que utilizei para preparar este artigo, autenticando-me em uma conta filha gerenciada pelo AWS Organizations.
AWS SAM CLI instalado: Essencial para interpretar nosso template e orquestrar o deploy.
Passo 1: Validando nosso template.yaml (sam validate
)
Antes de pedir para o SAM construir nossa infraestrutura, é uma boa prática pedir para ele revisar nosso arquivo. O comando sam validate
faz exatamente isso: ele lê seu template.yaml
e verifica se há erros de sintaxe ou de lógica, sem custar nada e sem criar nenhum recurso.
Abra o terminal na raiz do projeto e execute:
sam validate
Se tudo estiver correto, você receberá uma mensagem confirmando que o template.yaml
é válido.
Passo 2: Preparando o Terreno (O Bucket S3)
O AWS SAM funciona em duas etapas: primeiro, ele faz o upload do nosso artefato (function.zip
) para um "local de staging" na nuvem, que é um bucket S3. Depois, ele instrui o CloudFormation a criar a Lambda usando o artefato que está nesse bucket.
Portanto, precisamos criar esse bucket S3 antes de continuar.
Importante: Nomes de buckets S3 são globalmente únicos. Para garantir que o seu seja único, adicione um sufixo com números ou letras aleatórias.
aws s3 mb s3://[nome-do-seu-bucket] --region sa-east-1
Se o nome estiver disponível, o comando retornará uma mensagem de sucesso, como make_bucket: s3://...
. Anote o nome exato que você usou.
Passo 3: Fazendo o deploy na AWS (sam deploy
)
Agora sim, com tudo no lugar, vamos ao deploy. O comando sam deploy
irá ler o template.yaml
, empacotar nosso código, enviá-lo para o bucket que acabamos de criar e, finalmente, criar todos os recursos na AWS.
Use o comando abaixo, lembrando de substituir o nome do bucket pelo que você acabou de criar:
sam deploy --stack-name test-app --region sa-east-1 --s3-bucket [nome-do-seu-bucket] --capabilities CAPABILITY_IAM --confirm-changeset
Vamos entender os parâmetros-chave:
-
--stack-name test-app
: Dá um nome à nossa pilha de recursos no AWS CloudFormation. Pense nisso como o nome do nosso projeto na nuvem. -
--region sa-east-1
: Especifica a região da AWS onde os recursos serão criados. -
--s3-bucket [nome-do-seu-bucket]
: Aqui usamos o bucket S3 que criamos no passo anterior. É para onde o SAM enviará nossofunction.zip
. -
--capabilities CAPABILITY_IAM
: Como nosso template pode criar roles de permissão, precisamos explicitamente autorizar essa criação. -
--confirm-changeset
: Pede para o SAM nos mostrar um resumo das mudanças antes de aplicá-las.
Ao executar o comando, o SAM CLI irá te guiar com algumas perguntas:
- Ele mostrará as mudanças (um "changeset") e perguntará se você quer fazer o deploy. Digite
y
e pressione Enter. - Ele avisará que a função não tem autenticação. Para nosso teste, isso está ok. Digite
y
e pressione Enter.
Deploy Concluído com Sucesso!
Aguarde o processo terminar. O SAM mostrará o progresso da criação dos recursos. Se tudo deu certo, o final do output será a seção Outputs
que definimos no nosso template:
---------------------------------------------------------------------------------------------------------
Outputs
---------------------------------------------------------------------------------------------------------
Key ApiUrl
Description URL do endpoint do Api Gateway:
Value https://<ID_DA_SUA_API>.execute-api.sa-east-1.amazonaws.com/
---------------------------------------------------------------------------------------------------------
Com a URL base fornecida pelo SAM, nossa API está oficialmente no ar. Agora você pode testar os dois endpoints que criamos usando sua ferramenta de API preferida, como o Postman ou Insomnia.
Use a URL de saída para montar as requisições:
- Faça uma requisição
GET
para o caminho/Prod/greetings
para acionar aGreetingsFunction
. - Faça uma requisição
POST
para o caminho/Prod/calculator/sum
, enviando o JSON com os números no corpo da requisição, para acionar aCalculatorHandler
.
Cada chamada irá invocar a função Lambda correspondente diretamente na AWS.
Código Fonte no GitHub
O projeto completo desenvolvido neste artigo está disponível no GitHub. Para acessar o código exatamente como ele estava ao final desta Parte 1, utilize o link para a branch específica abaixo.
Acesse o repositório na branch parte1-criando-primeiras-lambdas
Agradecimentos e Fontes
A criação deste conteúdo foi inspirada e auxiliada por artigos e documentações fantásticas da comunidade. Finalizo esse artigo deixando aqui um agradecimento especial e a recomendação de leitura:
- One Package, Multiple Lambdas with Quarkus Lambda: Um excelente artigo que detalha a arquitetura de múltiplas Lambdas em um só projeto Quarkus.
- Lambda Function with GraalVM Native Image: Um guia prático sobre o deploy de imagens nativas como um Custom Runtime na AWS.
- Guia Oficial do Quarkus para AWS Lambda: A documentação oficial, sempre uma referência indispensável e completa.
Top comments (0)