<?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>DEV Community: Victor Osório</title>
    <description>The latest articles on DEV Community by Victor Osório (@vepo).</description>
    <link>https://dev.to/vepo</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%2F80605%2F51d843f9-c79e-4ee9-a655-7ee2be927fb8.jpeg</url>
      <title>DEV Community: Victor Osório</title>
      <link>https://dev.to/vepo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vepo"/>
    <language>en</language>
    <item>
      <title>O que são Sistemas Distribuídos?</title>
      <dc:creator>Victor Osório</dc:creator>
      <pubDate>Tue, 26 Nov 2024 12:04:17 +0000</pubDate>
      <link>https://dev.to/vepo/o-que-sao-sistemas-distribuidos-3jgm</link>
      <guid>https://dev.to/vepo/o-que-sao-sistemas-distribuidos-3jgm</guid>
      <description>&lt;p&gt;Nos últimos 10 anos a internet se tornou onipresente. Isso nos levou a estarmos sempre conectados ao nosso smartphone que se torna um tela de acesso a todo o mundo. Mas isso não mudou somente as nossas vidas, mas a arquitetura de software como um todo. Quase todos os sistemas hoje são conectados a internet e interagem com outros sistemas como se fossem parte de uma inteligência distribuída. Nessa série vou tentar colocar no "papel" o que são sistemas distribuídos e como podemos avaliar eles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Procurando uma definição
&lt;/h2&gt;

&lt;p&gt;Antes de começarmos a falar sobre sistemas distribuídos que tal procurar definir o que são sistemas distribuídos? Vou aceitar a definição do livro do &lt;a href="https://amzn.to/3Q6BhsD" rel="noopener noreferrer"&gt;Maarten van Steen e Andrew S. Tanenbaum&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Definição&lt;/strong&gt;&lt;br&gt;
Um &lt;strong&gt;Sistema Distribuído&lt;/strong&gt; é uma coleção de elementos computacionais autônomos que aparecem para seus usuários como um único sistema coerente.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Dessa definição podemos realçar duas características muito importantes para quando analisamos os sistemas distribuídos. A primeira é que estamos falando de &lt;strong&gt;elementos computacionais autônomos&lt;/strong&gt;, ou seja, estamos falando de uma arquitetura de software/hardware que contém elementos distintos e independentes. Mas também estamos falando sobre &lt;strong&gt;usuários&lt;/strong&gt; que veem esses sistemas como um único e coerente sistema, ou seja, estamos falando de vários uma arquitetura de software que conterá vários elementos autônomos que podem ser compreendidos como um só pela colaboração de seus elementos.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;— Se fala o tempo inteiro de Microsserviços... Qual seria a diferença entre um Microsserviço e um Sistema Distribuído?!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A discussão sobre microsserviços é uma discussão paralela aos Sistemas Distribuídos. Para termos essa percepção precisamos olhar para a definição que o Sam Newman traz no primeiro capitulo do livro &lt;a href="https://amzn.to/3IAcRpN" rel="noopener noreferrer"&gt;Criando Microsserviços&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Definição&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Microsserviços&lt;/strong&gt; (&lt;em&gt;microservices&lt;/em&gt;) são serviços que podem ser lançados (&lt;em&gt;deploy&lt;/em&gt;) de forma independentes e são modelados com base em um domínio de negócios. [...] A arquitetura de microsserviços é um tipo de arquitetura orientada a serviços, com uma definição bem clara sobre como as fronteiras dos serviços devem ser traçadas, e para a qual a possibilidade de implantações independentes é fundamental.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Através dessa definição podemos perceber que a discussão de microsserviços é atrelada a implantação e ao deploy. Nós estamos falando de software em produção de um domínio especifico que evolui e não sobre uma arquitetura estática.&lt;/p&gt;

&lt;p&gt;Ouso dizer que toda arquitetura de Microsserviço é uma arquitetura de um sistema distribuído, mas nem todo sistema distribuído tem uma arquitetura em microsserviço. Isso porque um sistema composto por microsserviços pode ser visto como um sistema único, mas um sistema distribuído pode não se adequar a uma arquitetura em microsserviço.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;— COMO ASSIM?!?!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Deixa eu exemplificar! A análise de um Sistema Distribuído vai focar em qualidades do software que são comuns a uma gama maior que os sistemas que abrangem o foco dos Microsserviços. Por exemplo, se você olhar o &lt;a href="https://thepiratebays.com/pt/" rel="noopener noreferrer"&gt;The Pirate Bay&lt;/a&gt; vai ver o maior catálogo de Torrents que existe. Torrents são baixados em uma arquitetura &lt;a href="https://pt.wikipedia.org/wiki/Peer-to-peer" rel="noopener noreferrer"&gt;Peer-to-Peer&lt;/a&gt; que é um Sistema Distribuído mas de forma alguma pode ser encarado como um Microsserviço. O The Pirate Bay pode até ter uma arquitetura de microsserviços, mas ele faz parte de um sistema maior que é uma arquitetura mais complexa com protocolos e algoritmos próprios.&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%2Fblog.vepo.dev%2Fassets%2Fimages%2Fpeer-to-peer.svg" 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%2Fblog.vepo.dev%2Fassets%2Fimages%2Fpeer-to-peer.svg" alt="Arquitetura Peer-to-Peer" width="1082" height="643"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quando falamos de Sistemas Distribuídos estamos preocupados em como os softwares vão interagir, quais algoritmos eles irão usar para alcançar um objetivo e qual é o modelo de falha. Já quando falamos em Microsserviços estamos falando de um subconjunto dessa analise mais focado em como o software vai se manter em produção, qual a fronteira de cada elemento da arquitetura, como será o design do sistema, etc.&lt;/p&gt;

</description>
      <category>computacao</category>
      <category>sistemassistribuidos</category>
      <category>microsserviços</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>REST &amp; HTTP</title>
      <dc:creator>Victor Osório</dc:creator>
      <pubDate>Tue, 14 Sep 2021 11:15:55 +0000</pubDate>
      <link>https://dev.to/vepo/rest-http-4mg</link>
      <guid>https://dev.to/vepo/rest-http-4mg</guid>
      <description>&lt;p&gt;Ano passado eu me dediquei a escrever sobre HTTP e REST. Estava com alguns objetivos claro em mente, queria mostrar quando usar e como usar o HTTP. Depois me fiz algumas perguntas e fui pesquisar se existem padrões de projeto em REST. Dessa pesquisa saiu dois POST enormes. O primeiro eu decidi tornar um livreto, mas sem muita revisão e sem muita experiência.&lt;/p&gt;

&lt;p&gt;Com esse "livreto" eu acabei conseguindo ser aceito como escritor na &lt;a href="https://www.casadocodigo.com.br/" rel="noopener noreferrer"&gt;Casa do Código&lt;/a&gt;, a ideia é escrever um livro sobre desenvolvimento backend, mas focado nos protocolos e não nos frameworks. A parte HTTP já está pronta, e o tal "livreto" é só um capitulo, tem muito mais.&lt;/p&gt;

&lt;p&gt;Esse tal livreto está disponível na Amazon, de graça pra quem gosta de sustentar o Jeff Benzos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.amazon.com.br/Anatomia-Protocolo-HTTP-protocolos-frameworks-ebook/dp/B08PSDT35Y/?_encoding=UTF8&amp;amp;pd_rd_w=uCTIy&amp;amp;pf_rd_p=4b9652c9-ac45-4535-ac4d-eec51129bb6c&amp;amp;pf_rd_r=15TFWDDHRR59X7MWSBNM&amp;amp;pd_rd_r=57f799bb-5689-4dd4-8b73-f7ba4703b773&amp;amp;pd_rd_wg=1Ar7d&amp;amp;ref_=pd_gw_ci_mcx_mr_hp_d" rel="noopener noreferrer"&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%2Fdz8ojfctd6lh150hakag.png" alt="Anatomia do Protocolo HTTP" width="397" height="633"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se você quiser pegar no Leanpub, também está lá: &lt;a href="https://leanpub.com/anatomiahttp/" rel="noopener noreferrer"&gt;leanpub.com/anatomiahttp&lt;/a&gt;&lt;/p&gt;

</description>
      <category>http</category>
      <category>backend</category>
      <category>livros</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Criando um Stream em Java</title>
      <dc:creator>Victor Osório</dc:creator>
      <pubDate>Mon, 29 Mar 2021 17:24:43 +0000</pubDate>
      <link>https://dev.to/vepo/criando-um-stream-em-java-2ii9</link>
      <guid>https://dev.to/vepo/criando-um-stream-em-java-2ii9</guid>
      <description>&lt;p&gt;Esse é um post muito rápido! Eu tinha estudado isso muito tempo atrás, na época que o Java 8 foi lançado, mas hoje tive uma ideia de usar ele.&lt;/p&gt;

&lt;h1&gt;
  
  
  Qual é problema a se resolver?
&lt;/h1&gt;

&lt;p&gt;Podemos usar Stream para abstrair um tipo de coleção, com o Stream podemos encapsular o metodo de captura do dado e só expor uma fonte de dados.&lt;/p&gt;

&lt;h1&gt;
  
  
  Porque eu decidir usar?
&lt;/h1&gt;

&lt;p&gt;Estou implementando uma funcionalidade que consome uma lista de produtos de uma API. Como essa lista é paginada e eu preciso usar em alguns lugares, prefiro criar um Stream, assim toda a lógica de percorrer a lista é encapsulada. Se eu retornasse uma lista, a primeira operação só ocorreria quando toda a lista estivesse carregada na memória. Com o Stream, eu terei pequenas listas na memória e quando ela se esgota vai percorrendo as páginas.&lt;/p&gt;

&lt;h1&gt;
  
  
  Como implementar?
&lt;/h1&gt;

&lt;p&gt;Vamos abstrair o meu &lt;code&gt;StoreService&lt;/code&gt;, certo? Vou apresentar ele como uma interface (na verdade ele é, só que usando &lt;a href="https://github.com/eclipse/microprofile-rest-client" rel="noopener noreferrer"&gt;MicroProfile RestClient&lt;/a&gt; com &lt;a href="https://quarkus.io/guides/rest-client" rel="noopener noreferrer"&gt;Quarkus&lt;/a&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="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@RegisterRestClient&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;StoreService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; 
    &lt;span class="nd"&gt;@GET&lt;/span&gt;
    &lt;span class="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/produtos"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@Consumes&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Produto&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;listarProdutos&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@QueryParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"limit"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                                 &lt;span class="nd"&gt;@QueryParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"offset"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;offset&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;Configurado e validado que está funcionando corretamente é hora de começar a construir o Stream. O próximo passo e se perguntar qual é as caracteristicas principais desse Stream. Para isso recomendo ler a documentação do &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html" rel="noopener noreferrer"&gt;Spliterator&lt;/a&gt;, interface que é o coração de qualquer Stream. Dado as caracteristicas do meu Stream, vou considerar ele imutável, não nulo e com tamanho fixo.&lt;/p&gt;

&lt;p&gt;Agora podemos implementar a classe que irá dar vida ao Stream. Para isso devemos basicamente implementar um método, o &lt;code&gt;tryAdvance&lt;/code&gt;, ele deverá consumir um dos itens da lista de produtos e retornar se há ou não mais elementos. Segue abaixo uma tabela com os detalhes da implmentação por método.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Método&lt;/th&gt;
&lt;th&gt;Escolhas&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tryAdvance&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Irá consumir elementos da pilha. Se a pilha estiver vazia irá pedir uma nova página, se vier menos elementos que o requisitado, irá setar uma flag dizendo que acabou os elementos.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;trySplit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sempre retornará &lt;code&gt;null&lt;/code&gt;, não será possível fazer processamento paralelo.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;estimateSize&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Será o tamanho da pilha mais uma página, se a última requisição voltar menos itens que uma página, será apenas o tamanho da pilha.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;characteristics&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Irá informar que esse Stream é imutável, com tamanho fixo e não nulo.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Segue a implementação final:&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RemoteSpliterator&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Spliterator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Produto&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&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;Logger&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LoggerFactory&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="nc"&gt;RemoteSpliterator&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="kd"&gt;private&lt;/span&gt; &lt;span class="n"&gt;statica&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="no"&gt;LIMITE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// tamanho da página&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Queue&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Produto&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;produtos&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;boolean&lt;/span&gt; &lt;span class="n"&gt;temMais&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;int&lt;/span&gt; &lt;span class="n"&gt;offsetAtual&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;StoreService&lt;/span&gt; &lt;span class="n"&gt;storeService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;RemoteSpliterator&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;StoreService&lt;/span&gt; &lt;span class="n"&gt;storeService&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;produtos&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;LinkedList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;temMais&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;offsetAtual&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&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;storeService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;storeService&lt;/span&gt;&lt;span class="o"&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="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;tryAdvance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;super&lt;/span&gt; &lt;span class="nc"&gt;Produto&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;produtos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;temMais&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="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;produtosRemotos&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;storeService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listarProdutos&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;LIMITE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;offsetAtual&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;temMais&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;produtosRemotos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;LIMITE&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                &lt;span class="n"&gt;offsetAtual&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;produtosRemotos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Produdos lidos do servidor: {}"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;produtosRemotos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;produtos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;produtosRemotos&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="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;produtos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&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="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;produtos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;poll&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&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="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Spliterator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Produto&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;trySplit&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="kc"&gt;null&lt;/span&gt;&lt;span class="o"&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="kt"&gt;long&lt;/span&gt; &lt;span class="nf"&gt;estimateSize&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;temMais&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;produtos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="no"&gt;LIMITE&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;produtos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&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="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;characteristics&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="nc"&gt;Spliterator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;IMMUTABLE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Spliterator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SIZED&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Spliterator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;NONNULL&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;Para finalizar, precisamos apenas criar o Stream, isso pode se feito chamando o método &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/StreamSupport.html#stream-java.util.Spliterator-boolean-" rel="noopener noreferrer"&gt;StreamSupport.stream&lt;/a&gt; usando o Spliterator criado como primeiro parâmetro e &lt;code&gt;false&lt;/code&gt; como segundo parâmetro, já que ele não aceita processamento paralelo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Porque usei LinkedList?
&lt;/h2&gt;

&lt;p&gt;Porque o acesso não será como em um array, mas em pilha. Apenas adicionarei itens no final a removereis itens do começo. Usar &lt;code&gt;ArrayList&lt;/code&gt; tem um custo maior para adicionar e remover, enquanto sua vantagem está no acesso a itens que é em &lt;code&gt;O(1)&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusão
&lt;/h1&gt;

&lt;p&gt;Para se criar Streams não precisamos de ter todos os dados em mãos, essa é uma ferramenta poderosa que nos permite transformar qualquer fluxo de dados em uma API poderosa que irá agilizar a execução do seu código. &lt;/p&gt;

&lt;p&gt;Você não precisa resolver tudo em uma lista e depois criar o Stream.&lt;/p&gt;

</description>
      <category>java</category>
      <category>javastream</category>
      <category>programacaofuncional</category>
      <category>brailizandevs</category>
    </item>
    <item>
      <title>Using Bean Validation on Quarkus.io</title>
      <dc:creator>Victor Osório</dc:creator>
      <pubDate>Mon, 25 Jan 2021 14:07:08 +0000</pubDate>
      <link>https://dev.to/vepo/using-bean-validation-on-quarkus-io-3h1i</link>
      <guid>https://dev.to/vepo/using-bean-validation-on-quarkus-io-3h1i</guid>
      <description>&lt;p&gt;&lt;a href="https://beanvalidation.org/latest-draft/spec/" rel="noopener noreferrer"&gt;Jakarta Bean Validation&lt;/a&gt; is a very useful specification. I can't find any reason to do not use it. If you know, please share with me.&lt;/p&gt;

&lt;h2&gt;
  
  
  The worst way to do it
&lt;/h2&gt;

&lt;p&gt;Validation is a boring feature. It is important, but most of the time it pollutes the code. You have to check function by function if all values are according to the expected.&lt;/p&gt;

&lt;p&gt;So, let's imagine the in the code of our Step 02 we need to validate that the &lt;code&gt;username&lt;/code&gt; is a String not empty, with a minimum size of 4 and a maximum of 15 and no whitespace. How can we do it?&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="nd"&gt;@POST&lt;/span&gt;
&lt;span class="nd"&gt;@Produces&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON&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;User&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CreateUserRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;requireNonNull&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUsername&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"\"username\" cannot be null!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUsername&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;isBlank&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;BadRequestException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\"username\" may not be blank"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUsername&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;matches&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"^[a-zA-Z][a-zA-Z0-9]+$"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;BadRequestException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\"username\" should start with a letter and should only accept letters and numbers"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUsername&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUsername&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;BadRequestException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\"username\" should have size [4,15]"&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;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEmail&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUsername&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getFirstName&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLastName&lt;/span&gt;&lt;span class="o"&gt;()).&lt;/span&gt;&lt;span class="na"&gt;admin&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isAdmin&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hashedPassword&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getHashedPassword&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&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;Jakarta Bean Validation allow us to remove all this code and replace with simple annotations.&lt;/p&gt;
&lt;h2&gt;
  
  
  Configuring JPA in an existent Quarkus Project
