<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Pedro Henrique </title>
    <description>The latest articles on Forem by Pedro Henrique  (@pdrhp_).</description>
    <link>https://forem.com/pdrhp_</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1188298%2F04702eaa-06dc-44ea-8f0a-d739752257a5.jpeg</url>
      <title>Forem: Pedro Henrique </title>
      <link>https://forem.com/pdrhp_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/pdrhp_"/>
    <language>en</language>
    <item>
      <title>Um Guia Prático com Quarkus, SAM e GraalVM - Parte 1 Criando o projeto Quarkus e fazendo deploy com SAM</title>
      <dc:creator>Pedro Henrique </dc:creator>
      <pubDate>Tue, 09 Sep 2025 10:00:00 +0000</pubDate>
      <link>https://forem.com/pdrhp_/um-guia-pratico-com-quarkus-sam-e-graalvm-parte-1-criando-o-projeto-quarkus-e-fazendo-deploy-com-35mg</link>
      <guid>https://forem.com/pdrhp_/um-guia-pratico-com-quarkus-sam-e-graalvm-parte-1-criando-o-projeto-quarkus-e-fazendo-deploy-com-35mg</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;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 &lt;strong&gt;Quarkus (com compilação nativa GraalVM)&lt;/strong&gt; e &lt;strong&gt;AWS SAM&lt;/strong&gt; para enfrentar desafios comuns do Java no ambiente serverless, como o tempo de inicialização (&lt;em&gt;cold starts&lt;/em&gt;) e o consumo de memória.&lt;/p&gt;

&lt;p&gt;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á:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Nesta Parte 1 (o artigo atual)&lt;/strong&gt;, focaremos nos fundamentos: a configuração do projeto, a criação de múltiplas funções Lambda e o deploy automatizado na AWS.&lt;/li&gt;
&lt;li&gt; Na &lt;strong&gt;Parte 2&lt;/strong&gt;, adicionaremos uma camada de segurança, integrando nossa aplicação com o &lt;strong&gt;Amazon Cognito&lt;/strong&gt; para gerenciar a autenticação e usando as Lambdas para interagir com a API de usuários.&lt;/li&gt;
&lt;li&gt; Na &lt;strong&gt;Parte 3&lt;/strong&gt;, implementaremos a persistência de dados, adicionando uma tabela do &lt;strong&gt;Amazon DynamoDB&lt;/strong&gt; à nossa infraestrutura e manipulando os dados através das Lambdas.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O nosso objetivo hoje é deixar a estrutura básica pronta e funcionando na nuvem. Vamos cobrir:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A criação e estruturação de um projeto Java com Quarkus.&lt;/li&gt;
&lt;li&gt;A implementação das nossas primeiras funções Lambda.&lt;/li&gt;
&lt;li&gt;O deploy automatizado de toda a estrutura na AWS.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pré-requisitos
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Java (JDK 21):&lt;/strong&gt; Essencial para rodar o Quarkus e compilar o código. Neste tutorial, usamos a versão 21.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Verifique sua versão com:&lt;/em&gt; &lt;code&gt;java --version&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Gradle (8.5+):&lt;/strong&gt; Usado para gerenciar as dependências e o build do projeto.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Verifique sua versão com:&lt;/em&gt; &lt;code&gt;gradle --version&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Não tem? Siga o:&lt;/em&gt; &lt;a href="https://gradle.org/install/" rel="noopener noreferrer"&gt;Guia Oficial de Instalação do Gradle&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;AWS CLI v2:&lt;/strong&gt; A ferramenta de linha de comando para interagir com a AWS. É importante que ela esteja configurada com suas credenciais.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Verifique sua versão com:&lt;/em&gt; &lt;code&gt;aws --version&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Não tem? Siga o:&lt;/em&gt; &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html" rel="noopener noreferrer"&gt;Guia Oficial de Instalação da AWS CLI&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;AWS SAM CLI:&lt;/strong&gt; A ferramenta principal que usaremos para o build e deploy da nossa aplicação serverless.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Verifique sua versão com:&lt;/em&gt; &lt;code&gt;sam --version&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Não tem? Siga o:&lt;/em&gt; &lt;a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html" rel="noopener noreferrer"&gt;Guia Oficial de Instalação da SAM CLI&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Container Runtime (Docker ou Podman):&lt;/strong&gt; Requisito indispensável em nosso fluxo. Embora seja possível &lt;a href="https://quarkus.io/guides/building-native-image" rel="noopener noreferrer"&gt;compilar uma imagem nativa instalando o GraalVM diretamente na sua máquina&lt;/a&gt;, &lt;strong&gt;neste tutorial usaremos a abordagem de build via contêiner&lt;/strong&gt;. 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.&lt;/p&gt;