&lt;/h2&gt;

&lt;p&gt;To enable Jakarta Bean Validation, you should add it's implementation to Quarkus, that is &lt;a href="https://hibernate.org/validator/" rel="noopener noreferrer"&gt;Hibernate Validator&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.quarkus&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;quarkus-hibernate-validator&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That is all you need! Now you just need to configure where you will use and what fields you want to validate.&lt;/p&gt;
&lt;h2&gt;
  
  
  Requiring Valid Parameters
&lt;/h2&gt;

&lt;p&gt;The next step, you should informe Quarkus, where you want to use the validate. From the example above, we can remove all validation lines and just add the annotation &lt;code&gt;javax.validation.Valid&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="nd"&gt;@POST&lt;/span&gt;
&lt;span class="nd"&gt;@Produces&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON&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;User&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Valid&lt;/span&gt; &lt;span class="nc"&gt;CreateUserRequest&lt;/span&gt; &lt;span class="n"&gt;request&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;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEmail&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUsername&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getFirstName&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLastName&lt;/span&gt;&lt;span class="o"&gt;()).&lt;/span&gt;&lt;span class="na"&gt;admin&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isAdmin&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hashedPassword&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getHashedPassword&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&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;Then we need inform Quarkus the logic for this validation, it can be done inside CreataUserRequest class. We will use the annotations &lt;code&gt;Email&lt;/code&gt;, &lt;code&gt;NotBlank&lt;/code&gt;, &lt;code&gt;Pattern&lt;/code&gt; and &lt;code&gt;Size&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="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.validation.constraints.Email&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;javax.validation.constraints.NotBlank&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;javax.validation.constraints.Pattern&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;javax.validation.constraints.Size&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;CreateUserRequest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Email&lt;/span&gt;
    &lt;span class="nd"&gt;@NotBlank&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"email may not be blank"&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;email&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"username should have size [{min},{max}]"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@NotBlank&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"username may not be blank"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@Pattern&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;regexp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"^[a-zA-Z][a-zA-Z0-9]+$"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"\"username\" should start with a letter and should only accept letters and numbers"&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;username&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@NotBlank&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"firstName may not be blank"&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;firstName&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@NotBlank&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"lastName may not be blank"&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;lastName&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;boolean&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@NotBlank&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"hashedPassword may not be blank"&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;hashedPassword&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// [Getters and Setters]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This can be used in any Managed Bean inside Quarkus, but if you used on Endpoints it will enable HTTP validation returning a Bad Request response, as we can see in the response bellow. This is not a good way to present errors on a REST API, but at least follow some patterns as returning the correct HTTP Status Code and informing all constraint violations.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"classViolations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"parameterViolations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"constraintType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PARAMETER"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;username&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; should start with a letter and should only accept letters and numbers"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"create.request.username"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2vepo"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"propertyViolations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"returnValueViolations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you need to add validation for a parameter that you do not implement the class, like a &lt;code&gt;String&lt;/code&gt; or a primitive type, you can use the annotations directly on the bean paramenter. In this case you can ommit the &lt;code&gt;Valid&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="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findByUsername&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;15&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;username&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;TypedQuery&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createNamedQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"User.findByUsername"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;User&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="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;username&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;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getResultStream&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;findFirst&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;h2&gt;
  
  
  Creating Custom Validations
&lt;/h2&gt;

&lt;p&gt;Now that we are able to use the Built-in validations, let's create some custom validators. First we need to define the annotation for it. It should have the following pattern.&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="nd"&gt;@Documented&lt;/span&gt;
&lt;span class="nd"&gt;@Constraint&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validatedBy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ReservedWordValidator&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="nd"&gt;@Target&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt;
    &lt;span class="no"&gt;METHOD&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="no"&gt;FIELD&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="no"&gt;ANNOTATION_TYPE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="no"&gt;CONSTRUCTOR&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="no"&gt;PARAMETER&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="no"&gt;TYPE_USE&lt;/span&gt; &lt;span class="o"&gt;})&lt;/span&gt;
&lt;span class="nd"&gt;@Retention&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;RUNTIME&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Repeatable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ReservedWords&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="nd"&gt;@SupportedValidationTarget&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ANNOTATED_ELEMENT&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@ReportAsSingleViolation&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nd"&gt;@interface&lt;/span&gt; &lt;span class="nc"&gt;ReservedWord&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;value&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="s"&gt;"You are using a Reserved Word"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Payload&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;[]&lt;/span&gt; &lt;span class="nf"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="o"&gt;{};&lt;/span&gt;

    &lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;[]&lt;/span&gt; &lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="k"&gt;default&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;In our case we are creating a &lt;code&gt;Repeatable&lt;/code&gt; just for an example, but you can set any kind of Type for value. Then we need to declare and implement the Validator. As you can see, we are already linking the Validator with the Annotation using &lt;code&gt;@Constraint(validatedBy = ReservedWordValidator.class)&lt;/code&gt;, now we only need to implement it.&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ReservedWordValidator&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ConstraintValidator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ReservedWord&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;&amp;gt;&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;word&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="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ReservedWord&lt;/span&gt; &lt;span class="n"&gt;wordAnnotation&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;word&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;wordAnnotation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="o"&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="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isValid&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;value&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ConstraintValidatorContext&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;return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compareToIgnoreCase&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&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;Now you can use it in your service.&lt;/p&gt;
&lt;h2&gt;
  
  
  Executing and Testing
&lt;/h2&gt;

&lt;p&gt;With the database running you only need to start the Quarkus using maven.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn quarkus:dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In our example, we have provided 2 endpoints where you can test with valid and invalid parameters.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create an User: &lt;code&gt;POST /user&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Find User by Username: &lt;code&gt;GET /user/{username}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://app.getpostman.com/run-collection/f9fc24e64abbfb3aac90" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frun.pstmn.io%2Fbutton.svg" alt="Run in Postman" width="128" height="32"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can find all the code on github.com/vepo/quarkus-tutorial.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/vepo" rel="noopener noreferrer"&gt;
        vepo
      &lt;/a&gt; / &lt;a href="https://github.com/vepo/quarkus-tutorial" rel="noopener noreferrer"&gt;
        quarkus-tutorial
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      This is a series of blog posts where I will create a tutorial of Quakus.io.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Quarkus Tutorial&lt;/h1&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Steps&lt;/h1&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;1. Create a REST API&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/vepo/quarkus-tutorial./step-01-configure-quarkus/README.md" rel="noopener noreferrer"&gt;More information&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the first example, we create a minimal REST API using Quarkus and JAX-RS.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;2. Configure JPA &lt;em&gt;Jakarta Persistence&lt;/em&gt;
&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/vepo/quarkus-tutorial./step-02-configure-jpa/README.md" rel="noopener noreferrer"&gt;More information&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the second example, we add the persistence layer for our REST API.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;3. Configure Jakarta Bean Validation&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/vepo/quarkus-tutorial./step-03-bean-validation/README.md" rel="noopener noreferrer"&gt;More information&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the third example, we add the validation to all layers of our REST API.&lt;/p&gt;

&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/vepo/quarkus-tutorial" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h2&gt;
  
  
  Design by Contract
&lt;/h2&gt;

&lt;p&gt;The most important concept on Validating parameters is &lt;strong&gt;Design By Contract&lt;/strong&gt;. A contract defines you rights and responsability, if you define a contract you will not handle values outside that contract. And using Bean Validation enable you to implement Orthogonal Contracts, keeping your code clear. You do not mix validation with business logic. And you don't need to replicated code, only adding an annotation you can spread validation in all your Managed Beans.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Quarkus is easy to configure. You can remove a lot of code, only creating validations.&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%2Fi%2Fe65xl1069bgqs8ge87wm.jpg" 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%2Fi%2Fe65xl1069bgqs8ge87wm.jpg" alt="Man drawing a Software Architecture diagram" width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
Foto de Startup Stock Photos no Pexels&lt;/p&gt;

</description>
      <category>quarkus</category>
      <category>java</category>
      <category>beanvalidation</category>
      <category>brailizandevs</category>
    </item>
    <item>
      <title>Log Cleanup no Kafka</title>
      <dc:creator>Victor Osório</dc:creator>
      <pubDate>Fri, 27 Nov 2020 19:07:35 +0000</pubDate>
      <link>https://dev.to/vepo/log-cleanup-no-kafka-dg2</link>
      <guid>https://dev.to/vepo/log-cleanup-no-kafka-dg2</guid>
      <description>&lt;p&gt;Ao ler o livro &lt;a href="https://www.confluent.io/designing-event-driven-systems/" rel="noopener noreferrer"&gt;Designing Event-Driven Systems&lt;/a&gt;, tive a impressão que o Kafka atua exatamente como uma base de dados. Essa é uma informação falsa. Ele pode atuar como uma base de dados, desde que seja configurado para. &lt;/p&gt;

&lt;p&gt;Nesse post vou mostrar algumas configurações de tópicos que deve ser feitas para que o dado seja persistente e não efêmero.&lt;/p&gt;

&lt;h1&gt;
  
  
  Partições e Segmentos
&lt;/h1&gt;

&lt;p&gt;Espero que você já conheça alguns elementos importantes de um tópico, como Partições e Fator de Replicação. Caso não conheça, leia &lt;a href="https://dev.to/vepo/anatomia-de-um-topico-25da"&gt;Anatomia de um Tópico &lt;/a&gt; para podermos conhecer basicamente como funciona um tópico.&lt;/p&gt;

&lt;p&gt;No post anterior, só entrei até o detalhe do número de partição, pois essa é a parte importante quando falamos de &lt;strong&gt;ordenação de mensagens&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Já quando falamos de Cleanup, precisamos introduzir Segmentos. Cada partição, é subdividida em Segmentos. Segmentos contém os dados ordenados sequencialmente (um arquivo de log), assim como a partição. Ao escrever, o Broker escreve apenas ao final do último segmento da partição. Mas os dados são lidos sequencialmente pelos consumers.&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%2Fi%2Fu7rtsztzbog3f4n5lxon.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%2Fi%2Fu7rtsztzbog3f4n5lxon.png" alt="Segmentos" width="620" height="140"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se formos fazer um levantamento nas configurações de um tópico, podemos ver que muitas das propriedades são referentes não somente ao tópico, mas ao segmento.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Propriedade&lt;/th&gt;
&lt;th&gt;Descrição&lt;/th&gt;
&lt;th&gt;Valor Padrão&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://kafka.apache.org/documentation/#segment.bytes" rel="noopener noreferrer"&gt;&lt;code&gt;segment.bytes&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Tamanho do arquivo de segmento.&lt;/td&gt;
&lt;td&gt;1073741824 (1 GB)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://kafka.apache.org/documentation/#segment.index.bytes" rel="noopener noreferrer"&gt;&lt;code&gt;segment.index.bytes&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Tamanho do arquivo de index do segmento.&lt;/td&gt;
&lt;td&gt;10485760 (10 MB)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://kafka.apache.org/documentation/#segment.jitter.ms" rel="noopener noreferrer"&gt;&lt;code&gt;segment.jitter.ms&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;O jitter aleatório máximo subtraído do tempo de rolagem do segmento programado para evitar sobrecargas.&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://kafka.apache.org/documentation/#segment.ms" rel="noopener noreferrer"&gt;&lt;code&gt;segment.ms&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Idade máxima do segmento. O Kafka fará a rolagem para garantir sua limpeza&lt;/td&gt;
&lt;td&gt;604800000 (7 dias)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Todos esses valores também podem ser configurados por cluster. A configuração de cluster é usando como padrão, caso o valor não seja configurado no Tópico.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Configuração do Tópico&lt;/th&gt;
&lt;th&gt;Configuração do Broker&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;segment.bytes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;log.segment.bytes&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;segment.index.bytes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;log.index.size.max.bytes&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;segment.jitter.ms&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;log.roll.jitter.ms&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;segment.ms&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;log.roll.ms&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Dado os valores de &lt;code&gt;segmento.ms&lt;/code&gt; e &lt;code&gt;segment.bytes&lt;/code&gt;, o Kafka decidirá quando um segmento será finalizado para que outro seja inicializado.&lt;/p&gt;

&lt;p&gt;O arquivo de index, como o nome já diz, é um índice que mapeia em qual posição do arquivo de offset uma mensagem está armazenada, garantindo assim ao Kafka que qualquer mensagem seja lida em tempo constante.&lt;/p&gt;

&lt;p&gt;Há também um outro arquivo de index, o &lt;code&gt;timeindex&lt;/code&gt;. Este tem como função criar um index baseado no timestamp da mensagem.&lt;/p&gt;

&lt;h1&gt;
  
  
  Políticas de Limpeza
&lt;/h1&gt;

&lt;p&gt;Mas o que o Kafka faz com mensagens antigas? Isso é configurável por Tópico ou no Cluster.&lt;/p&gt;

&lt;p&gt;Essa configuração é muito importante se você usa seu Cluster como Fonte de Verdade ou caso você precise fazer um reset de todo pipeline.&lt;/p&gt;

&lt;p&gt;Para configurar é preciso alterar o valor de &lt;code&gt;cleanup.policy&lt;/code&gt; (ou &lt;code&gt;log.cleanup.policy&lt;/code&gt; para o Cluster). Essa propriedade aceita os valores &lt;code&gt;compact&lt;/code&gt; e &lt;code&gt;delete&lt;/code&gt;. Por padrão, essas propriedades vêm como &lt;code&gt;delete&lt;/code&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Delete
&lt;/h2&gt;

&lt;p&gt;Quando a política de limpeza selecionada é delete, o Kafka vai remover o segmento baseado na sua idade ou no tamanho da partição.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Propriedade&lt;/th&gt;
&lt;th&gt;Descrição&lt;/th&gt;
&lt;th&gt;Valor Padrão&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://kafka.apache.org/documentation/#retention.ms" rel="noopener noreferrer"&gt;&lt;code&gt;retention.ms&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Idade máxima de um segmento&lt;/td&gt;
&lt;td&gt;604800000 (7 dias)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://kafka.apache.org/documentation/#retention.bytes" rel="noopener noreferrer"&gt;&lt;code&gt;retention.bytes&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Tamanho máximo da partição&lt;/td&gt;
&lt;td&gt;-1 (desabilitado)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Vale lembrar que essas duas propriedades podem também ser configuradas por Cluster.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Configuração do Tópico&lt;/th&gt;
&lt;th&gt;Configuração do Broker&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;retention.ms&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;log.retention.ms&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;retention.bytes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;log.retention.bytes&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Compactação
&lt;/h2&gt;

&lt;p&gt;A compactação do Log vai fazer uma limpeza, mas garantindo que você terá ao menos a última mensagem enviada por chave. Assim teremos apenas a última informação de cada chave.&lt;/p&gt;

&lt;p&gt;A compactação não irá alterar os offsets das mensagens, uma mensagem é imutável. Irá apenas remover mensagem com &lt;code&gt;offset&lt;/code&gt; inferior a última mensagem de cada chave.&lt;/p&gt;

&lt;p&gt;Mensagens anda podem ser recebidas, mesmo depois de removidas, isso é feito baseado na propriedade &lt;a href="https://kafka.apache.org/documentation/#delete.retention.ms" rel="noopener noreferrer"&gt;&lt;code&gt;delete.retention.ms&lt;/code&gt;&lt;/a&gt;. Após esse tempo se esgotar a mensagem não será recebida.&lt;/p&gt;

&lt;p&gt;Uma mensagem apagada, significa que novos consumidores não a receberão. Consumidores que já estejam recebendo mensagens não perceberão que o histórico foi alterado, a não ser que este tenha seu offset reiniciado.&lt;/p&gt;

&lt;p&gt;A compactação ocorre quando o segmento é finalizado.&lt;/p&gt;

&lt;h1&gt;
  
  
  Implicações
&lt;/h1&gt;

&lt;p&gt;Ao desenvolvedor e arquiteto, uma pergunta deve ser feita. Quais as implicações da escolha da política de limpeza?&lt;/p&gt;

&lt;p&gt;Um Cluster terá suas configurações padrão, mas cada Tópico pode ter sua própria configuração.&lt;/p&gt;

&lt;h2&gt;
  
  
  Delete
&lt;/h2&gt;

&lt;p&gt;Ao se escolher por remover mensagens de um Tópico, deve-se ter ciência que novos consumers não receberão mensagens antigas. Vamos imaginar que, com os valores padrões, a idade máxima de uma mensagem será 14 dias. Assim, se um tópico é considerado fonte de verdade, deve ter os valores de &lt;code&gt;retention.ms&lt;/code&gt; e &lt;code&gt;retention.bytes&lt;/code&gt; configurados corretamente.&lt;/p&gt;

&lt;p&gt;Para se calcular o volume de dados armazenado por Tópico, é preciso levar em consideração o tamanho médio de uma mensagem, o número de mensagens por dia e o tempo de retenção de uma mensagem. Essa é uma informação que o Arquiteto de Software tem que ter, e mesmo que não tenha, deve estimar baseado nas estatisticas da aplicação.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compactação
&lt;/h2&gt;

&lt;p&gt;Ao se escolher compactar segmentos de um Tópico, deve-se ter ciência que uma mensagem não deve conter apenas uma atualização de estado, mas a informação completa. Caso haja apenas atualização de estado, haverá perca de dados.&lt;/p&gt;

&lt;p&gt;Para se calcular o volume de dados armazenado por Tópico, é necessário ter ciência do número de chaves únicas e o tamanho médio da mensagem, e adicionar o tamanho máximo de um segmento.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusão
&lt;/h1&gt;

&lt;p&gt;Kafka pode ser usado como Fonte de Verdade, mas antes deve-se conhecer a fundo como configurar. As configurações padrão garantem que uma mensagem ficará armazenada por entre 7 e 14 dias, mas isso pode ser alterado de acordo com os requisitos do sistema.&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%2Fi%2F1os85b4rmdpauz3yjbsu.jpg" 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%2Fi%2F1os85b4rmdpauz3yjbsu.jpg" alt="Hard Disk" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Foto de &lt;strong&gt;Azamat E&lt;/strong&gt; no &lt;a href="https://www.pexels.com/pt-br/foto/analogico-analogo-aparelhos-armazenamento-117729/" rel="noopener noreferrer"&gt;&lt;strong&gt;Pexels&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>kafka</category>
      <category>apachekafka</category>
      <category>microservices</category>
      <category>brailizandevs</category>
    </item>
    <item>
      <title>Configure JPA on Quarkus.io</title>
      <dc:creator>Victor Osório</dc:creator>
      <pubDate>Thu, 26 Nov 2020 03:23:42 +0000</pubDate>
      <link>https://dev.to/vepo/configure-jpa-on-quarkus-7gb</link>
      <guid>https://dev.to/vepo/configure-jpa-on-quarkus-7gb</guid>
      <description>&lt;p&gt;JPA is a specification from Jakarta EE that controls the Data Access Layer. The most common implementation for it is &lt;a href="https://hibernate.org/orm/" rel="noopener noreferrer"&gt;Hibernate ORM&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Trade-offs
&lt;/h1&gt;

&lt;p&gt;Choose technology involves a trade-off. I always thought that if I choose JPA, I will lose control of any generated SQL. And that is true!&lt;/p&gt;

&lt;p&gt;JPA is an ORM, so most of the SQL is generated from a JPQL. If you do a bad design of your code, you will have SQL been generated at execution time, that is a bad design. In truth, horrible design.&lt;/p&gt;

&lt;p&gt;But you will boost your coding speed. You will no more care about writing SQL or modelling the database. You can think in terms of objects, not tables. This does not mean that you will not care about modelling. In the first time is better to create the database model before, than design the objects according to what you want. This will avoid you creating some very commons Anti Patterns from JPA. I, have worked on a project where if you get a user from the database, you can load all objects associated with that user on the memory crashing the application.&lt;/p&gt;

&lt;p&gt;It is important to know well the specification to create an optimal service, balancing database performance with development speed.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Advantages&lt;/th&gt;
&lt;th&gt;Aisadvantages&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Fast Coding&lt;/td&gt;
&lt;td&gt;SQL is generated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Easy to change the model&lt;/td&gt;
&lt;td&gt;Lack of support for NoSQL ¹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database agnostic&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;¹ Use &lt;a href="https://www.jnosql.org/" rel="noopener noreferrer"&gt;JNoSQL&lt;/a&gt; instead of JPA&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Configuring JPA in an existent Quarkus Project
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Configure dependencies
&lt;/h2&gt;

&lt;p&gt;So the first step is to configure the dependencies. For adding JPA you will have to add the Hibernate Plugin and the Database JDBC plugin. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why we have two dependencies?&lt;/em&gt; This is one of the code ideas of JPA, it is database agnostic. You can change your database with almost no change on your code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.quarkus&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;quarkus-hibernate-orm&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.quarkus&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;quarkus-jdbc-postgresql&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you want to know which database you can use, just search on &lt;a href="https://mvnrepository.com/search?q=jdbc&amp;amp;d=io.quarkus" rel="noopener noreferrer"&gt;mvnrepository.com&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Modeling the database
&lt;/h2&gt;

&lt;p&gt;The next step we need to model the database. You probably have your database model using SQL, but you need to create Java POJOs that will map your data in your Java code.&lt;/p&gt;

&lt;p&gt;For this example we will create a backend CRUD for User. That means we will create the Create, Read, Update and Delete endpoints for it.&lt;/p&gt;

&lt;p&gt;So, to model we have to add the annotations:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Annotation&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;javax.persistence.Entity&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specifies that the class is an entity.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;javax.persistence.Table&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specifies the primary table for the annotated entity.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;javax.persistence.Id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specifies the primary key of an entity.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;javax.persistence.Column&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specifies the mapped column for a persistent property or field.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Not even all annotations are required, but you should do a good design of your code.&lt;/p&gt;

&lt;p&gt;So I'm defining the User adding all required annotations, and some NamedQuery and a Builder. The builder is just a fancy code to improve the readability and the NamedQuery it will be used later to search for users.&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="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;io.vepo.tutorial.quarkus.user&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;javax.persistence.Column&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;javax.persistence.Entity&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;javax.persistence.GeneratedValue&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;javax.persistence.GenerationType&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;javax.persistence.Id&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;javax.persistence.NamedQuery&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;javax.persistence.Table&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;javax.persistence.UniqueConstraint&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Entity&lt;/span&gt;
&lt;span class="nd"&gt;@Table&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"tb_users"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;uniqueConstraints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@UniqueConstraint&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"uq_users_username"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;columnNames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"username"&lt;/span&gt; &lt;span class="o"&gt;}),&lt;/span&gt;
    &lt;span class="nd"&gt;@UniqueConstraint&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"uq_users_email"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;columnNames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="o"&gt;})&lt;/span&gt;