&lt;p&gt;Precisaremos de um contêiner por dois motivos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Para o &lt;strong&gt;build nativo do Quarkus&lt;/strong&gt;, usando a flag &lt;code&gt;-Dquarkus.native.container-build=true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; Para o &lt;strong&gt;AWS SAM CLI&lt;/strong&gt;, que o utiliza para simular o ambiente da AWS Lambda localmente.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Verifique se está rodando com:&lt;/em&gt; &lt;code&gt;docker info&lt;/code&gt; ou &lt;code&gt;podman info&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Opções de Instalação:&lt;/em&gt; &lt;a href="https://docs.docker.com/desktop/" rel="noopener noreferrer"&gt;Docker Desktop&lt;/a&gt; (mais comum) ou &lt;a href="https://podman.io/getting-started/installation" rel="noopener noreferrer"&gt;Podman&lt;/a&gt; (alternativa).&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Noções de Quarkus:&lt;/strong&gt; 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).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Precisa de uma introdução? Confira os:&lt;/em&gt; &lt;a href="https://quarkus.io/get-started/" rel="noopener noreferrer"&gt;Guias "Getting Started" do Quarkus&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Criando o Projeto com Quarkus
&lt;/h2&gt;

&lt;p&gt;Existem várias maneiras de se iniciar um projeto Quarkus, cada uma adequada a um estilo de trabalho diferente. As principais são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Via Linha de Comando (CLI):&lt;/strong&gt; Para desenvolvedores que preferem o terminal, é possível usar a &lt;a href="https://quarkus.io/guides/cli-tooling" rel="noopener noreferrer"&gt;CLI oficial do Quarkus&lt;/a&gt; ou o próprio wrapper do Gradle para criar o projeto. É uma abordagem rápida e excelente para automação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Via Gerador Web (&lt;code&gt;code.quarkus.io&lt;/code&gt;):&lt;/strong&gt; 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.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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 &lt;a href="https://code.quarkus.io/" rel="noopener noreferrer"&gt;&lt;strong&gt;code.quarkus.io&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;.zip&lt;/code&gt; com o projeto pronto para ser aberto na sua IDE preferida.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vamos configurar nosso projeto com as seguintes especificações:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Build Tool:&lt;/strong&gt; Gradle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Java Version:&lt;/strong&gt; 21&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Group:&lt;/strong&gt; (use o de sua preferência, ex: &lt;code&gt;br.com.seudominio&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Artifact:&lt;/strong&gt; (use o de sua preferência, ex: &lt;code&gt;sam-quarkus-app&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Em seguida, adicione as seguintes &lt;strong&gt;extensões (dependências)&lt;/strong&gt;, que são a base para nossa aplicação serverless:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;code&gt;quarkus-amazon-lambda&lt;/code&gt;: A extensão principal que adapta a aplicação Quarkus para ser executada como uma função AWS Lambda.&lt;/li&gt;
&lt;li&gt; &lt;code&gt;quarkus-rest&lt;/code&gt; (anteriormente RESTEasy Reactive): Fornece o framework JAX-RS para a criação de endpoints REST.&lt;/li&gt;
&lt;li&gt; &lt;code&gt;quarkus-rest-jackson&lt;/code&gt;: Adiciona o suporte para serialização e desserialização de objetos Java para JSON usando a biblioteca Jackson.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Após selecionar essas opções, clique em "Generate your application" para baixar o &lt;code&gt;.zip&lt;/code&gt; com o projeto. Descompacte-o e abra na sua IDE preferida.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs9bqw5aufyfs7rwkyc8w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs9bqw5aufyfs7rwkyc8w.png" alt="Criando projeto java quarkus no code.quarkus.io" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando nossas primeiras Lambdas
&lt;/h2&gt;

&lt;p&gt;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 &lt;code&gt;code.quarkus.io&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A primeira e mais importante é a &lt;code&gt;io.quarkus:quarkus-amazon-lambda&lt;/code&gt;. É 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 &lt;em&gt;handlers&lt;/em&gt; e nos dá acesso direto às interfaces cruciais da AWS, como &lt;code&gt;RequestHandler&lt;/code&gt;, &lt;code&gt;APIGatewayProxyRequestEvent&lt;/code&gt; (para receber dados do API Gateway) e &lt;code&gt;APIGatewayProxyResponseEvent&lt;/code&gt; (para formular a resposta).&lt;/p&gt;

&lt;p&gt;A segunda peça-chave é a &lt;code&gt;io.quarkus:quarkus-rest-jackson&lt;/code&gt;. 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.&lt;/p&gt;

&lt;p&gt;Com essas duas ferramentas em mãos, estamos prontos para estruturar nosso código.&lt;/p&gt;

&lt;h3&gt;
  
  
  Criando nossos primeiros handlers
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h4&gt;
  
  
  Exemplo 1: Um "Olá, Mundo" Simples (&lt;code&gt;GreetingsHandler&lt;/code&gt;)
&lt;/h4&gt;

&lt;p&gt;Nosso primeiro handler é o mais básico possível: ele não recebe dados de entrada e retorna uma mensagem de texto simples.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Em: src/main/java/.../handler/GreetingsHandler.java&lt;/span&gt;
&lt;span class="nd"&gt;@ApplicationScoped&lt;/span&gt;
&lt;span class="nd"&gt;@Named&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"greetingsHandler"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreetingsHandler&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RequestHandler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;APIGatewayProxyRequestEvent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;APIGatewayProxyResponseEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;APIGatewayProxyResponseEvent&lt;/span&gt; &lt;span class="nf"&gt;handleRequest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;APIGatewayProxyRequestEvent&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Context&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Lógica para criar e retornar uma resposta HTTP 200 OK&lt;/span&gt;
        &lt;span class="nc"&gt;APIGatewayProxyResponseEvent&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;APIGatewayProxyResponseEvent&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setStatusCode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setHeaders&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;singletonMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"text/plain; charset=utf-8"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setBody&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Olá do Quarkus Lambda!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos nos concentrar nos três pontos fundamentais que já discutimos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Gerenciamento com CDI (&lt;code&gt;@ApplicationScoped&lt;/code&gt;)&lt;/strong&gt;: Integra o handler ao Quarkus, transformando-o em um &lt;em&gt;bean&lt;/em&gt; gerenciável.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;A Identidade da Lambda (&lt;code&gt;@Named("greetingsHandler")&lt;/code&gt;)&lt;/strong&gt;: Atribui um ID único que usaremos no &lt;code&gt;template.yaml&lt;/code&gt; para conectar a infraestrutura a esta classe específica.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;O Contrato com a AWS (&lt;code&gt;RequestHandler&lt;/code&gt;)&lt;/strong&gt;: Define a classe como um ponto de entrada de Lambda, especificando os tipos de evento de entrada e saída do API Gateway.&lt;/li&gt;
&lt;/ol&gt;




&lt;h4&gt;
  
  
  Exemplo 2: Uma Lambda com Lógica e JSON (&lt;code&gt;CalculatorHandler&lt;/code&gt;)
&lt;/h4&gt;

&lt;p&gt;Agora, vamos criar um exemplo mais prático. O &lt;code&gt;CalculatorHandler&lt;/code&gt; receberá um JSON com dois números, fará uma soma e retornará o resultado em outro JSON.&lt;/p&gt;

&lt;h5&gt;
  
  
  Definindo as Estruturas de Dados (DTOs)
&lt;/h5&gt;

&lt;p&gt;Primeiro, precisamos de classes para modelar os dados de entrada (&lt;code&gt;CalculationRequest&lt;/code&gt;) e saída (&lt;code&gt;CalculationResponse&lt;/code&gt;). Crie estes dois arquivos no seu pacote &lt;code&gt;dto&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Em: src/main/java/.../dto/CalculationRequest.java&lt;/span&gt;
&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;br.com.seudominio.samquarkusapp.dto&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.quarkus.runtime.annotations.RegisterForReflection&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@RegisterForReflection&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculationRequest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;number1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;number2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Getters e Setters&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;getNumber1&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;number1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setNumber1&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;number1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;number1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;number1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;getNumber2&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;number2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setNumber2&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;number2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;number2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;number2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Em: src/main/java/.../dto/CalculationResponse.java&lt;/span&gt;
&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;br.com.seudominio.samquarkusapp.dto&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.quarkus.runtime.annotations.RegisterForReflection&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@RegisterForReflection&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculationResponse&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;CalculationResponse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;operation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Getters e Setters&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;getResult&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setResult&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getOperation&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setOperation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;operation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Ponto de Atenção: &lt;code&gt;@RegisterForReflection&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
Esta anotação é &lt;strong&gt;essencial para a compilação nativa com GraalVM&lt;/strong&gt;. 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 &lt;code&gt;@RegisterForReflection&lt;/code&gt; 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.&lt;/p&gt;
&lt;h5&gt;
  
  
  Implementando o Handler
&lt;/h5&gt;

&lt;p&gt;Agora, crie a classe &lt;code&gt;CalculatorHandler&lt;/code&gt; no pacote &lt;code&gt;handler&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Em: src/main/java/.../handler/CalculatorHandler.java&lt;/span&gt;
&lt;span class="nd"&gt;@ApplicationScoped&lt;/span&gt;
&lt;span class="nd"&gt;@Named&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"calculatorHandler"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculatorHandler&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RequestHandler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;APIGatewayProxyRequestEvent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;APIGatewayProxyResponseEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// Para fins didáticos, mas a injeção de dependência é preferível.&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;ObjectMapper&lt;/span&gt; &lt;span class="n"&gt;objectMapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ObjectMapper&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;APIGatewayProxyResponseEvent&lt;/span&gt; &lt;span class="nf"&gt;handleRequest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;APIGatewayProxyRequestEvent&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Context&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// 1. pega o corpo da requisição (que é uma string json)&lt;/span&gt;
            &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBody&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

            &lt;span class="c1"&gt;// 2. desserializa a string JSON em um objeto Java&lt;/span&gt;
            &lt;span class="nc"&gt;CalculationRequest&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;objectMapper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;CalculationRequest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// 3. executa a lógica de negócio&lt;/span&gt;
            &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getNumber1&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getNumber2&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

            &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLogger&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Calculando: %f + %f = %f"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getNumber1&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getNumber2&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

            &lt;span class="c1"&gt;// 4. cria o objeto de resposta&lt;/span&gt;
            &lt;span class="nc"&gt;CalculationResponse&lt;/span&gt; &lt;span class="n"&gt;responsePayload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CalculationResponse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"soma"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// 5. serializa o objeto de resposta de volta para uma string JSON e retorna&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;APIGatewayProxyResponseEvent&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withStatusCode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withHeaders&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withBody&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;objectMapper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;writeValueAsString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responsePayload&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLogger&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Erro ao processar: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;APIGatewayProxyResponseEvent&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withStatusCode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Bad Request&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withHeaders&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withBody&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{\"message\":\"Corpo da requisição inválido.\"}"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este handler segue o mesmo padrão, mas sua lógica interna é mais rica:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Ele recebe o corpo da requisição, que esperamos ser um JSON como &lt;code&gt;{"number1": 10, "number2": 20}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; Usa o &lt;code&gt;objectMapper.readValue&lt;/code&gt; para converter essa string em um objeto &lt;code&gt;CalculationRequest&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; Executa a soma.&lt;/li&gt;
&lt;li&gt; Cria um objeto &lt;code&gt;CalculationResponse&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; Usa o &lt;code&gt;objectMapper.writeValueAsString&lt;/code&gt; para converter o objeto de resposta em uma string JSON antes de enviá-lo de volta com um status &lt;code&gt;200 OK&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Buildando nosso executável nativo
&lt;/h2&gt;

&lt;p&gt;Com nosso handler Java pronto, o próximo passo é compilá-lo. No entanto, este não é um build comum que gera um &lt;code&gt;.jar&lt;/code&gt;; nosso objetivo é criar um executável nativo para Linux, a chave para obtermos a performance excepcional que o Quarkus com GraalVM promete.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Temos duas maneiras principais de executar o build. Ambas chegam ao mesmo resultado.&lt;/p&gt;




&lt;h4&gt;
  
  
  Opção 1: Usando o Gradle Wrapper (Recomendado)
&lt;/h4&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Abra seu terminal na raiz do projeto e execute o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./gradlew build &lt;span class="nt"&gt;-x&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="s2"&gt;"-Dquarkus.native.enabled=true"&lt;/span&gt; &lt;span class="s2"&gt;"-Dquarkus.native.container-build=true"&lt;/span&gt; &lt;span class="s2"&gt;"-Dquarkus.package.jar.enabled=false"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos entender cada parte:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;./gradlew build&lt;/code&gt;: O comando padrão para iniciar o build com o Gradle.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-x test&lt;/code&gt;: Um comando do Gradle para pular a execução dos testes, agilizando o processo de build.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"-Dquarkus.native.enabled=true"&lt;/code&gt;: A chave que liga o "modo nativo", instruindo o Quarkus a iniciar a compilação com GraalVM.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"-Dquarkus.native.container-build=true"&lt;/code&gt;: 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.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"-Dquarkus.package.jar.enabled=false"&lt;/code&gt;: Uma pequena otimização. Como nosso foco é 100% no executável nativo, dizemos ao Quarkus para não se preocupar em gerar os &lt;code&gt;.jar&lt;/code&gt;s tradicionais.&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  Opção 2: Usando a Quarkus CLI
&lt;/h4&gt;

&lt;p&gt;Para quem prefere uma linha de comando mais limpa e tem a &lt;a href="https://quarkus.io/guides/cli-tooling" rel="noopener noreferrer"&gt;CLI do Quarkus instalada&lt;/a&gt;, o comando é um pouco mais enxuto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;quarkus build &lt;span class="nt"&gt;--native&lt;/span&gt; &lt;span class="nt"&gt;--no-tests&lt;/span&gt; &lt;span class="s2"&gt;"-Dquarkus.native.container-build=true"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As flags &lt;code&gt;--native&lt;/code&gt; e &lt;code&gt;--no-tests&lt;/code&gt; são atalhos para as propriedades equivalentes que vimos no comando do Gradle.&lt;/p&gt;




&lt;h3&gt;
  
  
  O Resultado
&lt;/h3&gt;

&lt;p&gt;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!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frytytk76630ss6azukx5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frytytk76630ss6azukx5.png" alt="Output final do terminal após a execução do build, mostrando a mensagem 'BUILD SUCCESSFUL in 3m 32s', confirmando o sucesso da compilação." width="800" height="61"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao final, se tudo correu bem, você terá o nosso tão esperado artefato pronto para o deploy no seguinte caminho:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;build/function.zip&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftj7m7fgzawbp3wu8p9b4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftj7m7fgzawbp3wu8p9b4.png" alt="Visualização da pasta 'build' em um editor de código, destacando o arquivo 'function.zip', que é o pacote de deploy para a AWS Lambda gerado pelo build nativo." width="484" height="545"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Este arquivo &lt;code&gt;.zip&lt;/code&gt; contém nosso executável Linux (&lt;code&gt;bootstrap&lt;/code&gt;) pronto para ser executado na AWS Lambda. É este o artefato que, na próxima seção, diremos ao AWS SAM para usar.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Receita da Nossa Infraestrutura: O &lt;code&gt;template.yaml&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Com nosso código Java agora contendo dois handlers, precisamos atualizar nosso arquivo de manifesto, o &lt;code&gt;template.yaml&lt;/code&gt;, para dizer à AWS como expor ambas as funções.&lt;/p&gt;

&lt;p&gt;Pense neste arquivo como a &lt;strong&gt;planta&lt;/strong&gt; 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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;AWSTemplateFormatVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2010-09-09'&lt;/span&gt;
&lt;span class="na"&gt;Transform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Serverless-2016-10-31&lt;/span&gt;

&lt;span class="na"&gt;Globals&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;Function&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;provided.al2023&lt;/span&gt;
    &lt;span class="na"&gt;Handler&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequest&lt;/span&gt;
    &lt;span class="na"&gt;Architectures&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;x86_64&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;MemorySize&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;128&lt;/span&gt;
    &lt;span class="na"&gt;Timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;15&lt;/span&gt;
    &lt;span class="na"&gt;CodeUri&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build/function.zip&lt;/span&gt;
    &lt;span class="na"&gt;Environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;Variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;DISABLE_SIGNAL_HANDLERS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true"&lt;/span&gt;

&lt;span class="na"&gt;Resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;GreetingsFunction&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Serverless::Function&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;Environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;Variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;QUARKUS_LAMBDA_HANDLER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;greetingsHandler&lt;/span&gt;
      &lt;span class="na"&gt;Events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;GetGreetings&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Api&lt;/span&gt;
          &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;Path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/greetings&lt;/span&gt;
            &lt;span class="na"&gt;Method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;get&lt;/span&gt;

  &lt;span class="na"&gt;CalculatorFunction&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Serverless::Function&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;Environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;Variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;QUARKUS_LAMBDA_HANDLER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;calculatorHandler&lt;/span&gt;
      &lt;span class="na"&gt;Events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;PostCalculate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Api&lt;/span&gt;
          &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;Path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/calculator/sum&lt;/span&gt;
            &lt;span class="na"&gt;Method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;post&lt;/span&gt;

&lt;span class="na"&gt;Outputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ApiUrl&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;URL&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;do&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;endpoint&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;do&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Api&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Gateway:"&lt;/span&gt;
    &lt;span class="na"&gt;Value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Sub&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pode parecer complexo, mas é bastante lógico. Vamos analisar cada bloco.&lt;/p&gt;




&lt;h4&gt;
  
  
  &lt;code&gt;Globals&lt;/code&gt;: Os Padrões da Construção
&lt;/h4&gt;

&lt;p&gt;A seção &lt;code&gt;Globals&lt;/code&gt; 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.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Runtime: provided.al2023&lt;/code&gt;: Como nosso build com GraalVM gera um executável Linux autossuficiente, usamos &lt;code&gt;provided&lt;/code&gt; para dizer à AWS: "nós estamos fornecendo nosso próprio executável". A imagem &lt;code&gt;al2023&lt;/code&gt; garante a presença de bibliotecas essenciais, como a &lt;code&gt;glibc&lt;/code&gt;, que nosso executável nativo precisa.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Handler: io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequest&lt;/code&gt;: 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 &lt;code&gt;@Named&lt;/code&gt; correto.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CodeUri: build/function.zip&lt;/code&gt;: Aponta para o arquivo &lt;code&gt;.zip&lt;/code&gt; que contém nosso executável nativo. Note que ambas as funções usam o mesmo artefato de código.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Environment -&amp;gt; DISABLE_SIGNAL_HANDLERS: "true"&lt;/code&gt;: Uma variável de ambiente crucial para a execução nativa, que resolve incompatibilidades entre o Quarkus e o ambiente Custom Runtime da AWS.&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  &lt;code&gt;Resources&lt;/code&gt;: Desenhando a Estrutura Principal
&lt;/h4&gt;

&lt;p&gt;Agora, definimos dois componentes na nossa infraestrutura.&lt;/p&gt;

&lt;h5&gt;
  
  
  A primeira função: GreetingsFunction
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GreetingsFunction:&lt;/code&gt;: O nome lógico da nossa primeira função Lambda.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Type: AWS::Serverless::Function&lt;/code&gt;: Especifica que estamos criando uma função Lambda.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Properties&lt;/code&gt;: As configurações específicas deste "cômodo".

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Environment -&amp;gt; Variables -&amp;gt; QUARKUS_LAMBDA_HANDLER: greetingsHandler&lt;/code&gt;: O valor &lt;code&gt;greetingsHandler&lt;/code&gt; é o mesmo que usamos na anotação &lt;code&gt;@Named("greetingsHandler")&lt;/code&gt;. É assim que o roteador do Quarkus sabe qual classe Java executar.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;Events:&lt;/code&gt;: Define a "porta de entrada" da função.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Path: /greetings&lt;/code&gt; e &lt;code&gt;Method: get&lt;/code&gt;: Mapeia a função para ser acionada por uma requisição &lt;code&gt;GET&lt;/code&gt; no caminho &lt;code&gt;/greetings&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h5&gt;
  
  
  A segunda função: CalculatorFunction
&lt;/h5&gt;

&lt;p&gt;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".&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CalculatorFunction:&lt;/code&gt;: O nome lógico da nossa nova função de cálculo.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Properties&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;QUARKUS_LAMBDA_HANDLER: calculatorHandler&lt;/code&gt;: E aqui está a conexão para o nosso segundo handler. O valor &lt;code&gt;calculatorHandler&lt;/code&gt; corresponde exatamente à anotação &lt;code&gt;@Named("calculatorHandler")&lt;/code&gt; da nossa classe &lt;code&gt;CalculatorHandler.java&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;Events:&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Path: /calculator/sum&lt;/code&gt; e &lt;code&gt;Method: post&lt;/code&gt;: Mapeamos esta função para um caminho diferente (&lt;code&gt;/calculator/sum&lt;/code&gt;) e um método HTTP diferente (&lt;code&gt;post&lt;/code&gt;), ideal para enviar dados no corpo da requisição.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h4&gt;
  
  
  &lt;code&gt;Outputs&lt;/code&gt;: Recebendo o Endereço Final
&lt;/h4&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ApiUrl&lt;/code&gt;: Define uma saída de informação com a URL base da API.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Fazendo o deploy da nossa aplicação serverless
&lt;/h2&gt;

&lt;p&gt;Com nosso executável nativo empacotado no &lt;code&gt;function.zip&lt;/code&gt; e a planta da nossa infraestrutura definida no &lt;code&gt;template.yaml&lt;/code&gt;, temos todas as peças do quebra-cabeça. Agora, vamos usar o AWS SAM CLI para montar tudo na nuvem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pré-requisitos para o Deploy
&lt;/h3&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;AWS CLI configurada e autenticada&lt;/strong&gt;: O SAM CLI usa as credenciais configuradas na AWS CLI. Você precisa estar autenticado em uma conta da AWS.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O caminho mais direto para este tutorial é configurar a CLI com uma &lt;strong&gt;Access Key&lt;/strong&gt; e &lt;strong&gt;Secret Key&lt;/strong&gt; de um usuário IAM.&lt;/li&gt;
&lt;li&gt;Usuários mais avançados podem usar outros métodos, como o &lt;code&gt;aws sso login&lt;/code&gt;, que foi o que utilizei para preparar este artigo, autenticando-me em uma conta filha gerenciada pelo AWS Organizations.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AWS SAM CLI instalado&lt;/strong&gt;: Essencial para interpretar nosso template e orquestrar o deploy.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Passo 1: Validando nosso template.yaml (&lt;code&gt;sam validate&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Antes de pedir para o SAM construir nossa infraestrutura, é uma boa prática pedir para ele revisar nosso arquivo. O comando &lt;code&gt;sam validate&lt;/code&gt; faz exatamente isso: ele lê seu &lt;code&gt;template.yaml&lt;/code&gt; e verifica se há erros de sintaxe ou de lógica, sem custar nada e sem criar nenhum recurso.&lt;/p&gt;

&lt;p&gt;Abra o terminal na raiz do projeto e execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sam validate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se tudo estiver correto, você receberá uma mensagem confirmando que o &lt;code&gt;template.yaml&lt;/code&gt; é válido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvp1aetfgydaguo09v9hp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvp1aetfgydaguo09v9hp.png" alt="Terminal mostrando o comando 'sam validate' e sua saída de sucesso, com a mensagem de que o arquivo 'template.yaml' é um template SAM válido." width="800" height="40"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Passo 2: Preparando o Terreno (O Bucket S3)
&lt;/h3&gt;

&lt;p&gt;O AWS SAM funciona em duas etapas: primeiro, ele faz o upload do nosso artefato (&lt;code&gt;function.zip&lt;/code&gt;) 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.&lt;/p&gt;

&lt;p&gt;Portanto, precisamos criar esse bucket S3 antes de continuar.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Importante&lt;/strong&gt;: Nomes de buckets S3 são &lt;strong&gt;globalmente únicos&lt;/strong&gt;. Para garantir que o seu seja único, adicione um sufixo com números ou letras aleatórias.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3 mb s3://[nome-do-seu-bucket] &lt;span class="nt"&gt;--region&lt;/span&gt; sa-east-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se o nome estiver disponível, o comando retornará uma mensagem de sucesso, como &lt;code&gt;make_bucket: s3://...&lt;/code&gt;. Anote o nome exato que você usou.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4epggfbhwhmfrsqakd5o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4epggfbhwhmfrsqakd5o.png" alt="Terminal mostrando o comando 'aws s3 mb' criando o bucket 'teste-bucket-sam-app-123765' e a mensagem de sucesso 'make_bucket' como resultado." width="800" height="34"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Passo 3: Fazendo o deploy na AWS (&lt;code&gt;sam deploy&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Agora sim, com tudo no lugar, vamos ao deploy. O comando &lt;code&gt;sam deploy&lt;/code&gt; irá ler o &lt;code&gt;template.yaml&lt;/code&gt;, empacotar nosso código, enviá-lo para o bucket que acabamos de criar e, finalmente, criar todos os recursos na AWS.&lt;/p&gt;

&lt;p&gt;Use o comando abaixo, lembrando de &lt;strong&gt;substituir o nome do bucket&lt;/strong&gt; pelo que você acabou de criar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sam deploy &lt;span class="nt"&gt;--stack-name&lt;/span&gt; test-app &lt;span class="nt"&gt;--region&lt;/span&gt; sa-east-1 &lt;span class="nt"&gt;--s3-bucket&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;nome-do-seu-bucket] &lt;span class="nt"&gt;--capabilities&lt;/span&gt; CAPABILITY_IAM &lt;span class="nt"&gt;--confirm-changeset&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos entender os parâmetros-chave:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--stack-name test-app&lt;/code&gt;: Dá um nome à nossa pilha de recursos no AWS CloudFormation. Pense nisso como o nome do nosso projeto na nuvem.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--region sa-east-1&lt;/code&gt;: Especifica a região da AWS onde os recursos serão criados.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--s3-bucket [nome-do-seu-bucket]&lt;/code&gt;: &lt;strong&gt;Aqui usamos o bucket S3 que criamos no passo anterior.&lt;/strong&gt; É para onde o SAM enviará nosso &lt;code&gt;function.zip&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--capabilities CAPABILITY_IAM&lt;/code&gt;: Como nosso template pode criar roles de permissão, precisamos explicitamente autorizar essa criação.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--confirm-changeset&lt;/code&gt;: Pede para o SAM nos mostrar um resumo das mudanças antes de aplicá-las.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ao executar o comando, o SAM CLI irá te guiar com algumas perguntas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Ele mostrará as mudanças (um "changeset") e perguntará se você quer fazer o deploy. Digite &lt;code&gt;y&lt;/code&gt; e pressione Enter.&lt;/li&gt;
&lt;li&gt; Ele avisará que a função não tem autenticação. Para nosso teste, isso está ok. Digite &lt;code&gt;y&lt;/code&gt; e pressione Enter.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffftap17whjb51g3qzkiz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffftap17whjb51g3qzkiz.png" alt="Terminal exibindo o preview do changeset do AWS SAM, com a lista de novos recursos como as duas Lambdas, Roles de IAM e o API Gateway, aguardando a confirmação 'y/N' do usuário." width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploy Concluído com Sucesso!
&lt;/h3&gt;

&lt;p&gt;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 &lt;code&gt;Outputs&lt;/code&gt; que definimos no nosso template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---------------------------------------------------------------------------------------------------------
Outputs
---------------------------------------------------------------------------------------------------------
Key                 ApiUrl
Description         URL do endpoint do Api Gateway:
Value               https://&amp;lt;ID_DA_SUA_API&amp;gt;.execute-api.sa-east-1.amazonaws.com/
---------------------------------------------------------------------------------------------------------
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwfksjw3153qlok01bhcd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwfksjw3153qlok01bhcd.png" alt="Tela do console da AWS Lambda mostrando as duas funções, 'CalculatorFunction' e 'GreetingsFunction', criadas com sucesso pelo deploy do AWS SAM." width="800" height="144"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Use a URL de saída para montar as requisições:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faça uma requisição &lt;code&gt;GET&lt;/code&gt; para o caminho &lt;code&gt;/Prod/greetings&lt;/code&gt; para acionar a &lt;code&gt;GreetingsFunction&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Faça uma requisição &lt;code&gt;POST&lt;/code&gt; para o caminho &lt;code&gt;/Prod/calculator/sum&lt;/code&gt;, enviando o JSON com os números no corpo da requisição, para acionar a &lt;code&gt;CalculatorHandler&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cada chamada irá invocar a função Lambda correspondente diretamente na AWS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4bro0v0yc808161r5o5o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4bro0v0yc808161r5o5o.png" alt="Tela de variáveis do Postman mostrando a criação da variável 'gateway-url-poc' com o valor da URL do API Gateway gerada pelo SAM" width="800" height="111"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fatkbyf3n306gmqodnjxn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fatkbyf3n306gmqodnjxn.png" alt="Teste bem-sucedido da rota /greetings no Postman retornando a mensagem " width="800" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fopnj3ly1ha9iwthq4xma.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fopnj3ly1ha9iwthq4xma.png" alt="Requisição POST para o endpoint de cálculo, enviando um JSON com number1 e number2, e recebendo a resposta 200 OK com o resultado da soma." width="800" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Código Fonte no GitHub
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/pdrhp/quarkus-native-graalvm-serveless-poc/tree/parte1-criando-primeiras-lambdas" rel="noopener noreferrer"&gt;Acesse o repositório na branch &lt;code&gt;parte1-criando-primeiras-lambdas&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Agradecimentos e Fontes
&lt;/h3&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://tenderheartpirate.medium.com/one-package-multiple-lambdas-with-quarkus-lambda-30560b273f9e" rel="noopener noreferrer"&gt;One Package, Multiple Lambdas with Quarkus Lambda&lt;/a&gt;&lt;/strong&gt;: Um excelente artigo que detalha a arquitetura de múltiplas Lambdas em um só projeto Quarkus.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/aws-builders/lambda-function-with-graalvm-native-image-part-2-how-to-develop-and-deploy-lambda-function-with-custom-runtime-3g1p"&gt;Lambda Function with GraalVM Native Image&lt;/a&gt;&lt;/strong&gt;: Um guia prático sobre o deploy de imagens nativas como um Custom Runtime na AWS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://quarkus.io/guides/aws-lambda" rel="noopener noreferrer"&gt;Guia Oficial do Quarkus para AWS Lambda&lt;/a&gt;&lt;/strong&gt;: A documentação oficial, sempre uma referência indispensável e completa.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>serverless</category>
      <category>graalvm</category>
      <category>aws</category>
    </item>
  </channel>
</rss>