&lt;span class="o"&gt;})&lt;/span&gt;
&lt;span class="nd"&gt;@NamedQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"User.findByUsernameAndHashedPassword"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"SELECT usr FROM User usr WHERE usr.username = :username AND usr.hashedPassword = :hashedPassword AND usr.enabled = true"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@NamedQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"User.findByUsername"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"SELECT usr FROM User usr WHERE usr.username = :username"&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;User&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;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserBuilder&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;email&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;username&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;firstName&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;lastName&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;boolean&lt;/span&gt; &lt;span class="n"&gt;admin&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;hashedPassword&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;UserBuilder&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="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;UserBuilder&lt;/span&gt; &lt;span class="nf"&gt;email&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;email&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;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&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;this&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;UserBuilder&lt;/span&gt; &lt;span class="nf"&gt;username&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;username&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;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;username&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;this&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;UserBuilder&lt;/span&gt; &lt;span class="nf"&gt;firstName&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;firstName&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;firstName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;firstName&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;this&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;UserBuilder&lt;/span&gt; &lt;span class="nf"&gt;lastName&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;lastName&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;lastName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lastName&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;this&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;UserBuilder&lt;/span&gt; &lt;span class="nf"&gt;admin&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;admin&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;admin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;admin&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;this&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;UserBuilder&lt;/span&gt; &lt;span class="nf"&gt;hashedPassword&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;hashedPassword&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;hashedPassword&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hashedPassword&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;this&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;User&lt;/span&gt; &lt;span class="nf"&gt;build&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="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;User&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="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="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;UserBuilder&lt;/span&gt; &lt;span class="nf"&gt;builder&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="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;UserBuilder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Id&lt;/span&gt;
    &lt;span class="nd"&gt;@GeneratedValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GenerationType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;IDENTITY&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;Integer&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Column&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;email&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Column&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;username&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Column&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"first_name"&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;firstName&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Column&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"last_name"&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;lastName&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Column&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Column&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"hashed_password"&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;hashedPassword&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Column&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"enabled"&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;boolean&lt;/span&gt; &lt;span class="n"&gt;enabled&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;User&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="kd"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;User&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;UserBuilder&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;firstName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;lastName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;admin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;admin&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;hashedPassword&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hashedPassword&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;enabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&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;Integer&lt;/span&gt; &lt;span class="nf"&gt;getId&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;id&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;setId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;id&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;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id&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;getEmail&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;email&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;setEmail&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;email&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;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&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;getUsername&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;username&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;setUsername&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;username&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;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;username&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;getFirstName&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;firstName&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;setFirstName&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;firstName&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;firstName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;firstName&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;getLastName&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;lastName&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;setLastName&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;lastName&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;lastName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lastName&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;boolean&lt;/span&gt; &lt;span class="nf"&gt;isAdmin&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;admin&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;setAdmin&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;admin&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;admin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;admin&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;getHashedPassword&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;hashedPassword&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;setHashedPassword&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;hashedPassword&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;hashedPassword&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hashedPassword&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;boolean&lt;/span&gt; &lt;span class="nf"&gt;isEnabled&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;enabled&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;setEnabled&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;enabled&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;enabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="o"&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="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;hashCode&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;prime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&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="n"&gt;prime&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="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hashCode&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="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&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="n"&gt;obj&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="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&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="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&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="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&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="kc"&gt;false&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="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&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="kc"&gt;false&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="kc"&gt;true&lt;/span&gt;&lt;span class="o"&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;String&lt;/span&gt; &lt;span class="nf"&gt;toString&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="s"&gt;"User [id="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;", email="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;", username="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;", firstName="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;firstName&lt;/span&gt;
                &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;", lastName="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;lastName&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;", admin="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;", hashedPassword="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;hashedPassword&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;", enabled="&lt;/span&gt;
                &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;enabled&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&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;I want to point out some important things on this code. The &lt;code&gt;@Column&lt;/code&gt; annotation is not required, if you omit does not mean that JPA will ignore, it will only read the column with the same name from the field. If you want a not persisted column, you should use create a &lt;code&gt;transient&lt;/code&gt; field. If you have a compound name for the field, for example, &lt;code&gt;lastName&lt;/code&gt;, if you do not specify the name in &lt;code&gt;@Column&lt;/code&gt;, JPA will search for &lt;code&gt;lastName&lt;/code&gt;, not &lt;code&gt;last_name&lt;/code&gt;. I don't know if you have understood, but naming is important! All applications should follow naming conventions and the &lt;a href="https://dzone.com/articles/a-guide-to-sql-naming-conventions" rel="noopener noreferrer"&gt;SQL Naming Convetions&lt;/a&gt; is different from &lt;a href="https://www.oracle.com/java/technologies/javase/codeconventions-namingconventions.html" rel="noopener noreferrer"&gt;Java Naming Convetions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With the &lt;code&gt;@Column&lt;/code&gt; you have more options, like &lt;code&gt;required&lt;/code&gt; and &lt;code&gt;unique&lt;/code&gt;. You can see all options on &lt;a href="https://jakarta.ee/specifications/persistence/2.2/apidocs/javax/persistence/Column.html" rel="noopener noreferrer"&gt;Jakarta Documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For the &lt;code&gt;id&lt;/code&gt; column, I have added two important annotations. &lt;code&gt;@Id&lt;/code&gt; and &lt;code&gt;@GeneratedValue&lt;/code&gt;are required to create a good design, but if you choose a different database probably it will have different values! &lt;/p&gt;

&lt;p&gt;I have added the Unique Constraints, this is not required, but as I'm creating the database automatically, I have to do it. In a future tutorial I will teach how to use Flyway to create automatically the database using SQL.&lt;/p&gt;
&lt;h2&gt;
  
  
  Define the parameters
&lt;/h2&gt;

&lt;p&gt;Hibernate requires few parameters to configure, you can put all in &lt;code&gt;src/main/resources/application.properties&lt;/code&gt;. But you can also replace it using environment variables. This will take place later in a tutorial from Microprofile Config.&lt;/p&gt;

&lt;p&gt;So we need to define the Database type and credentials and what Hibernate will do with the Schema. For production always use &lt;code&gt;quarkus.hibernate-orm.database.generation=validate&lt;/code&gt;, but in our example, we will use &lt;code&gt;drop-and-create&lt;/code&gt; recreating the database schema every deploy.&lt;/p&gt;

&lt;p&gt;If you need to change more configurations properties, the &lt;a href="https://quarkus.io/guides/hibernate-orm#quarkus-hibernate-orm_configuration" rel="noopener noreferrer"&gt;Quarkus documentation has a list of all available configurations&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;quarkus.datasource.db-kind&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;postgresql&lt;/span&gt;
&lt;span class="py"&gt;quarkus.datasource.username&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
&lt;span class="py"&gt;quarkus.datasource.password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;password&lt;/span&gt;
&lt;span class="py"&gt;quarkus.datasource.jdbc.url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;jdbc:postgresql://localhost:5432/tutorial&lt;/span&gt;

&lt;span class="py"&gt;quarkus.hibernate-orm.database.generation&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;drop-and-create&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Creating the database
&lt;/h2&gt;

&lt;p&gt;To create the database, we will use Docker. So just execute the line bellow.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; postgres-db &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;password &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;tutorial &lt;span class="nt"&gt;-p&lt;/span&gt; 5432:5432 &lt;span class="nt"&gt;-d&lt;/span&gt; postgres:13-alpine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you want to use Postgres directly, just download and install it. It will work fine.&lt;/p&gt;
&lt;h2&gt;
  
  
  Acessing the database
&lt;/h2&gt;

&lt;p&gt;There is a lot of ways to access the database, but you should always use &lt;code&gt;javax.persistence.EntityManager&lt;/code&gt;. I have created a service class called &lt;code&gt;Users&lt;/code&gt; and added some methods to show the best way to access it.&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="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;io.vepo.tutorial.quarkus.user&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;java.util.List&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;java.util.Objects&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;java.util.Optional&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;javax.enterprise.context.ApplicationScoped&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;javax.persistence.EntityManager&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;javax.persistence.PersistenceContext&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;javax.persistence.TypedQuery&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;javax.persistence.criteria.CriteriaBuilder&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;javax.persistence.criteria.CriteriaQuery&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;javax.transaction.Transactional&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Transactional&lt;/span&gt;
&lt;span class="nd"&gt;@ApplicationScoped&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;Users&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@PersistenceContext&lt;/span&gt;
    &lt;span class="nc"&gt;EntityManager&lt;/span&gt; &lt;span class="n"&gt;em&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;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;CriteriaBuilder&lt;/span&gt; &lt;span class="n"&gt;criteriaBuilder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getCriteriaBuilder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;CriteriaQuery&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;criteriaBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;User&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="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;User&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;getResultList&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;User&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nonNull&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;()))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalStateException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Id should be null!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;persist&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&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;user&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;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findByUsername&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;username&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;TypedQuery&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createNamedQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"User.findByUsername"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;User&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="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;username&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;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getResultStream&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;findFirst&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;User&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;userId&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;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;User&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="n"&gt;userId&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;h3&gt;
  
  
  Using Criteria Builder
&lt;/h3&gt;

&lt;p&gt;Using Criteria Builder is a good way when you need to generate dynamically the query. You will create the query programmatically, the API is not so easy to understand because it is very powerful.&lt;/p&gt;
&lt;h3&gt;
  
  
  Using Named Query
&lt;/h3&gt;

&lt;p&gt;For me, Named Queries is the best way to execute commons queries. You have to write the query on JPQL, not SQL. JPQL is very similar to SQL, but you can use the same query in different databases, Hibernate will translate it for you. It is better to use it than custom JPQL queries because it will compile it once.&lt;/p&gt;
&lt;h3&gt;
  
  
  Using Query
&lt;/h3&gt;

&lt;p&gt;You can create the query directly. But this is not a good approach! Every time you call &lt;code&gt;createQuery&lt;/code&gt; it will compile the query.&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="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findByUsername&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;username&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;TypedQuery&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SELECT usr FROM User usr WHERE usr.username = :username"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;User&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="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;username&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;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getResultStream&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;findFirst&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;h3&gt;
  
  
  Access the data directly
&lt;/h3&gt;

&lt;p&gt;If you have a Class and an Id, you can access the object directly.&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="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;userId&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;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;User&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="n"&gt;userId&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;h3&gt;
  
  
  Transactional Objects
&lt;/h3&gt;

&lt;p&gt;As we are using a transactional object, all changes we do in the JPA object it will be updated on the database. Each object read from the database is attached to the current session.&lt;/p&gt;
&lt;h2&gt;
  
  
  Executing and Testing
&lt;/h2&gt;

&lt;p&gt;With the database running you only need to start the Quarkus using maven.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn quarkus:dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In our example, we have provided 3 endpoints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;List all Users: &lt;code&gt;GET /user&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create an User: &lt;code&gt;POST /user&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Find User by Username: &lt;code&gt;GET /user/{username}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can find all code in the repository bellow.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/vepo" rel="noopener noreferrer"&gt;
        vepo
      &lt;/a&gt; / &lt;a href="https://github.com/vepo/quarkus-tutorial" rel="noopener noreferrer"&gt;
        quarkus-tutorial
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      This is a series of blog posts where I will create a tutorial of Quakus.io.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Quarkus Tutorial&lt;/h1&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Steps&lt;/h1&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;1. Create a REST API&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/vepo/quarkus-tutorial./step-01-configure-quarkus/README.md" rel="noopener noreferrer"&gt;More information&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the first example, we create a minimal REST API using Quarkus and JAX-RS.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;2. Configure JPA &lt;em&gt;Jakarta Persistence&lt;/em&gt;
&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/vepo/quarkus-tutorial./step-02-configure-jpa/README.md" rel="noopener noreferrer"&gt;More information&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the second example, we add the persistence layer for our REST API.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;3. Configure Jakarta Bean Validation&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/vepo/quarkus-tutorial./step-03-bean-validation/README.md" rel="noopener noreferrer"&gt;More information&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the third example, we add the validation to all layers of our REST API.&lt;/p&gt;

&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/vepo/quarkus-tutorial" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;And you can test it using Postman.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://app.getpostman.com/run-collection/f9fc24e64abbfb3aac90" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frun.pstmn.io%2Fbutton.svg" alt="Run in Postman" width="128" height="32"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;If you want to develop fast and use databases, you should use JPA. You will not be worried about queries and knowing the JPA features and implementation, you can optimize the access from your database.&lt;/p&gt;

&lt;h1&gt;
  
  
  Future Readings
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/spgroup/ORM-Smells-Catalog" rel="noopener noreferrer"&gt;Catálogo de Code Smells ORM&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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%2Fi%2Fiy1m1az6tcyceagl8o5a.jpg" 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%2Fi%2Fiy1m1az6tcyceagl8o5a.jpg" alt="Cover Image. A data center with many servers" width="800" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>quarkus</category>
      <category>java</category>
      <category>jpa</category>
      <category>brailizandevs</category>
    </item>
    <item>
      <title>How to set up a REST API using Quarkus.io</title>
      <dc:creator>Victor Osório</dc:creator>
      <pubDate>Tue, 10 Nov 2020 12:32:21 +0000</pubDate>
      <link>https://dev.to/vepo/how-to-set-up-a-rest-api-using-quarkus-io-56m3</link>
      <guid>https://dev.to/vepo/how-to-set-up-a-rest-api-using-quarkus-io-56m3</guid>
      <description>&lt;h1&gt;
  
  
  Why Quarkus is a good choice?
&lt;/h1&gt;

&lt;p&gt;Quarkus is one of the best frameworks for Java! First, there was the Wildfly, that as an experiment became a microservices focus project called Wildfly Swarm. Then Wildfly Swarm was renamed to Thorntail. The main purpose of Thorntail was to build a Jakarta EE implementation build for microservices. But there was some pitfall that needed a full rewrite for the code. So this is Quarkus, a light implementation, ready for microservices and it has native support to GraalVM.&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%2Fi%2F6dk8bybj6fylk0wlmtfq.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%2Fi%2F6dk8bybj6fylk0wlmtfq.png" alt="Quarkus metrics" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So Quarkus is based on &lt;a href="https://docs.thorntail.io/4.0.0-SNAPSHOT/" rel="noopener noreferrer"&gt;lessons learned&lt;/a&gt; from previous development. Based on these lessons I believe this will be a better framework, easy to use and fast on execution.&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%2Fi%2Fi1e4iz13iuf790bszwt5.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%2Fi%2Fi1e4iz13iuf790bszwt5.png" alt="Thorntail icon" width="64" height="64"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Mangling artifacts is dangerous&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;When you mangle and repackage a user’s artifacts and dependencies, it can many times go awry.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don’t replace Maven&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Let Maven (or Gradle) handle the entirety of pulling dependencies. We cannot predict the topology of someone’s repository managers, proxies and network.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don’t get complicated with uberjars&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;The more complex our uberjar layout is, the harder it is to support Gradle or other non-Maven build systems.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Classpaths are tricky&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;If different codepaths are required for executing from Maven, an IDE, a unit-test, and during production, you will have a bad time.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don’t insist on uberjars&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;For Linux containers, people want layers that cleanly separate application code from runtime support code.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testability is important&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;A slow test is a test that is never willingly executed. PRs take forever to validate. Users like to be able to test their own code quickly and iteratively.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Easily extensible means ecosystem&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;If it’s entirely too difficult to extend the platform, the ecosystem will not grow. New integrations should be simple.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related: Core things should not be any more first-class than community contributions&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;For instance, auto-detection in WildFly Swarm only worked with core fractions; user-provided wouldn’t auto-detect.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ensure the public-vs-private API guarantees are clear.&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Intertwingly code (and javadocs) make finding the delineation between public API and private implementations difficult.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Allow BYO components&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;We don’t want to decide all of the implementations, and certainly not versions, of random components we support.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be a framework, not a platform&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Frameworks are easier to integrate into an existing app; a platform becomes the target with (generally too many) constraints.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Maintain tests &amp;amp; documentation&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Ensure the definition of "done" includes both tests and documentation.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Productization complexity&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;The greater divergence between community and product, the more effort is required for productization. Complicating any process to automate productization from community.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BOM complexity&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Related to productization as well, but of itself having a handful of BOMs made life confusing for us and for users. There were often times where fractions would be "Unstable" or "Experimental" for months with no real reason other than we forgot to update it.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Configure Quarkus
&lt;/h1&gt;

&lt;p&gt;The first question we need to answer on a tutorial is: &lt;em&gt;To build a project using Quarkus, what do you need?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For Quarkus we need:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add the dependencies&lt;/li&gt;
&lt;li&gt;Configure the package&lt;/li&gt;
&lt;li&gt;Starting coding&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Configure the dependencies
&lt;/h2&gt;

&lt;p&gt;As Quarkus is a Jakarta EE, we will use the Jakarta EE annotations on the code. But, for the &lt;code&gt;pom.xml&lt;/code&gt; we should point to Quarkus dependencies because quarkus has native support for GraalVM.&lt;/p&gt;

&lt;p&gt;First we need add all dependencies to Quarkus, this can be done using dependencyManagement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependencyManagement&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.quarkus&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;quarkus-universe-bom&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.9.2.Final&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;type&amp;gt;&lt;/span&gt;pom&lt;span class="nt"&gt;&amp;lt;/type&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;import&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependencyManagement&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The for that project we will need:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create REST API&lt;/li&gt;
&lt;li&gt;Add JSON Support&lt;/li&gt;
&lt;li&gt;Add Reactive Support&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For that we will need the following dependencies:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;io.quarkus:io.quarkus&lt;/code&gt; for creating the REST API&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;io.quarkus:quarkus-resteasy-jsonb&lt;/code&gt; for adding JSON serializer to REST API&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;io.quarkus:quarkus-resteasy-mutiny&lt;/code&gt; for adding reactive support for REST API&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  2. Configuring the build
&lt;/h2&gt;

&lt;p&gt;The next step we should configure Quarkus build. As we know, Quarkus creates a fat jar with all dependencies.&lt;/p&gt;

&lt;p&gt;To enable the Quarkus builder on Maven, just add the following plugin:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.quarkus&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;quarkus-maven-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.9.2.Final&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;generate-code&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;generate-code-tests&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;build&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In this example, I'm compiling as Java 11, but I'm using Java 15 to test. It will work for any version of Java newer than 11. If you need to execute it on Java 8, just change the compiler options.&lt;/p&gt;

&lt;p&gt;We can make the build just executing:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn clean package
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This will create two &lt;code&gt;jars&lt;/code&gt; inside the target folder, the one terminating with &lt;code&gt;-runner.jar&lt;/code&gt; can be executed with no dependencies.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;java &lt;span class="nt"&gt;-jar&lt;/span&gt; target&lt;span class="se"&gt;\q&lt;/span&gt;uarkus-tutorial-runner.jar
__  ____  __  _____   ___  __ ____  ______
 &lt;span class="nt"&gt;--&lt;/span&gt;/ __ &lt;span class="se"&gt;\/&lt;/span&gt; / / / _ | / _ &lt;span class="se"&gt;\/&lt;/span&gt; //_/ / / / __/
 -/ /_/ / /_/ / __ |/ , _/ ,&amp;lt; / /_/ /&lt;span class="se"&gt;\ \&lt;/span&gt;
&lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="se"&gt;\_&lt;/span&gt;__&lt;span class="se"&gt;\_\_&lt;/span&gt;___/_/ |_/_/|_/_/|_|&lt;span class="se"&gt;\_&lt;/span&gt;___/___/
2020-11-09 11:16:53,416 INFO  &lt;span class="o"&gt;[&lt;/span&gt;io.quarkus] &lt;span class="o"&gt;(&lt;/span&gt;main&lt;span class="o"&gt;)&lt;/span&gt; quarkus-tutorial 0.0.1-SNAPSHOT on JVM &lt;span class="o"&gt;(&lt;/span&gt;powered by Quarkus 1.9.2.Final&lt;span class="o"&gt;)&lt;/span&gt; started &lt;span class="k"&gt;in &lt;/span&gt;4.706s. Listening on: http://0.0.0.0:8080
2020-11-09 11:16:53,470 INFO  &lt;span class="o"&gt;[&lt;/span&gt;io.quarkus] &lt;span class="o"&gt;(&lt;/span&gt;main&lt;span class="o"&gt;)&lt;/span&gt; Profile prod activated.
2020-11-09 11:16:53,475 INFO  &lt;span class="o"&gt;[&lt;/span&gt;io.quarkus] &lt;span class="o"&gt;(&lt;/span&gt;main&lt;span class="o"&gt;)&lt;/span&gt; Installed features: &lt;span class="o"&gt;[&lt;/span&gt;cdi, mutiny, resteasy, resteasy-jsonb, resteasy-mutiny, smallrye-context-propagation]
2020-11-09 11:16:58,790 INFO  &lt;span class="o"&gt;[&lt;/span&gt;io.quarkus] &lt;span class="o"&gt;(&lt;/span&gt;Shutdown thread&lt;span class="o"&gt;)&lt;/span&gt; quarkus-tutorial stopped &lt;span class="k"&gt;in &lt;/span&gt;0.024s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This is the way we should execute for production environments, for development we can use Quarkus Maven plugin. It already does the deploy of any change on the running server:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn quarkus:dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  3. Adding the REST API Endpoint
&lt;/h2&gt;

&lt;p&gt;The latest step for creating an API is creating the code that will handle the requests. Using JAX-RS is easy, just create a class and add the annotations. &lt;/p&gt;

&lt;p&gt;The most simple example is:&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="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/hello"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@ApplicationScoped&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;HelloEndpoint&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@GET&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;sayHello&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="s"&gt;"Hello World!"&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;JAX-RS automatically generate a JSON representation for any object returned by this method, you have just to inform the MIME Type.&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="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/hello"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@ApplicationScoped&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;HelloEndpoint&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;HelloResponse&lt;/span&gt; &lt;span class="nf"&gt;generateResponse&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;HelloResponse&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;HelloResponse&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;setCode&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;Random&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;nextInt&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;setMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World!"&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="nd"&gt;@GET&lt;/span&gt;
    &lt;span class="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/json"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@Produces&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON&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;HelloResponse&lt;/span&gt; &lt;span class="nf"&gt;sayHelloWithJson&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="nf"&gt;generateResponse&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;Quarkus also have support for reactive programming. For JAX-RS, you have just to return a &lt;code&gt;Uni&lt;/code&gt; or a &lt;code&gt;CompletableFuture&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="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/hello"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@ApplicationScoped&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;HelloEndpoint&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;HelloResponse&lt;/span&gt; &lt;span class="nf"&gt;generateResponse&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;HelloResponse&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;HelloResponse&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;setCode&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;Random&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;nextInt&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;setMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World!"&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="nd"&gt;@GET&lt;/span&gt;
    &lt;span class="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/json/reactive"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@Produces&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON&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;Uni&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HelloResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;sayHelloWithJsonReactively&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="nc"&gt;Uni&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createFrom&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;item&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="n"&gt;generateResponse&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;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;With Quarkus you can build quickly a REST API using JAX-RS. As JAX-RS is a Jakarta EE specification, you can migrate your code with few changes to another existing implementation, but Quarkus is the lighter implementation. &lt;/p&gt;

&lt;p&gt;Quarkus is a good choice! &lt;/p&gt;

&lt;p&gt;You can find all examples on &lt;a href="https://github.com/vepo/quarkus-tutorial" rel="noopener noreferrer"&gt;github.com/vepo/quarkus-tutorial&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/vepo" rel="noopener noreferrer"&gt;
        vepo
      &lt;/a&gt; / &lt;a href="https://github.com/vepo/quarkus-tutorial" rel="noopener noreferrer"&gt;
        quarkus-tutorial
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      This is a series of blog posts where I will create a tutorial of Quakus.io.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Quarkus Tutorial&lt;/h1&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Steps&lt;/h1&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;1. Create a REST API&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/vepo/quarkus-tutorial./step-01-configure-quarkus/README.md" rel="noopener noreferrer"&gt;More information&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the first example, we create a minimal REST API using Quarkus and JAX-RS.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;2. Configure JPA &lt;em&gt;Jakarta Persistence&lt;/em&gt;
&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/vepo/quarkus-tutorial./step-02-configure-jpa/README.md" rel="noopener noreferrer"&gt;More information&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the second example, we add the persistence layer for our REST API.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;3. Configure Jakarta Bean Validation&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/vepo/quarkus-tutorial./step-03-bean-validation/README.md" rel="noopener noreferrer"&gt;More information&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the third example, we add the validation to all layers of our REST API.&lt;/p&gt;

&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/vepo/quarkus-tutorial" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&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%2Fi%2Fonndm6f6d2r6xt8rs4z4.jpg" 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%2Fi%2Fonndm6f6d2r6xt8rs4z4.jpg" alt="Cover Image" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>quarkus</category>
      <category>java</category>
      <category>brailizandevs</category>
      <category>jakartaee</category>
    </item>
    <item>
      <title>Installing an Old Kubernetes version on Windows</title>
      <dc:creator>Victor Osório</dc:creator>
      <pubDate>Tue, 27 Oct 2020 20:55:40 +0000</pubDate>
      <link>https://dev.to/vepo/installing-an-old-kubernetes-version-on-windows-2an0</link>
      <guid>https://dev.to/vepo/installing-an-old-kubernetes-version-on-windows-2an0</guid>
      <description>&lt;p&gt;Yes, sometimes we need to downgrade. So that was my problem I need to maintain an application using Windows and Kubernetes 1.17.&lt;/p&gt;

&lt;h1&gt;
  
  
  First attempt
&lt;/h1&gt;

&lt;p&gt;I try to install the Kubernetes package inside Docker. But... For now, I only have the version 1.19! I know that I should reproduce the same environment from the deployment.&lt;/p&gt;

&lt;h1&gt;
  
  
  Second attempt
&lt;/h1&gt;

&lt;p&gt;What if I deploy Rancher v2?&lt;/p&gt;

&lt;p&gt;We have one problem. The latest version of Rancher doesn't create a Kubernetes 1.17 cluster, only a 1.19!&lt;/p&gt;

&lt;p&gt;So I have to find a version of Rancher that creates the cluster on the required version. I found it on the version &lt;code&gt;2.3.8&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So to get this Rancher open a CMD running as Administrator and execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --name rancher --privileged -d --restart=unless-stopped -p 10080:80 -p 10443:443 rancher/rancher:v2.3.8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why I'm not using port &lt;code&gt;80&lt;/code&gt; and &lt;code&gt;443&lt;/code&gt;? Because ETCD will use these ports, let them free!&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;p&gt;If you tried running more than one Kubernetes Cluster on Windows with WSL, you will have a problem with client certification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2020-10-27 20:14:53.231000 I | etcdserver: published {Name:etcd-docker-desktop ClientURLs:[https://192.168.65.3:2379 https://192.168.65.3:4001]} to cluster 3c0da32f1ef888fb
2020-10-27 20:14:53.232544 I | embed: serving client requests on [::]:2379
2020-10-27 20:14:53.241806 I | embed: rejected connection from "192.168.65.3:43330" (error "tls: failed to verify client's certificate: x509: certificate signed by unknown authority (possibly because of \"crypto/rsa: verification error\" while trying to verify candidate authority certificate \"kube-ca\")", ServerName "")
2020-10-27 20:14:58.251358 I | embed: rejected connection from "192.168.65.3:43744" (error "tls: failed to verify client's certificate: x509: certificate signed by unknown authority (possibly because of \"crypto/rsa: verification error\" while trying to verify candidate authority certificate \"kube-ca\")", ServerName "")
2020-10-27 20:15:03.258650 I | embed: rejected connection from "192.168.65.3:43908" (error "tls: failed to verify client's certificate: x509: certificate signed by unknown authority (possibly because of \"crypto/rsa: verification error\" while trying to verify candidate authority certificate \"kube-ca\")", ServerName "")
2020-10-27 20:16:22.390547 I | embed: rejected connection from "192.168.65.3:46707" (error "EOF", ServerName "")
2020-10-27 20:16:36.732519 I | embed: rejected connection from "192.168.65.3:47178" (error "tls: failed to verify client's certificate: x509: certificate signed by unknown authority (possibly because of \"crypto/rsa: verification error\" while trying to verify candidate authority certificate \"kube-ca\")", ServerName "")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This happens because Rancher ETCD creates a folder inside the host machine and reuse some data. You can find that information on the log:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2020-10-27 20:14:43.703157 N | etcdmain: the server is already initialized as member before, starting as etcd member...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the line above, ETCD is informing us that it will use a certificate for an old cluster. This will produce an error.&lt;/p&gt;

&lt;p&gt;To resolve this problem, you should remove all data from &lt;code&gt;/var/lib/etcd&lt;/code&gt;. I could not find that folder on Windows File System, so I open the &lt;strong&gt;Docker Troubleshoot&lt;/strong&gt; and select &lt;strong&gt;Clean / Purge data&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%2Fi%2Fkzy1aj9d5dy7dmaa2o6w.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%2Fi%2Fkzy1aj9d5dy7dmaa2o6w.png" alt="Docker Troubleshoot" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;You can run any version of Kubernetes using Windows, WSL and Rancher. You have only to find the correct versions.&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%2Fi%2F2o33rjz6jnhgttdbomqk.jpg" 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%2Fi%2F2o33rjz6jnhgttdbomqk.jpg" alt="Picture by Julius Silver from Pexels" width="800" height="538"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Picture by &lt;strong&gt;Julius Silver&lt;/strong&gt; from &lt;strong&gt;Pexels&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>windows</category>
      <category>wsl</category>
      <category>docker</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Docker 101 - Tecnologias e Conceitos</title>
      <dc:creator>Victor Osório</dc:creator>
      <pubDate>Thu, 22 Oct 2020 13:45:27 +0000</pubDate>
      <link>https://dev.to/vepo/docker-101-tecnologias-e-conceitos-3p5o</link>
      <guid>https://dev.to/vepo/docker-101-tecnologias-e-conceitos-3p5o</guid>
      <description>&lt;p&gt;&lt;em&gt;Este material era para ser um curso de Docker. Mas eu não tenho skills para gravação/edição de vídeo. Minha intenção aqui é apresentar alguns conceitos básicos de Docker.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  O que é Docker?
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Antes de iniciar qualquer curso sobre Docker, precisamos primeiro entender o que é Docker? Essa pergunta pode não ter uma resposta muito simples, visto que você pode ouvir esse termo em vários contextos diferentes.&lt;/p&gt;

&lt;p&gt;Para responder vamos levantar as seguintes perguntas?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Seria Docker uma empresa?&lt;/li&gt;
&lt;li&gt;Seria Docker um software?&lt;/li&gt;
&lt;li&gt;Seria Docker uma plataforma?&lt;/li&gt;
&lt;li&gt;Seria Docker uma tecnologia?&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Seria Docker uma empresa?
&lt;/h3&gt;

&lt;p&gt;SIM!&lt;/p&gt;

&lt;p&gt;Sim Docker é a empresa que criou o Docker. A &lt;strong&gt;Docker, Inc.&lt;/strong&gt; provê soluções Enterprise e o Docker Hub.&lt;/p&gt;

&lt;h3&gt;
  
  
  Seria Docker um Software?
&lt;/h3&gt;

&lt;p&gt;SIM!&lt;/p&gt;

&lt;p&gt;Sim, você pode executar um &lt;code&gt;docker --version&lt;/code&gt; em qualquer máquina com Docker instalado. Ele é desenvolvido pela &lt;strong&gt;Docker, Inc.&lt;/strong&gt; e pode ser instalado em qualquer dos mais comuns SOs do mercado.&lt;/p&gt;

&lt;h3&gt;
  
  
  Seria Docker uma Plataforma?
&lt;/h3&gt;

&lt;p&gt;Podemos dizer que SIM!&lt;/p&gt;

&lt;p&gt;Não sou tão assertivo nessa resposta porque o termo plataforma é genérico. Mas há uma série de componentes no Docker que nos permite chamar ele de plataforma. Você usa docker para criar imagens, que pode ser armazenadas em um Docker Registry, que serão carregadas por um Gerenciador de Containers. Há inúmeros nós nessa teia.&lt;/p&gt;

&lt;h3&gt;
  
  
  Seria Docker uma Tecnologia?
&lt;/h3&gt;

&lt;p&gt;Com certeza SIM!&lt;/p&gt;

&lt;p&gt;O que a &lt;strong&gt;Docker, Inc.&lt;/strong&gt; criou foi muito além de um software. Ela utilizou vários recursos já existente para criar um conceito a &lt;em&gt;containerização&lt;/em&gt;. Com isso se gerou uma Explosão Cambriana na industria. Novos conceitos e padrões surgirão depois dele. &lt;/p&gt;

&lt;p&gt;Assim podemos dizer que a maneira de se gerenciar uma infra-estrutura em 2019 é completamente diferente da maneira que se gerenciava em 2005. &lt;strong&gt;COMPLETAMENTE DIFERENTE!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Depois do advento do Docker, a &lt;strong&gt;Docker, Inc.&lt;/strong&gt; cedeu sua &lt;em&gt;core engine&lt;/em&gt; para &lt;a href="https://www.cncf.io/" rel="noopener noreferrer"&gt;Cloud Native Computing Foundation&lt;/a&gt; sob o nome de &lt;a href="https://github.com/containerd/containerd" rel="noopener noreferrer"&gt;containerd&lt;/a&gt;. Você pode ver pela &lt;a href="https://landscape.cncf.io/" rel="noopener noreferrer"&gt;CNCF Landscape&lt;/a&gt; que o containerd é uma caixinha em Container Runtime. A evolução da tecnologia não é mais controlada pela &lt;strong&gt;Docker, Inc.&lt;/strong&gt;, mas por essa organização que faz parte da Linux Foundation.&lt;/p&gt;

&lt;h2&gt;
  
  
  A tecnologia Docker
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;"Na natureza nada se cria, nada se perde, tudo se transforma"&lt;/em&gt; Antoine-Laurent de Lavoisier&lt;/p&gt;

&lt;p&gt;Essa frase de Lavoisier se adequa perfeitamente a projetos Open Source! Na verdade Docker não criou nada novo e nem utilizou nenhuma tecnologia nova, mas a partir do que existia uma nova tecnologia foi criada. &lt;/p&gt;

&lt;h3&gt;
  
  
  Tecnologias Bases
&lt;/h3&gt;

&lt;p&gt;Docker se baseia em algumas tecnologias já existentes no Linux.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pt.wikipedia.org/wiki/C%C3%B3pia_em_grava%C3%A7%C3%A3o" rel="noopener noreferrer"&gt;COW - Copy On Write&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Cgroups" rel="noopener noreferrer"&gt;cgroups&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pt.wikipedia.org/wiki/Iptables" rel="noopener noreferrer"&gt;iptables&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Linux_namespaces" rel="noopener noreferrer"&gt;Linux Namespaces&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  COW
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Copy On Write&lt;/em&gt; é uma técnica que permite a criação de uma estrutura de arquivos por camada. Cada camada altera a anterior e camadas podem ser compartilhadas com processos diferentes.&lt;/p&gt;

&lt;h4&gt;
  
  
  cgroups
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;cgroups&lt;/em&gt; é uma feature do Linux que permite controlar o tanto de recurso (CPU, Memória, I/O) que um processo pode utilizar.&lt;/p&gt;

&lt;h4&gt;
  
  
  iptables
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;iptables&lt;/em&gt; é um programa Linux que permite criar regras de redirecionamento de portas dentro do Linux.&lt;/p&gt;

&lt;h4&gt;
  
  
  Linux Namespaces
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Linux Namespaces&lt;/em&gt; permite o compartilhamento, e o isolamento, de recursos do SO dentro do Linux. Similar ao &lt;em&gt;cgroups&lt;/em&gt;, mas se refere a outros tipos de recursos. Por exemplos: PIDs, nomes de arquivos, hostnames, etc...&lt;/p&gt;

&lt;h2&gt;
  
  
  Infraestrutura Imutável
&lt;/h2&gt;

&lt;p&gt;O termo &lt;strong&gt;Immutable Infrastructure&lt;/strong&gt; vem em contraste ao que tinhamos antes do Docker, que é a &lt;strong&gt;Mutable Infraestructure&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Em uma Infraestrutura mutável, para fazer qualquer alteração em ambientes, deve-se alterar as configurações existente. Cada atualização há um risco muito grande que deve ser minimizado por técnicas como rollback, dry-run e backups. Cada update é um risco, pois o novo deploy vem alterar o antigo.&lt;/p&gt;

&lt;p&gt;Com a infraestrutura imutável, o novo deploy vem em paralelo ao antigo. É criado uma nova estrutura e o mesmo substitui o antigo. Assim, caso o novo apresente falhas, o antigo pode ser reutilizado.&lt;/p&gt;

&lt;h3&gt;
  
  
  Antes do Docker
&lt;/h3&gt;

&lt;p&gt;Antes do Docker existir, para fazer a configuração de um serviço era preciso alguns passos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Configurar um Servidor (Instalar Linux, Unix ou Windows)&lt;/li&gt;
&lt;li&gt;Instalar dependências (Apacha httpd, Java, Python, etc...)&lt;/li&gt;
&lt;li&gt;Configurar o Servidor de Aplicação (JBoss, IIS)&lt;/li&gt;
&lt;li&gt;Fazer deploy da Aplicação &lt;/li&gt;
&lt;li&gt;Monitorar o estado da Aplicação (&lt;a href="https://mmonit.com/monit/" rel="noopener noreferrer"&gt;monit&lt;/a&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Configurar um servidor era a tarefa mais fácil, o difícil era fazer atualizações ou gerenciar projetos legados. Muitas vezes duas aplicações precisam de diferentes dependências para rodar. Ou tinha problema com o compartilhamento de recursos, duas aplicações tentando escutar na mesma porta TCP. &lt;/p&gt;

&lt;p&gt;Atualizar um servidor de produção, envolvia criar scripts para fazer diversas alterações que nem sempre funcionavam na produção. Quando um erro acontecia na implementação.... ROLLBACK! O que também era uma atividade complexa!&lt;/p&gt;

&lt;h3&gt;
  
  
  Possível solução
&lt;/h3&gt;

&lt;p&gt;Uma boa e possível solução era a criação de &lt;strong&gt;fotos&lt;/strong&gt; (ou &lt;em&gt;snapshots&lt;/em&gt;) do servidor. E se pudéssemos a partir de uma foto rodar um servidor? Ou voltar para uma versão anterior a partir de uma foto? E se esse servidor fosse totalmente isolado? Posso executar duas versões dele em paralelo?&lt;/p&gt;

&lt;h3&gt;
  
  
  Depois do Docker
&lt;/h3&gt;

&lt;p&gt;Para executar um servidor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull my-application:1.0.1
docker stop my-app
docker &lt;span class="nb"&gt;rm &lt;/span&gt;my-app
docker run &lt;span class="nt"&gt;-name&lt;/span&gt; my-app &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:80 my-application:1.0.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com as 4 linhas acima, podemos atualizar uma aplicação chamada &lt;code&gt;my-application&lt;/code&gt; para versão 1.0.1. Deu erro?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker stop my-app
docker &lt;span class="nb"&gt;rm &lt;/span&gt;my-app
docker run &lt;span class="nt"&gt;-name&lt;/span&gt; my-app &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:80 my-application:1.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mais 3 linhas para fazer o rollback seguro!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conceitos Básicos
&lt;/h2&gt;

&lt;p&gt;Um pouco antes do Docker, uma das tecnologias da moda era a virtualização. Mas em que consistia a virtualização e porque a necessidade de containerização&lt;/p&gt;

&lt;h3&gt;
  
  
  Virtualização
&lt;/h3&gt;

&lt;p&gt;Talvez você já tenha criado uma Máquina Virtual. Se não criou, gaste algum tempo baixando o VirtualBox e rodando algumas versões de SOs diferentes dentro da sua máquina.&lt;/p&gt;

&lt;p&gt;Quando falamos de virtualização, estamos dividindo os recursos físicos da máquina com outras máquinas, que são chamadas máquinas virtuais. Assim, podemos alocar 1 CPU, 2GB de memória, etc... Nessa máquina rodará um Sistema Operacional completo que não compartilhará nenhum recurso com nenhum outro. Se esse SO não utilizar todo o recurso alocado, este não poderá ser compartilhado.&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%2Fi%2Fq40xfw2qlei05qihud6m.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%2Fi%2Fq40xfw2qlei05qihud6m.png" alt="Virtual Machine" width="421" height="609"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Containerização
&lt;/h3&gt;

&lt;p&gt;Com containers todas as aplicações compartilham o mesmo SO. O SO rodará a aplicação isoladamente, criando e alocando qualquer recurso que o container necessitar.&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%2Fi%2Ffj02eotpgiggs4mqfrgo.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%2Fi%2Ffj02eotpgiggs4mqfrgo.png" alt="Containers" width="421" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Vantagens
&lt;/h4&gt;

&lt;p&gt;Como a containerização acontece no nível do Sistema Operacional, há uma série de vantagens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Inicialização imediata. Não é necessário se inicializar o Sistema Operacional&lt;/li&gt;
&lt;li&gt;Compartilhamento de Recursos. Caso o container não utilize Memoria ou CPU, esta fica disponível para outro.&lt;/li&gt;
&lt;li&gt;É possível criar mais uma instância do mesmo container imediatamente.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Docker Building Blocks
&lt;/h2&gt;

&lt;p&gt;Gosto do conceito de Building Blocks, quando me refiro a ele estou definindo elementos básicos para algo. Assim em Docker podemos definir alguns building blocks.&lt;/p&gt;

&lt;p&gt;Para o desenvolvimento de qualquer aplicação Docker, é necessário entender o que são cada um desses elementos.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Imagem

&lt;ul&gt;
&lt;li&gt;TAGs&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Container

&lt;ul&gt;
&lt;li&gt;Volume&lt;/li&gt;
&lt;li&gt;Network&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Registry&lt;/li&gt;

&lt;li&gt;Dockerfile&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Imagem
&lt;/h3&gt;

&lt;p&gt;Uma Imagem é uma foto do Container em seu momento inicial. Se formos comparar com os conceitos de máquinas virtuais, a Imagem seria um SNAPSHOT.&lt;/p&gt;

&lt;p&gt;Uma Imagem é usada para gerar um Container. Uma Imagem pode ser gerada a partir de um Container. Uma Imagem tem algumas propriedades que estendem o conceito de Snapshot, podemos definir qual comando a Imagem irá executar assim que ela iniciar.&lt;/p&gt;

&lt;p&gt;Uma Imagem é preferencialmente construida a partir de um Dockerfile.&lt;/p&gt;

&lt;h3&gt;
  
  
  TAGs
&lt;/h3&gt;

&lt;p&gt;Uma Imagem pode ter uma ou mais TAG associada. Cada imagem possui um nome, este nome pode estar associado a várias TAGs. &lt;/p&gt;

&lt;p&gt;Por exemplo, se formos criar um container do MariaDB, sabemos que o nome dele é &lt;code&gt;mariadb&lt;/code&gt;. Mas se referenciarmos apenas esse nome, será baixada a image &lt;code&gt;mariadb:latest&lt;/code&gt;, o que não é tão bom, visto que não sabemos exatamente qual versão será executada. No caso do MariaDB, temos as seguintes TAGs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;10.4.10-bionic, 10.4-bionic, 10-bionic, bionic, 10.4.10, 10.4, 10, latest&lt;/li&gt;
&lt;li&gt;10.3.20-bionic, 10.3-bionic, 10.3.20, 10.3&lt;/li&gt;
&lt;li&gt;10.2.29-bionic, 10.2-bionic, 10.2.29, 10.2&lt;/li&gt;
&lt;li&gt;10.1.43-bionic, 10.1-bionic, 10.1.43, 10.1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Uma boa opção, seria utilizar &lt;code&gt;mariadb:10.4&lt;/code&gt; para escolher a versão &lt;strong&gt;10.4.10&lt;/strong&gt; ou qualquer versão futura com bug fixes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Container
&lt;/h3&gt;

&lt;p&gt;Um Container é uma instância de uma aplicação. Pode haver vários Containers rodando com a partir da mesma Imagem. Ao se executar um Container é preciso uma Imagem e um conjunto de informações:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Volumes&lt;/li&gt;
&lt;li&gt;Variáveis de Ambiente&lt;/li&gt;
&lt;li&gt;Portas&lt;/li&gt;
&lt;li&gt;etc...&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Volume
&lt;/h3&gt;

&lt;p&gt;O Sistema de Arquivo de um Container é descartável. Assim, ao se remover o container, todos os arquivos dele são removidos. Um Volume é um mapeamento entre um diretório da máquina hospedeira para o container. Usando COW, o diretório, ou arquivo, dentro container é sobrescrito. &lt;/p&gt;

&lt;h3&gt;
  
  
  Network
&lt;/h3&gt;

&lt;p&gt;Quando um container é executado, pode pertencer a uma ou várias Networks. Por padrão, ele pertence a Network Default. Para cada Network associada, ele terá um IP NAT associado. &lt;/p&gt;

&lt;p&gt;Uma Network serve para criar uma VPC. Dois containers só podem se comunicar se pertencerem a mesma Network. Uma Network contém DNS que resolve o IP através do nome do container. Assim, se um container tentar acessar &lt;code&gt;container-1:8080&lt;/code&gt; estará tentando acessar a porta &lt;strong&gt;8080&lt;/strong&gt; do container com nome &lt;strong&gt;container-1&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Registry
&lt;/h3&gt;

&lt;p&gt;Um Registry é um servidor web para armazenar uma Imagem. No ciclo de vida de uma Imagem, ela pode ser gerada ou baixada de um Registry. &lt;/p&gt;

&lt;p&gt;O padrão é o &lt;a href="https://hub.docker.com/" rel="noopener noreferrer"&gt;Docker Hub&lt;/a&gt;, sempre que possível procure imagens lá. No Docker Hub há imagens verificadas e não verificadas. Procure usar as imagens verificadas, caso contrário você pode estar correndo o risco de expor seus dados.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dockerfile
&lt;/h3&gt;

&lt;p&gt;Dockerfile é o script de criação de uma Imagem. Uma Imagem deve ser construida através de um script, e pode ser reconstruida em qualquer máquina.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusão
&lt;/h1&gt;

&lt;p&gt;Docker pode parecer uma mágica, mas é só o uso inteligente de tecnologias há muito tempo já existiam no Sistema Operacional Linux. Com o uso dessas tecnologias, podemos agora criar deploys completamente independentes dentro de um mesmo sistema operacional, usando a mesma infraestrutura. &lt;/p&gt;

&lt;p&gt;Com Docker não há o desperdício de recursos que existia com a Virtualização. Agora os recursos podem ser alocados de forma mais inteligente.&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%2Fi%2Fvpwhp0r7ampxf1jywqv8.jpg" 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%2Fi%2Fvpwhp0r7ampxf1jywqv8.jpg" alt="Navio carregado de Containers" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.pexels.com/pt-br/foto/panorama-vista-paisagem-agua-3057963/" rel="noopener noreferrer"&gt;Foto de &lt;em&gt;Tom Fisk&lt;/em&gt; no &lt;em&gt;Pexels&lt;/em&gt;.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>containers</category>
      <category>devops</category>
      <category>linux</category>
    </item>
    <item>
      <title>Ágil 101 - O que devo saber?</title>
      <dc:creator>Victor Osório</dc:creator>
      <pubDate>Sat, 03 Oct 2020 21:25:44 +0000</pubDate>
      <link>https://dev.to/vepo/agil-101-o-que-devo-saber-21d2</link>
      <guid>https://dev.to/vepo/agil-101-o-que-devo-saber-21d2</guid>
      <description>&lt;p&gt;Ágil é um adjetivo. Ele descreve uma característica de algo. Mas Ágil não pode vir sozinho, pois seu uso se refere a uma comparação. &lt;em&gt;Um ninja é mais ágil que um lutador de sumô&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Quando falamos de Ágil no mundo do Desenvolvimento de Software estamos falando de um movimento que veio em resposta aos modelos gerenciais predominantes até 2001.&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%2Fi%2Fnk0ojzs854v9j83lff1v.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%2Fi%2Fnk0ojzs854v9j83lff1v.png" alt="Significado de Ágil" width="654" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Porque 2001? Porque foi em 2001 que &lt;a href="https://amzn.to/3cYFN94" rel="noopener noreferrer"&gt;Kent Back&lt;/a&gt; reuniu um pessoal, que muitos não se gostam publicamente hoje, para discutir os Modelos de Desenvolvimento de Software. De lá saiu &lt;a href="https://agilemanifesto.org/iso/ptbr/manifesto.html" rel="noopener noreferrer"&gt;um manifesto&lt;/a&gt; que se você não o conhece... Bom, ele define o que é Ágil.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Estamos descobrindo maneiras melhores de desenvolver software, fazendo-o nós mesmos e ajudando outros a fazerem o mesmo. Através deste trabalho, passamos a valorizar:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indivíduos e interações&lt;/strong&gt; mais que processos e ferramentas&lt;br&gt;
&lt;strong&gt;Software em funcionamento&lt;/strong&gt; mais que documentação abrangente&lt;br&gt;
&lt;strong&gt;Colaboração com o cliente&lt;/strong&gt; mais que negociação de contratos&lt;br&gt;
&lt;strong&gt;Responder a mudanças&lt;/strong&gt; mais que seguir um plano&lt;/p&gt;

&lt;p&gt;Ou seja, mesmo havendo valor nos itens à direita, valorizamos mais os itens à esquerda.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Eu vou falar sobre cada item desse manifesto, mas antes precisamos entender como é a gerência de projetos não-ágil e qual a ideia por trás do ágil.&lt;/p&gt;

&lt;h1&gt;
  
  
  Antes do Ágil havia o PMBOK
&lt;/h1&gt;

&lt;p&gt;A disciplina de Gerência de Projetos é bastante complexa e precisamos ter em mente que não há certo e errado. Há padrões e esses padrões podem ser aplicados em contextos. O &lt;a href="https://pt.wikipedia.org/wiki/Project_Management_Body_of_Knowledge" rel="noopener noreferrer"&gt;PMBOK&lt;/a&gt;, &lt;em&gt;Project Management Body of Knowledge&lt;/em&gt;, é bastante útil e é largamente utilizado na indústria e governos. Ele consiste em uma série práticas que vão definir como um projeto deve ser gerenciado. Temos os processos, documentos que devem ser gerados, reuniões que deve ser feitas, etc..&lt;/p&gt;

&lt;p&gt;Antes do Ágil, o padrão PMBOK era imposto dentro da empresa. Todos os projetos tinha que seguir exatamente o que estava definido lá. E é lá que temos o famoso Cascata, em que entre a definição do que será entregue e a entrega temos meses onde não há comunicação entre &lt;strong&gt;Equipe de Desenvolvimento&lt;/strong&gt; e &lt;strong&gt;Cliente&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Vale ressaltar que esse modelo é muito bom e funciona para outros tipos de projetos. Pensa bem, o que pode dar errado no meio do caminha da construção de um prédio? Muito diferente da construção de um software.&lt;/p&gt;

&lt;h1&gt;
  
  
  Ideias por trás do Ágil
&lt;/h1&gt;

&lt;p&gt;Antes que você pense que o Ágil foi uma revolução, não. Nos anos 90, o que aconteceu foi que ideias que já existiam de administração começaram a ser aplicada em Desenvolvimento de Software. &lt;/p&gt;

&lt;h2&gt;
  
  
  LEAN
&lt;/h2&gt;

&lt;p&gt;Um das ideias bem óbvias no Ágil e que passa despercebido por quem não conhece é a influencia do livro &lt;a href="https://amzn.to/2SqxVDO" rel="noopener noreferrer"&gt;Toyota Kata: Gerenciando Pessoas para Melhoria, Adaptabilidade e Resultados Excepcionais &lt;/a&gt; (&lt;em&gt;nunca li&lt;/em&gt;). Observe o que é dito nos apendices do livro &lt;a href="https://amzn.to/3cWxjPy" rel="noopener noreferrer"&gt;O Projeto Fênix&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As liçoes do Sr. Rother foram codificadas no livro &lt;em&gt;Toyota Kata&lt;/em&gt;, que estrutura o processo de planejamento e cultura que deve existir para permitir o ciclo PDCA Lean (Planejar, Fazer, Verificar, Agir). Acredito que essa seja uma das contribuições mais extraordinárias para o mundo da melhoria dos processos.&lt;br&gt;
A manifestação mais óbvia do &lt;em&gt;Toyota Kata&lt;/em&gt; é o ciclo de melhoria de duas semanas, no qual cada supervisor de centro de trabalho deve melhorar algo (qualquer coisa!) a cada duas semanas. Para citar o Sr. Rother, "A prática do kata é o ato de praticar um padrão para que ele se torne uma segunda natureza. Em sua gestão diária, a Toyota ensina uma maneira de trabalhar - um kata - que tem ajudado a torná-la muito bem-sucedida nas últimas décadas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Podemos ver claramente dois pontos aqui óbvios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ciclo de duas semanas&lt;/li&gt;
&lt;li&gt;Para cada letra do LEAN (PDCA em Português), tem uma reunião no SCRUM. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Gestão da Equipe
&lt;/h2&gt;

&lt;p&gt;A Gestão de uma Equipe também é baseada em ideias que vem de livros influentes. O SCRUM vai tentar resolver os problemas levantados no livro &lt;a href="https://amzn.to/30v0rbI" rel="noopener noreferrer"&gt;Os 5 desafios das equipes&lt;/a&gt; (&lt;em&gt;não li também&lt;/em&gt;). Observe o que é dito nos apendices do livro &lt;a href="https://amzn.to/3cWxjPy" rel="noopener noreferrer"&gt;O Projeto Fênix&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Em seu modelo, as cincos disfunções são descritas como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ausência de confiança - relutância em ser vulnerável dentro do grupo&lt;/li&gt;
&lt;li&gt;Medo de conflito - buscando harmonia artificial sobre debate fervoroso construtivo&lt;/li&gt;
&lt;li&gt;Falta de comprometimento - fingir comprar as decisões do grupo cria uma ambiguidade na organização&lt;/li&gt;
&lt;li&gt;Evitação de responsabilidade - desviar da responsabilidade para chamar a atenção dos colegas sobre comportamento contraprodutivo, que estabelece padrões baixos&lt;/li&gt;
&lt;li&gt;Desatenção aos resultados - focar no sucesso pessoal, status e ego antes do sucesso da equipe&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cada ponto desse é direcionado por alguma prática do SCRUM ou XP. Em uma simples descrição da equipe desejada pelo SCRUM, há muita teoria de administração de equipes.&lt;/p&gt;

&lt;h1&gt;
  
  
  O Manifesto
&lt;/h1&gt;

&lt;p&gt;Para se por em prática o Manifesto Ágil, é preciso ser um gestor e ter poder sobre os processo da empresa. PONTO FINAL. Não é possível uma equipe decidir ser ágil, sem contar com a boa vontade da empresa, mesmo que a empresa ganhe com essa mudança cultura.&lt;/p&gt;

&lt;p&gt;O Manifesto Ágil na verdade propõe uma inversão de valores corporativos. Ao invês de seguir os processos da empresa, cada equipe vai decidir o que fazer com a intenção de entregar mais valor mais rapidamente. Isso é uma resposta ao engessado PMBOK. Quando se assina um contrato para um projeto, todos os requisitos propostos DEVEM ser entregues. Isso pode implicar muitas horas extras caso haja algum imprevisto. Ou pode levar a não aceitação do produto pelo cliente, muitas vezes o cliente percebe que o que foi pedido não é o que se realmente deseja. Isso é comum, sem estresses. &lt;/p&gt;

&lt;p&gt;Então para se colocar em prática um framework Ágil, deve-se primeiro mudar a forma de se assinar os contratos. Não se pode vender um produto com homens/hora, escopo fechado. Tem que se vender um projeto com iterações e escopo aberto. Vamos começar a desenvolver o projeto X que inicialmente está previsto para 5 Sprints. Todos os documentos assinado entre Empresa e Cliente deve ser completamente diferentes.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Indivíduos e interações&lt;/strong&gt; mais que processos e ferramentas
&lt;/h2&gt;

&lt;p&gt;Em um ambiente Ágil, a equipe terá mais autonomia que em outros contextos. Os membros dessa equipe decidirão se vão executar o framework proposto (&lt;em&gt;viu que não falei processo?&lt;/em&gt;) ou se vão adaptar. O próprio Framework Scrum não se denomina processo por esse motivo, caso a equipe decida que alguma prática deve ser alterada, sem estresse! &lt;/p&gt;

&lt;p&gt;Muito das reuniões propostas pelo Scrum são denominadas rituais, porque eles devem ser executados como rotina, serem inseridos na cultura. Eles tem valores inseridos nele. Por exemplo, a Retrospectiva deve ser para reavaliar se o próximo Sprint deve ter melhorias. Lembra do processo de melhoria continua do LEAN?&lt;/p&gt;

&lt;p&gt;Obviamente que a equipe deverá seguir alguns padrões da empresa. Não dá pra simplesmente jogar fora a ferramenta de Solicitação de Mudança da empresa e usar uma nova. Mas a maneira de se usar deve ser menos impositiva.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Software em funcionamento&lt;/strong&gt; mais que documentação abrangente
&lt;/h2&gt;

&lt;p&gt;Em projetos PMBOK havia muito tempo gasto em escrita de documentação. Havia o documento de Requisitos, Arquitetura e Testes. Cada um era escrito e validado antes do desenvolvimento e deviam ser validados de acordo com a entrega. &lt;/p&gt;

&lt;p&gt;Em um contexto Ágil, o Software em funcionamento tem mais valor. No SCRUM, uma reunião de Review vale mais do que um documento de Requisito. E provavelmente é mais barato fazer um reunião de Review a cada 2 semanas do que escrever um documento de requisitos gigantesco a cada 3 meses.&lt;/p&gt;

&lt;p&gt;Que fique claro uma coisa, o software deve ser documentado, o que pode não ser documentado é os contratos de requisitos com o cliente. Caso seu projeto não use uma Wiki interna (ou coloca no repositório de código mesmo) para documentar arquitetura, vamos começar agora! Abre um README.md e coloca todos os pressupostos arquiteturais agora!&lt;/p&gt;

&lt;p&gt;O mais claro desse ponto é dizer: mais vale um teste automático do que um documento de testes em &lt;code&gt;.docx&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Colaboração com o cliente&lt;/strong&gt; mais que negociação de contratos
&lt;/h2&gt;

&lt;p&gt;O Cliente deve ser envolvido em todo o processo de desenvolvimento. Se não puder participar das reuniões diárias (&lt;em&gt;nem é bom participar...&lt;/em&gt; 😳), deve participar das reuniões de Review! Cada requisito tem que ser validado com o cliente, mostrado e discutido. A decisão é dele e as vezes a opinião dele muda muito rapidamente.&lt;/p&gt;

&lt;p&gt;O que acontecia com o PMBOK é que todo o projeto estava detalhado na documentação e deveria ser entregue conforme a documentação. Era esse o contrato. A comunicação com o cliente se dava somente para informar se o projeto está em dia ou atrasado, e muitas vezes as horas extras eram escondidas do cliente. &lt;em&gt;Vamos fazer uma banco de horas que próximo mês nós tiramos&lt;/em&gt;. Em meu primeiro projeto acumulei 72hs em apenas 2 meses e acabei tirando todas essas horas nos 2 meses seguintes.&lt;/p&gt;

&lt;p&gt;No contexto Ágil, o projeto não deve ser encarado como algo fechado que é contratado e deve ser entregue. Isso pode ser válido para construção de um prédio, mas para construção de software não é possível. Há muito mais volatilidade dos requisitos. O cliente deve ser envolvido em todo o processo.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Responder a mudanças&lt;/strong&gt; mais que seguir um plano
&lt;/h2&gt;

&lt;p&gt;Mudanças vão ocorrer! Toda a disciplina de Engenharia de Software já leva em conta que o Cliente não sabe o que quer, ou se sabe, pode ser que sua necessidade mude. &lt;/p&gt;

&lt;p&gt;É comum ver desenvolvedores reclamando que o cliente nunca sabe o que querem. É por isso que são chamado de &lt;strong&gt;desenvolvedores&lt;/strong&gt; e não &lt;strong&gt;engenheiros&lt;/strong&gt; de software! 😏&lt;/p&gt;

&lt;p&gt;Por isso que uma equipe ágil deve ter um &lt;em&gt;backlog&lt;/em&gt; e deve gerenciar esse &lt;em&gt;backlog&lt;/em&gt; muito bem! Ele deve ser repriorizado a cada iteração. Lembre-se o foco deve ser entregar valor ao cliente!&lt;/p&gt;

&lt;p&gt;Mas muito cuidado! Deve ser feito um Gerenciamento de Débito Técnico! Não é possível construir um software respondendo a mudanças rapidamente, mas deixando muita sujeira pra trás... O nome disso não é Ágil! É &lt;a href="https://gohorseprocess.com.br/extreme-go-horse-xgh/" rel="noopener noreferrer"&gt;eXtreme Go Horse (XGH)&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%2Fi%2Fl9r1nuqctxpvgw9jf7l6.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%2Fi%2Fl9r1nuqctxpvgw9jf7l6.png" alt="Logo do eXtreme Go Horse" width="205" height="232"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusão
&lt;/h1&gt;

&lt;p&gt;Acabei de apresentar quais são os principios do Ágil. Agora cabe a você usar bem esses conceitos. Os Frameworks Ágeis são baseados em Times autogerenciaveis, isso é uma das bases. &lt;/p&gt;

&lt;p&gt;Eu nunca tive contato com um agilista, mas caso você tenha veja se ele está aplicando esses conceitos. Caso não esteja, é hora de ter uma conversa séria com o gerente! É muito complicado se criar uma função para garantir o ágil... Parece contraditório.&lt;/p&gt;

&lt;p&gt;Há outros temas que o Ágil habilitou, porém são temas completamente diferentes. Você viu que todas as citações usadas foram de um livro de DevOps? Pois é, o Ágil possibilitou o DevOps. E este é nada mais nada menos do que a aplicação de conceitos ágil no suporte. Outro tema foi Microsserviços... Mas é muito tema para pouca letra...&lt;/p&gt;

&lt;p&gt;Desejo que você aplique esse conhecimento no seu projeto e que ele seja um sucesso! 😉&lt;/p&gt;

&lt;h1&gt;
  
  
  Leituras Recomendadas
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://amzn.to/33tCZ0p" rel="noopener noreferrer"&gt;O Projeto Fênix: um Romance Sobre TI, DevOps e Sobre Ajudar o seu Negócio a Vencer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amzn.to/2GnW7nF" rel="noopener noreferrer"&gt;Microsserviços Prontos Para a Produção: Construindo Sistemas Padronizados em uma Organização de Engenharia de Software&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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%2Fi%2F9fwzsz0n0f3aq9h4xzzs.jpg" 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%2Fi%2F9fwzsz0n0f3aq9h4xzzs.jpg" alt="Trem em alta velocidade" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Foto de &lt;a href="https://www.pexels.com/pt-br/foto/agil-alta-velocidade-assento-banco-1285618/" rel="noopener noreferrer"&gt;&lt;strong&gt;Essow Kedelina&lt;/strong&gt;&lt;/a&gt; no &lt;strong&gt;Pexels&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>agil</category>
      <category>projetos</category>
      <category>scrum</category>
      <category>metodologia</category>
    </item>
    <item>
      <title>Soft-Skill 101 - Mentoria. Porque e como?</title>
      <dc:creator>Victor Osório</dc:creator>
      <pubDate>Mon, 28 Sep 2020 12:14:48 +0000</pubDate>
      <link>https://dev.to/vepo/soft-skill-101-mentoria-porque-e-como-3lcd</link>
      <guid>https://dev.to/vepo/soft-skill-101-mentoria-porque-e-como-3lcd</guid>
      <description>&lt;h1&gt;
  
  
  Porque?
&lt;/h1&gt;

&lt;p&gt;Porque eu mentoro gratuitamente é a primeira pergunta que respondo quando me procuram. A resposta é simples: eu sei o que a falta de mentoria pode fazer com a carreira de uma pessoa. Passei meus 10 primeiros anos sem a ajuda de ninguém e evolui muito pouco. Não sabia como estudar, não conhecia o mercado, não sabia o que era uma postura profissional, não conhecia os frameworks, etc... As empresas que eu trabalhavam gostavam do perfil do herói. O cara que chega lá e mata o leão. E eu era esse perfil, mas sempre reinventando a roda.&lt;/p&gt;

&lt;p&gt;Só temos que contextualizar isso no tempo. Nessa época tinha pouco conteúdo online. E eu não sabia o que procurar. Muitas vezes ia procurar na academia, em artigos.&lt;/p&gt;

&lt;h1&gt;
  
  
  Como?
&lt;/h1&gt;

&lt;p&gt;A segunda pergunta é o como eu mentoro. &lt;/p&gt;

&lt;p&gt;Deixo minha agenda aberta, qualquer um com acesso ao meu LinkedIn pode me encontrar ou encontrar nos sites de mentoria gratuita e marcar 30 minutos.&lt;/p&gt;

&lt;p&gt;Marcada a reunião, eu dou uma olhada nas redes sociais da pessoa. O que ela anda postando? Como ela se descreve? O que ela anda curtindo?&lt;/p&gt;

&lt;p&gt;Dentro desses 30 minutos vou fazer pedir para a pessoa descrever a sua história. Porque me procurou? Quais são suas queixas? O que você está fazendo hoje?&lt;/p&gt;

&lt;p&gt;Normalmente a pessoa vai gastar 10 minutos contando essa história. Nesse tempo é fácil levantar algumas deficiências. Seja um conceito errado, seja uma incompatibilidade com suas redes sociais.&lt;/p&gt;

&lt;p&gt;Depois eu explico os conceitos que eu identifiquei como errados. Exemplifico os comportamentos que não são desejáveis. E aponto algumas melhorias nas redes sociais. O exemplo mais claro:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;— &lt;em&gt;Estamos desenvolvendo uma API REST...&lt;/em&gt;&lt;br&gt;
— &lt;em&gt;Como você me descreve uma API REST?&lt;/em&gt;&lt;br&gt;
— &lt;em&gt;Ah, uma API que usa JSON!&lt;/em&gt; &lt;br&gt;
Lá vou eu explicar que usar JSON não faz com que uma API seja RESTful.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Depois eu proponho um &lt;strong&gt;RoadMap&lt;/strong&gt;. Vamos iniciar um plano de estudos. Eu vou dar um tema, vou dar uns posts de blog e vou pedir que a pessoa estude. Se possível ela deve: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Produzir um post de blog&lt;/li&gt;
&lt;li&gt;Fazer um exemplo do que foi estudado&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Áreas Avaliadas
&lt;/h1&gt;

&lt;p&gt;Eu creio que mentoria é uma pratica muito importante. Eu nunca recebi um processo de mentoria formal, apenas algumas avaliações que me foram muito proveitosas.&lt;/p&gt;

&lt;p&gt;Para desenvolver meu processo de mentoria, acabei levantando algumas possíveis áreas e o que desejo produzir de resultados nas pessoas que me procuram.&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%2Fi%2Fh31sab0mdmea64g67s3i.jpg" 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%2Fi%2Fh31sab0mdmea64g67s3i.jpg" alt="Alt Text" width="800" height="599"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Qualidade de Código
&lt;/h2&gt;

&lt;p&gt;Um desenvolvedor deve produzir um código com qualidade. O que isso significa? Este código deve ser:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Estável&lt;/li&gt;
&lt;li&gt;De fácil compreensão&lt;/li&gt;
&lt;li&gt;De fácil manutenção&lt;/li&gt;
&lt;li&gt;Otimizado&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Linguagem de Programação
&lt;/h2&gt;

&lt;p&gt;Um desenvolvedor deve conhecer a fundo a sua linguagem de programação principal. Deve conhecer as APIs, como a sua linguagem está evoluindo, os seus pontos fortes e os seus pontos fracos.&lt;/p&gt;

&lt;p&gt;Este deve saber ao iniciar um projeto qual linguagem usar. Se a sua não for a mais recomendada, deve saber o porque e qual ele pode usar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arquitetura de Software
&lt;/h2&gt;

&lt;p&gt;Um desenvolvedor não precisa ser apenas um desenvolvedor. Ele pode atuar como arquiteto, compreendendo o que o arquiteto está falando e dialogar com o arquiteto. &lt;/p&gt;

&lt;p&gt;Por isso proponho que o desenvolvedor conheça os principais conceitos arquiteturais. Quais são os padrões arquiteturais existentes. Deve saber documentar a sua solução. &lt;/p&gt;

&lt;p&gt;Ele deve saber o que aplicar quando um problema surgir. E como raciocinar em cima do problema.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conceitos Teóricos
&lt;/h2&gt;

&lt;p&gt;O que você aprendeu na faculdade não fica na faculdade. É importante usar ele no seu trabalho.&lt;/p&gt;

&lt;p&gt;Cada mentorado deve ter os conceitos corretos e saber usar. E mesmo que seja alguém em migração de carreira, deve aprender alguns conceitos de Computação para desempenhar um bom trabalho.&lt;/p&gt;

&lt;h2&gt;
  
  
  Negócios
&lt;/h2&gt;

&lt;p&gt;Ninguém cresce em uma empresa se não conhecer a fundo o modelo de negócios dela. &lt;/p&gt;

&lt;p&gt;Desejo que meus mentorados saibam como suas empresas funcionem e que eles contribuam para o crescimento delas. &lt;/p&gt;

&lt;p&gt;Eles devem conhecer: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quem são seus superiores?&lt;/li&gt;
&lt;li&gt;Como a empresa se mantém?&lt;/li&gt;
&lt;li&gt;O que a empresa deseja deles?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Comportamento
&lt;/h2&gt;

&lt;p&gt;O comportamental é essencial. Ninguém cresce se seu comportamento não mudar. Todos iniciam como júnior. Depois vão ganhando independência e param de depender dos Seniores, nesse momento se tornam plenos. Depois passam a apoiar outros durante a realização das atividades, e nesse ponto se tornam Seniores.&lt;/p&gt;

&lt;p&gt;Eles devem saber ouvir e perguntar. Como se comportar e o que falar. As vezes um comentário indesejado pode ser fatal para sua carreira.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusão
&lt;/h1&gt;

&lt;p&gt;Eu sempre digo uma fase que reflete a minha própria experiência. &lt;em&gt;O problema quando você não sabe é que você não sabe o que não sabe.&lt;/em&gt; Eu passei muitos anos achando que sabia muito, isso porque tinha me treinado ao máximo naquilo que já sabia, mas como não tinha contato com pessoas mais experientes, estava travado.&lt;/p&gt;

&lt;p&gt;Só consegui crescer quando mudei de empresas e tive contatos com outras realidades. Isso foi muito enriquecedor!&lt;/p&gt;

&lt;p&gt;Se você deseja mentoria, procure alguém que você admira e mande uma mensagem. Não é preciso muito tempo para o mentor, apenas 30 minutos a cada duas semanas.&lt;/p&gt;

&lt;p&gt;Se você deseja mentorar e quer conversar, pode me procurar. Sempre respondo no Twitter e LinkedIn.&lt;/p&gt;

&lt;h1&gt;
  
  
  Atividades em paralelo
&lt;/h1&gt;

&lt;p&gt;Paralelo à mentoria, é urgente produzir material em português. Nós estamos passando por um período de grande crescimento da necessidade de desenvolvedores. Você pode reparar, 10 anos atrás só tinha formados trabalhando em nossa área, agora temo pessoas sem nenhum conhecimento teórico, apenas o conhecimento prático aprendido em Bootcamps que não devem se aprofundar muito. &lt;/p&gt;

&lt;p&gt;Tenho feito bastante isso, escrito coisas básicas. O que é básico para um pode ser muito relevante para outros.&lt;/p&gt;

&lt;h1&gt;
  
  
  Próximos Passos
&lt;/h1&gt;

&lt;p&gt;Agora que eu estabeleci uma rede com algumas pessoas sendo mentoradas, devo me aprofundar no tema. Ler alguns artigos sobre o próprio processo de mentoria e sua aplicação no mundo de desenvolvimento de software.&lt;/p&gt;

&lt;p&gt;Para isso escolhi dois artigos iniciais usando o Google Scholar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;KE Kram (2007) - &lt;a href="https://www.bu.edu/sph/files/2012/01/Ragins-Kram_The-landscape-of-mentoring-in-the-21st-century.pdf" rel="noopener noreferrer"&gt;The Landscape of Mentoring in the 21st Century&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;C Casado-Lumbreras (2011) - &lt;a href="https://e-archivo.uc3m.es/bitstream/handle/10016/14307/culture_SRE_2011.pdf?sequence=1&amp;amp;isAllowed=y" rel="noopener noreferrer"&gt;Culture dimensions in software development industry: The effects ofmentoring&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Espero ler eles em breve...&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%2Fi%2Flifgkggmy9gglx235vdr.jpg" 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%2Fi%2Flifgkggmy9gglx235vdr.jpg" alt="Alt Text" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Foto de &lt;strong&gt;nappy&lt;/strong&gt; no &lt;strong&gt;Pexels&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>softskill</category>
      <category>mentoria</category>
      <category>carreira</category>
    </item>
    <item>
      <title>Testes 101 - Testando aplicações Java</title>
      <dc:creator>Victor Osório</dc:creator>
      <pubDate>Wed, 02 Sep 2020 00:16:37 +0000</pubDate>
      <link>https://dev.to/vepo/testes-101-testando-aplicacoes-java-1m8i</link>
      <guid>https://dev.to/vepo/testes-101-testando-aplicacoes-java-1m8i</guid>
      <description>&lt;p&gt;Testes são fundamentais. Se você deseja ser desenvolvedor Java lhe recomendo pelo menos conhecer o que são TDD, Maven e JUnit. E vou te apresentar o porque.&lt;/p&gt;

&lt;h1&gt;
  
  
  TDD
&lt;/h1&gt;

&lt;p&gt;TDD significa Test-Driven-Development. Se você imagina que é criar o testes e depois o código, você está um pouco enganado. TDD é uma disciplina um pouco diferente.&lt;/p&gt;

&lt;p&gt;TDD é uma disciplina, não é algo que pode ser explicado. É uma cultura que você tem que aprender, e treinar. Depois de anos você vai ver já melhorou bastante, mas tem muito mais a aprender.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ciclos do TDD
&lt;/h2&gt;

&lt;p&gt;Pra explicar o TDD facilmente, temos que falar dos ciclos. Nem todos os testes criados serão usados e eles não devem refletir o requisito final. Você tem que usar &lt;strong&gt;Baby Steps&lt;/strong&gt;, passos de bebê, em cara ciclo. Imagine um ciclo como um rodada de desenvolvimento de 10 a 30 minutos: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;[R]&lt;/strong&gt; Você cria um Test, ele deve falhar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;[G]&lt;/strong&gt; Você implementa o código para o teste funcionar&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;[R]&lt;/strong&gt; Você Refatora o código&lt;/li&gt;
&lt;/ul&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%2Fi%2Fpfjgroqac0hnojyt7vmj.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%2Fi%2Fpfjgroqac0hnojyt7vmj.png" alt="Ciclo RGR" width="300" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao final de um tempo de desenvolvimento você terá vários testes. Alguns podem ser descartados, outros vão ficar. Eu recomendo ficar apenas os que representem a funcionalidades do código. E recomendo também que cubram o máximo possível o seu código.&lt;/p&gt;

&lt;h1&gt;
  
  
  Maven
&lt;/h1&gt;

&lt;p&gt;Se estamos falando de testes, estamos falando de Processo de Build. Se você cria os seus testes e não os colocar para serem executados automaticamente, você não fez praticamente nada. &lt;/p&gt;

&lt;p&gt;O Maven abstrai cada build criando um ciclo com fases. Então os testes sempre serão executados se você deseja executar ou empacotar o seu projeto.&lt;/p&gt;

&lt;p&gt;Para criar um projeto usando Maven, instale o Maven 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;mvn archetype:generate &lt;span class="nt"&gt;-DgroupId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;io.vepo.tests &lt;span class="nt"&gt;-DartifactId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;testsExample &lt;span class="nt"&gt;-DarchetypeArtifactId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;maven-archetype-quickstart &lt;span class="nt"&gt;-DinteractiveMode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você vai observar duas coisas: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;o Maven criou um arquivo pom.xml colocando como dependência o JUnit, e que versão antiga! 🙄&lt;/li&gt;
&lt;li&gt;o Maven criou duas pastas de código: &lt;code&gt;src/main/java&lt;/code&gt; e &lt;code&gt;src/test/java&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;project&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0"&lt;/span&gt; &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;
  &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;modelVersion&amp;gt;&lt;/span&gt;4.0.0&lt;span class="nt"&gt;&amp;lt;/modelVersion&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.vepo.tests&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;testsExample&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;packaging&amp;gt;&lt;/span&gt;jar&lt;span class="nt"&gt;&amp;lt;/packaging&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0-SNAPSHOT&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;testsExample&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;http://maven.apache.org&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;junit&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;junit&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.8.1&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;
&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%2Fi%2Fg21r9j3qm38eh6eh95cd.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%2Fi%2Fg21r9j3qm38eh6eh95cd.png" alt="Estrutura de diretório" width="366" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mas onde o Maven configura que os testes devem ser executados durante a build ou como ele descobre os testes? O Maven se baseia na ideia convention-over-configuration, ou seja, Convenção acima de Configuração. Para realizar certas configurações basta apenas usar a convenção apropriada. &lt;/p&gt;

&lt;p&gt;O projeto criado já vem com alguns testes JUnit configurado, porém é usado a versão &lt;code&gt;3.8.1&lt;/code&gt;... Alguém por favor atualiza o &lt;a href="https://github.com/apache/maven-archetypes" rel="noopener noreferrer"&gt;github.com/apache/maven-archetypes&lt;/a&gt;, por favor!&lt;/p&gt;

&lt;h1&gt;
  
  
  JUnit 5
&lt;/h1&gt;

&lt;p&gt;O JUnit é o framework que irá gerenciar o ciclo de vida de seus testes. Cara classe dentro de &lt;code&gt;src/test/java&lt;/code&gt; contendo um método com a annotation &lt;a href="https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/Test.html" rel="noopener noreferrer"&gt;&lt;code&gt;org.junit.jupiter.api.Test&lt;/code&gt;&lt;/a&gt; será executado como testes. Assim para migrarmos o arquivo gerado automaticamente, basta mudar o seguinte conteúdo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;project&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0"&lt;/span&gt; &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;
  &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;modelVersion&amp;gt;&lt;/span&gt;4.0.0&lt;span class="nt"&gt;&amp;lt;/modelVersion&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.vepo.tests&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;testsExample&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;packaging&amp;gt;&lt;/span&gt;jar&lt;span class="nt"&gt;&amp;lt;/packaging&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0-SNAPSHOT&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;testsExample&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;http://maven.apache.org&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.junit.jupiter&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;junit-jupiter-engine&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;5.5.2&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- Need at least 2.22.0 to support JUnit 5 --&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-surefire-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.0.0-M3&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-compiler-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.8.1&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;source&amp;gt;&lt;/span&gt;1.8&lt;span class="nt"&gt;&amp;lt;/source&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;target&amp;gt;&lt;/span&gt;1.8&lt;span class="nt"&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/project&amp;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="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;io.vepo.tests&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;static&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;junit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jupiter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Assertions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;assertEquals&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;org.junit.jupiter.api.DisplayName&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;org.junit.jupiter.api.Test&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;AppTest&lt;/span&gt; 
&lt;span class="o"&gt;{&lt;/span&gt;   
    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="nd"&gt;@DisplayName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Test if it works"&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;simpleTest&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OK"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"OK"&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;Observe que com o JUnit 5 eu consigo dar nomes aos testes, isso facilita em muito a identificação de um erro. Eu costumo usar frases que definem as features testadas. Isso facilita quando preciso fazer manutenção em código escrito meses, ou anos, antes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ciclo de Vida
&lt;/h2&gt;

&lt;p&gt;O ciclo de vida de um teste passa pela execução métodos antes/depois da classe ser criada e métodos antes/depois da execução de cada teste. Dê uma olhada na &lt;a href="https://junit.org/junit5/docs/current/user-guide/#writing-tests-classes-and-methods" rel="noopener noreferrer"&gt;documentação&lt;/a&gt;. Há vários exemplos de como usar &lt;a href="https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/BeforeAll.html" rel="noopener noreferrer"&gt;@BeforeAll&lt;/a&gt;, &lt;a href="https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/BeforeEach.html" rel="noopener noreferrer"&gt;@BeforeEach&lt;/a&gt;, &lt;a href="https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/AfterEach.html" rel="noopener noreferrer"&gt;@AfterEach&lt;/a&gt; e &lt;a href="https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/BeforeAll.html" rel="noopener noreferrer"&gt;@AfterAll&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Se eu for detalhar cada feature do JUnit 5, esse post não terá fim. São muitas, conheça elas, assim você pode construir bons testes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Asserções
&lt;/h2&gt;

&lt;p&gt;O mais importante do JUnit não é apenas a execução dos testes, mas a validação dos resultados.&lt;/p&gt;

&lt;p&gt;O JUnit provê uma classe com métodos estáticos para realizar isso. Na &lt;a href="https://junit.org/junit5/docs/current/user-guide/#writing-tests-assertions" rel="noopener noreferrer"&gt;documentação oficial&lt;/a&gt; há vários exemplos.&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="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;standardAssertions&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;multiply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
            &lt;span class="s"&gt;"The optional failure message is now the last parameter"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;assertTrue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'a'&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="sc"&gt;'b'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"Assertion messages can be lazily evaluated -- "&lt;/span&gt;
            &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"to avoid constructing complex messages unnecessarily."&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;h1&gt;
  
  
  Tests DSL
&lt;/h1&gt;

&lt;p&gt;DSL significa &lt;em&gt;Domain-Specific Language&lt;/em&gt;. Você cria uma DSL seu código pode ser lido como uma linguagem. Em testes é comum se construir uma DSL usando os termos &lt;a href="https://www.agilealliance.org/glossary/gwt" rel="noopener noreferrer"&gt;Given-When-Then&lt;/a&gt;. Você pode fazer isso em português Dado-Quando-Então:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(&lt;strong&gt;Dado&lt;/strong&gt;) Qual o contexto que o teste é executado?&lt;/li&gt;
&lt;li&gt;(&lt;strong&gt;Quando&lt;/strong&gt;) Qual ação vai ser testada?&lt;/li&gt;
&lt;li&gt;(&lt;strong&gt;Então&lt;/strong&gt;) O que deve ser validado?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Um bom exemplo pode ser:&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="n"&gt;dadoNovoUsuário&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executaChecking&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;validaReserva&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aí fica de você implementar cada método e reutilizar ele quando possível.&lt;/p&gt;

&lt;h2&gt;
  
  
  AssertJ
&lt;/h2&gt;

&lt;p&gt;Há algumas bibliotecas que auxiliam na construção dessa DSL. Eu gosto muito da &lt;a href="https://assertj.github.io/doc/" rel="noopener noreferrer"&gt;AssertJ&lt;/a&gt;. Com ela é possível usar uma DSL para validação de resultados complexos.&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;// extracting multiple values at once grouped in tuples&lt;/span&gt;
&lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fellowshipOfTheRing&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;extracting&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"age"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"race.name"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                               &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tuple&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Boromir"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Man"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
                                         &lt;span class="n"&gt;tuple&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sam"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;38&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Hobbit"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
                                         &lt;span class="n"&gt;tuple&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Legolas"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Elf"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Mocks
&lt;/h1&gt;

&lt;p&gt;Mock significa Imitação. Imagina no caso de estarmos acessando uma base de dados. Você tem duas opções, ou liga a base de dados e testa diretamente nela, ou você mocka o acesso a base. O problema da primeira abordagem é que ela torna o teste mais abrangente. Não estaremos fazendo um Teste Unitário, mas um Teste de Integração.&lt;/p&gt;

&lt;p&gt;Não há problema em fazer Testes de Integração, mas eles serão muito mais lentos. Outro problema é que muitas vezes você não precisa testar uma base de dados. Mas as vezes é bom testar a integração, sempre evita um NullPointerException! ☠️&lt;/p&gt;

&lt;p&gt;Há algumas boas bibliotecas para Mock, vou falar um pouco do &lt;a href="https://site.mockito.org/" rel="noopener noreferrer"&gt;Mockito&lt;/a&gt; e &lt;a href="https://github.com/powermock/powermock" rel="noopener noreferrer"&gt;PowerMock&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Mockito
&lt;/h1&gt;

&lt;p&gt;Mockito serve para criar classes onde o código original pode ou não ser executado. &lt;/p&gt;

&lt;p&gt;Quando você quer executar o código original, estamos falando de um spy. O código é executado e você pode validar o que foi feito.&lt;/p&gt;

&lt;p&gt;Um Spy pode ser criado usando &lt;a href="https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#spy" rel="noopener noreferrer"&gt;&lt;code&gt;Mockito.spy&lt;/code&gt;&lt;/a&gt; ou usando o Jupiter Extension para o JUnit 5.&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="nd"&gt;@Test&lt;/span&gt;
&lt;span class="nd"&gt;@DisplayName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Testa o exemplo de Mock para UserRepository"&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;addUserInMemoryTest&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;userWithoutId&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;User&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;userWithoutId&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setEmail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"vepo@vepo.com"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;userWithoutId&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setUsername&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"vepo"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userRepositoryInMemory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userWithoutId&lt;/span&gt;&lt;span class="o"&gt;)).&lt;/span&gt;&lt;span class="na"&gt;hasFieldOrPropertyWithValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1L&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;verify&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userRepositoryInMemory&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userWithoutId&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;Observe que um Spy serve para verificar se o método foi chamado com um valor especifico. Ou seja, precisamos ter uma implementação concreta da classe.&lt;/p&gt;

&lt;p&gt;Agora quando falamos de Mocks não precisamos de implementações concretas. Podemos usar em interfaces. Quando é criado um mock, o código real não é chamado, são sempre retornados valores vazios ou nulls. Então é preciso definir o que será retornado e quando.&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="nd"&gt;@Test&lt;/span&gt;
&lt;span class="nd"&gt;@DisplayName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Testa o exemplo de Mock para UserRepository"&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;addUserTest&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;userWithoutId&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;User&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;userWithoutId&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setEmail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"vepo@vepo.com"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;userWithoutId&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setUsername&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"vepo"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;userWithId&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;User&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;userWithId&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1L&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;userWithId&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setEmail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"vepo@vepo.com"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;userWithId&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setUsername&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"vepo"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;when&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userWithoutId&lt;/span&gt;&lt;span class="o"&gt;)).&lt;/span&gt;&lt;span class="na"&gt;thenReturn&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userWithId&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userWithoutId&lt;/span&gt;&lt;span class="o"&gt;)).&lt;/span&gt;&lt;span class="na"&gt;hasFieldOrPropertyWithValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1L&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;h1&gt;
  
  
  Cobertura de Testes
&lt;/h1&gt;

&lt;p&gt;As coisas não andam se não tivermos estatísticas! Então para testes, precisamos saber com exatidão qual é a cobertura de testes do nosso projeto. Se não colocarmos isso em prática, muito rapidamente a cobertura irá cair e nem perceberemos.&lt;/p&gt;

&lt;p&gt;Uma ferramenta para gerar um relatório de cobertura é o &lt;a href="https://www.jacoco.org/jacoco/" rel="noopener noreferrer"&gt;JaCoCo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para configurar o JaCoCo no Maven, basta adicionar ele como um plugin e configurar quando será executado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.jacoco&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;jacoco-maven-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;0.8.1&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;prepare-agent&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;prepare-agent&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;report&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;phase&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/phase&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;report&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois para executar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn clean &lt;span class="nb"&gt;test &lt;/span&gt;jacoco:report
&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%2Fi%2Ftlsl5nnyppc2ikfbzr6v.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%2Fi%2Ftlsl5nnyppc2ikfbzr6v.png" alt="Relatório de Tests" width="800" height="78"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No caso será gerado um relatório. Esse relatório pode ser armazenado no Jenkins ou mesmo usado pela próxima ferramenta que vamos ver.&lt;/p&gt;

&lt;h1&gt;
  
  
  Code Smells
&lt;/h1&gt;

&lt;p&gt;Antes de partir para última ferramenta, vamos definir uma coisa.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Smells&lt;/strong&gt; são construções que podem trazer má qualidade ao código. Eliminando eles, você pode melhorar a qualidade do seu código.&lt;/p&gt;

&lt;h1&gt;
  
  
  Análise Estática de Código
&lt;/h1&gt;

&lt;p&gt;Como última ferramenta, vamos falar de Análise Estática de Código. Imagina se você pudesse analisar o seu código e encontrar bugs ou Code Smells. Seria bom, não?&lt;/p&gt;

&lt;p&gt;Mas temos isso e de graça. Você pode usar o &lt;a href="https://www.sonarqube.org/" rel="noopener noreferrer"&gt;SonarQube&lt;/a&gt;. Com esse plugin para o Maven você pode criar um servidor para armazenar a qualidade atual do seu código e construir uma timeline dele. Assim você pode desafiar o time a reduzir o número de Code Smells em 50%. Ou em aumentar a covertura de testes até um determinado patamar.&lt;/p&gt;

&lt;p&gt;Para integrar no Maven, basta colocar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.sonarsource.scanner.maven&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;sonar-maven-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.7.0.1746&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;phase&amp;gt;&lt;/span&gt;verify&lt;span class="nt"&gt;&amp;lt;/phase&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;sonar&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao adicionar o plugin, crie o projeto no Github e já inicialize ele no &lt;a href="https://sonarcloud.io" rel="noopener noreferrer"&gt;SonarCloud&lt;/a&gt;. Ao iniciar um projeto, você pode pegar um Token que deve ser usado na build.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn &lt;span class="nt"&gt;-Dsonar&lt;/span&gt;.login&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;SONAR_TOKEN&amp;gt; verify sonar:sonar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Caso queira rodar o &lt;a href="https://www.sonarqube.org/downloads/" rel="noopener noreferrer"&gt;Sonar&lt;/a&gt; em projetos internos da sua empresa, você só precisa de um servidor e uma instalação do Sonar. É simples de configurar.&lt;/p&gt;

&lt;h1&gt;
  
  
  Tudo Junto
&lt;/h1&gt;

&lt;p&gt;Agora vamos responder a última pergunta. Quem vai rodar tudo isso? Você pode configurar algumas ferramentas. Entre elas podemos citar:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Ferramenta&lt;/th&gt;
&lt;th&gt;Contexto&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Jenkins&lt;/td&gt;
&lt;td&gt;Para rodar projetos internos. Não é um serviço cloud.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Github Actions&lt;/td&gt;
&lt;td&gt;Excelentes para projetos Github.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TravisCI&lt;/td&gt;
&lt;td&gt;Could e facilmente integrado com o Github.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  Conclusão
&lt;/h1&gt;

&lt;p&gt;Testes são fundamentais e você não precisa saber fazer antes de começar a desenvolver. MAS... Se você souber criar testes, seu código terá muita estabilidade. &lt;/p&gt;

&lt;p&gt;Treine fazer testes. Treine TDD. Conheça as ferramentas e boa sorte!&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%2Fi%2F36whvqvlgpj79iy7lzmc.jpg" 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%2Fi%2F36whvqvlgpj79iy7lzmc.jpg" alt="Alt Text" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>testes</category>
      <category>tdd</category>
      <category>jacoco</category>
    </item>
  </channel>
</rss>
