<?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: Meu Código Ágil</title>
    <description>The latest articles on DEV Community by Meu Código Ágil (@meucodigoagil).</description>
    <link>https://dev.to/meucodigoagil</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%2F258449%2Fd3103bcb-3ea9-4964-b611-0f67921e635e.png</url>
      <title>DEV Community: Meu Código Ágil</title>
      <link>https://dev.to/meucodigoagil</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/meucodigoagil"/>
    <language>en</language>
    <item>
      <title>JHipster 8 - Analisando o código da nossa primeira aplicação monolítica - Parte 3/3</title>
      <dc:creator>Meu Código Ágil</dc:creator>
      <pubDate>Wed, 22 May 2024 12:01:50 +0000</pubDate>
      <link>https://dev.to/meucodigoagil/jhipster-8-analisando-o-codigo-da-nossa-primeira-aplicacao-monolitica-parte-33-2ic6</link>
      <guid>https://dev.to/meucodigoagil/jhipster-8-analisando-o-codigo-da-nossa-primeira-aplicacao-monolitica-parte-33-2ic6</guid>
      <description>&lt;p&gt;Chegamos finalmente à parte final da análise do código da nossa aplicação, vamos encarar agora o código frontend gerado pelo JHipster que, como escolhido durante os prompts apresentados, está baseado no framework &lt;a href="https://angular.io/"&gt;Angular&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Vimos ao longo desta análise que o código do frontend está sob o diretório &lt;code&gt;src/main/webapp&lt;/code&gt;. Assim como no backend, o JHipster também gera um volume grande de código. Assim, vou manter o foco nos pontos mais importantes.&lt;/p&gt;

&lt;p&gt;Vale relembrar que os arquivos de configuração do nosso frontend, tais como &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;tsconfig.json&lt;/code&gt;, &lt;code&gt;angular.json&lt;/code&gt;, &lt;code&gt;jest.conf.js&lt;/code&gt;etc, são armazenados na raiz da nossa aplicação e já foram abordados no &lt;a href="https://dev.to/meucodigoagil/jhipster-8-analisando-o-codigo-da-nossa-primeira-aplicacao-monolitica-parte-13-2380"&gt;primeiro post&lt;/a&gt; desta série de análise de código.&lt;/p&gt;

&lt;h1&gt;
  
  
  webapp/i18n/
&lt;/h1&gt;

&lt;p&gt;Sob este diretório encontramos um subdiretório para cada um dos idiomas suportados pela nossa aplicação, os quais selecionamos durante os prompts apresentados pelo JHipster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;└── webapp
    ├── i18n
    │   ├── en
    │   └── pt-br
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dentro de cada um dos subdiretórios, encontramos 18 arquivos JSON contendo textos no respectivo idioma a serem exibidos nas diversas páginas da UI da aplicação de acordo com o idioma selecionado pelo usuário. Abaixo um exemplo do arquivo &lt;code&gt;pt-br/error.json&lt;/code&gt;:&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;"error"&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;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Página de erro!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"http"&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;"400"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Requisição inválida."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"403"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Você não tem autorização para acessar esta página."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"404"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A página não existe."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"405"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"O verbo HTTP utilizado não é suportado para essa URL."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"500"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Erro interno do servidor."&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;"concurrencyFailure"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Outro usuário modificou esses dados ao mesmo tempo que você. Suas modificações foram rejeitadas."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"validation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Erro de validação no servidor."&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;Portanto, quando precisar fazer um ajuste nos textos exibidos na interface com o usuário, você já sabe onde alterar.&lt;/p&gt;

&lt;h1&gt;
  
  
  webapp/content/
&lt;/h1&gt;

&lt;p&gt;Aqui o JHipster incluiu os &lt;em&gt;assets&lt;/em&gt; do frontend: arquivos de imagem e arquivos de estilo CSS ou SCSS. Quando for trocar a logo da aplicação, por exemplo, é aqui que você vai guardar o arquivo de imagem. Quando for mudar cores, tamanho, fontes etc ... vai ser aqui também.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;└── webapp&lt;br&gt;
    ├── content&lt;br&gt;
    │   ├── css&lt;br&gt;
    │   ├── images&lt;br&gt;
    │   └── scss&lt;/code&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  webapp/app/
&lt;/h1&gt;

&lt;p&gt;No subdiretório &lt;code&gt;app&lt;/code&gt; encontraremos a grande maioria dos arquivos fonte do frontend. Aqui está o código de todos os componentes da interface com o usuário, das telas compostas por esses componentes, rotas, serviços, interceptadores etc.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;☢️ EITA! PARA TUDO!!!⚠️&lt;/strong&gt;&lt;br&gt;
Caso você seja um  desenvolvedor backend raiz,  tenho  certeza  que quase infartou no último parágrafo. Na verdade, já está sentido calafrios desde que resolveu parar pra ler este post, correto? &lt;/p&gt;

&lt;p&gt;Já  que você me deu essa moral de chegar até aqui, eu escrevi um outro post &lt;em&gt;Off Topic&lt;/em&gt; com uma nano introdução sobre alguns conceitos básicos de Angular. &lt;/p&gt;

&lt;p&gt;Acredito que  vai ajudar pra que esse post não fique muito  abstrato e  uma leitura excessivamente chata pra você. Acessa aí, veja se ajuda, dê seu feedback e depois volte aqui pra continuar nossa análise:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/meucodigoagil/off-topic-nano-introducao-do-framework-angular-para-devs-do-back-3jhd"&gt;[Off Topic] Nano introdução do framework Angular para Devs do back&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mas se você já está familiarizado com o Angular e quiser dar umas dicas de como a gente pode deixar esse post mais didático ou mais preciso, dá um confere lá também e mande seus comentários ;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Começando pela raiz do subdiretório &lt;code&gt;app&lt;/code&gt;, alguns elementos aqui merecem atenção:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app-routes.ts&lt;/code&gt;: como o nome já sugere, aqui estão declaradas as rotas principais da nossa aplicação.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HomeComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;home.title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;LoginComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;login.title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;authorities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Authority&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ADMIN&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;canActivate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;UserRouteAccessService&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="nx"&gt;loadChildren&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./admin/admin.routes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;account&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;loadChildren&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./account/account.route&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;app.config.ts&lt;/code&gt;: entre outras coisas, neste arquivo está o provimento das rotas declaradas acima:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app.routes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;appConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ApplicationConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;provideRouter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;routerFeatures&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  webapp/app/account/
&lt;/h2&gt;

&lt;p&gt;Adentrando na estrutura em ordem alfabética, temos este diretório que reúne todos os componentes e serviços relacionados às contas de usuários da nossa aplicação. Como podemos observar, o JHipster ainda subdividiu os componentes e serviços em grupos relacionados ao registro, a ativação de usuário, reinicialização de senha etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── account
│   ├── activate
│   ├── password
│   │   └── password-strength-bar
│   ├── password-reset
│   │   ├── finish
│   │   └── init
│   ├── register
│   └── settings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  webapp/app/admin/
&lt;/h2&gt;

&lt;p&gt;Neste diretório, encontramos os componentes e serviços relacionados à administração da aplicação. Uma das principais e sempre é gerada pelo JHipster é a de administração de usuários da aplicação, &lt;code&gt;user-management&lt;/code&gt;. Através do serviço e do conjunto de componentes ali implementados, um administrador poderá visualizar os dados dos usuários registrados e dar manutenção. Um outro grupo de funcionalidades, relacionados a métricas, logs e informações sobre o estado da aplicação, só está disponível porque, durante os prompts do JHipster, nós optamos pela geração da UI de administração.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── admin
│   ├── configuration
│   ├── docs
│   ├── health
│   ├── logs
│   ├── metrics
│   └── user-management
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  webapp/app/config/
&lt;/h2&gt;

&lt;p&gt;Aqui fica uma série de configurações default da aplicação. Por exemplo:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;authority.constants.ts&lt;/code&gt;: declara um enumerador Typescript com as roles &lt;code&gt;ADMIN&lt;/code&gt; e &lt;code&gt;USER&lt;/code&gt; utilizadas ao longo da aplicação para condicionar seu funcionamento. Suponhamos que e a lógica da nossa aplicação demandasse um outro papel com acessos intermediários entre o &lt;code&gt;ADMIN&lt;/code&gt; e o &lt;code&gt;USER&lt;/code&gt;, poderíamos criar aqui um novo elemento &lt;code&gt;MANAGER&lt;/code&gt; no enumerador e referenciá-lo ao longo da aplicação onde fosse aplicável.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;font-awesome-icons.ts&lt;/code&gt;: temos o import de alguns ícones específicos da dependência &lt;code&gt;@fortaawesome/free-solid-svg-icons&lt;/code&gt; que são utilizados ao longo da nossa UI.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pagination.constants.ts&lt;/code&gt;: define, entre outros, o número de registros padrão em cada página para as entidades que possuem busca paginada. Caso queiramos modificar essa quantidade de registros para todas as entidades paginadas, simplesmente podemos editar aqui essa constante.&lt;/p&gt;

&lt;h2&gt;
  
  
  webapp/app/core/
&lt;/h2&gt;

&lt;p&gt;Aqui encontramos uma série de serviços e classes com funcionalidades auxiliares que serão utilizadas de forma transversal ao longo da aplicação segmentados em subdiretórios:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;auth&lt;/code&gt;: implementa serviços relacionados a autenticação com JWT, manutenção de estado na &lt;code&gt;sessionStorage&lt;/code&gt; e lógica de autorização baseda em papéis utilizada na declaração das rotas (CanActivate).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;config&lt;/code&gt;: possui um serviço de configuração da aplicação.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;interceptors&lt;/code&gt;: contém um conjunto de interceptadores de requisições HTTP utilizados, por exemplo, para adicionar o HTTP HEADER &lt;code&gt;Authorization&lt;/code&gt; com o token JWT às requisições aos endpoints do backend, identificar requisições com JWT expirado e redirecionar o usuário para a tela de login, tratar outros erros HTTP não relacionados a autenticação etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  webapp/app/entities/
&lt;/h2&gt;

&lt;p&gt;Neste diretório encontramos a lógica associada às entidades suportadas pela aplicação. Tanto as entidades relacionadas ao contexto de segurança, &lt;code&gt;user&lt;/code&gt; e &lt;code&gt;authority&lt;/code&gt; quanto as entidades do domínio da nossa aplicação que, até agora, temos tão somente a produto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── entities
│   ├── produto
│   │   ├── delete
│   │   ├── detail
│   │   ├── list
│   │   ├── route
│   │   ├── service
│   │   └── update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos ver já pela estrutura que a entidade tem suas funcionalidades segmentadas em subdiretórios:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;list&lt;/code&gt;: provê o componente que é a porta de entrada da entidade Produto, responsável por carregar os dados e apresentar em forma tabular.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt; @if (produtos &lt;span class="err"&gt;&amp;amp;&amp;amp;&lt;/span&gt; produtos.length &amp;gt; 0) {
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"table-responsive table-entities"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"entities"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;table&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"table table-striped"&lt;/span&gt; &lt;span class="na"&gt;aria-describedby=&lt;/span&gt;&lt;span class="s"&gt;"page-heading"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;thead&amp;gt;&lt;/span&gt;
        ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;details&lt;/code&gt;: implementa o componente que exibirá os dados detalhados de um produto.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;delete&lt;/code&gt;: dispõe do componente que solicita a confirmação do usuário quando solicitada a exclusão de um produto e, confirmando-se, faz chamada ao método &lt;code&gt;delete&lt;/code&gt; do &lt;code&gt;ProdutoService&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;update&lt;/code&gt;: provê o componente de formulário tanto para criação quanto para manutenção dos dados de um produto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"editForm"&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt; &lt;span class="na"&gt;novalidate&lt;/span&gt; &lt;span class="na"&gt;(ngSubmit)=&lt;/span&gt;&lt;span class="s"&gt;"save()"&lt;/span&gt; &lt;span class="na"&gt;[formGroup]=&lt;/span&gt;&lt;span class="s"&gt;"editForm"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt;
        &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"jhi-produto-heading"&lt;/span&gt;
        &lt;span class="na"&gt;data-cy=&lt;/span&gt;&lt;span class="s"&gt;"ProdutoCreateUpdateHeading"&lt;/span&gt;
        &lt;span class="na"&gt;jhiTranslate=&lt;/span&gt;&lt;span class="s"&gt;"minhaAplicacaoMonoliticaApp.produto.home.createOrEditLabel"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Criar ou editar Produto
      &lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
      ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;service&lt;/code&gt;: implementa o serviço da entidade produto &lt;code&gt;ProdutoService&lt;/code&gt; que provê as funcionalidades de interação com os endpoints do backend para realizar CRUD na entidade:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProdutoService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nx"&gt;applicationConfigService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ApplicationConfigService&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nx"&gt;resourceUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;applicationConfigService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getEndpointFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;api/produtos&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NewProduto&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;EntityResponseType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&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="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IProduto&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resourceUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;response&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IProduto&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;EntityResponseType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&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="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;put&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IProduto&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resourceUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getProdutoIdentifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;response&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;EntityResponseType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&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="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IProduto&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resourceUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;response&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HttpResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&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="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resourceUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;response&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vale chamar atenção também para o fato de que, na raiz do &lt;code&gt;webapp/app/entities/produto&lt;/code&gt;, encontraremos um arquivo de definição de rotas específico para a entidade Produto, &lt;code&gt;produto-routes.ts&lt;/code&gt;. É possível observar que a exibição de cada um dos componentes contidos nos subdiretórios que acabamos de analisar está atrelada ao path da URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;produtoRoute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ProdutoComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;defaultSort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;ASC&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;canActivate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;UserRouteAccessService&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;:id/view&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ProdutoDetailComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ProdutoResolve&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;canActivate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;UserRouteAccessService&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ProdutoUpdateComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ProdutoResolve&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;canActivate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;UserRouteAccessService&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;:id/edit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ProdutoUpdateComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ProdutoResolve&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;canActivate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;UserRouteAccessService&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  webapp/app/layouts/
&lt;/h2&gt;

&lt;p&gt;Neste diretório são implementados uma série de componentes relacionados ao layout visual da aplicação: rodapé, barra de navegação, componente de erro etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── layouts
│   ├── error
│   ├── footer
│   ├── main
│   ├── navbar
│   └── profiles
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  webapp/app/shared/
&lt;/h2&gt;

&lt;p&gt;Aqui temos componentes compartilhados entre as diversas telas, tais como: paginação, filtros, exibição de mensagem, formatação de data etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;└── shared
    ├── alert
    ├── auth
    ├── date
    ├── filter
    ├── language
    ├── pagination
    └── sort
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Ufa! Concluímos por aqui a série de análises do código da nossa aplicação monolítica gerado pelo JHipster. Neste último post da série, percorremos a estrutura de diretórios do frontend Angular. Detalhei um pouco aqueles pontos que me pareceram mais relevantes. Acredito que após esses três posts já temos uma boa noção do código que temos em mãos.&lt;/p&gt;

&lt;p&gt;Nossa próxima missão é evoluir essa aplicação de forma que possamos conhecer outras funcionalidades do JHipster e, assim, aprofundarmos nosso conhecimento sobre essa poderosa ferramenta que tem um potencial enorme de acelerar os projetos de desenvolvimento das nossas organizações.&lt;/p&gt;

&lt;p&gt;Fique à vontade para enviar suas dúvidas, comentários, sugestões e continue me acompanhando pois tem muito mais conteúdo vindo por aí! ;)&lt;/p&gt;

</description>
      <category>jhipster</category>
      <category>angular</category>
      <category>frontend</category>
      <category>agile</category>
    </item>
    <item>
      <title>[Off Topic] Nano introdução do framework Angular para Devs do back</title>
      <dc:creator>Meu Código Ágil</dc:creator>
      <pubDate>Wed, 22 May 2024 11:52:42 +0000</pubDate>
      <link>https://dev.to/meucodigoagil/off-topic-nano-introducao-do-framework-angular-para-devs-do-back-3jhd</link>
      <guid>https://dev.to/meucodigoagil/off-topic-nano-introducao-do-framework-angular-para-devs-do-back-3jhd</guid>
      <description>&lt;p&gt;Fugindo um pouco do tema do canal, resolvi escrever esse post destinado aos Devs do backend que estão acompanhando a nossa jornada de descoberta da ferramenta JHipster. Caso você tenha caído aqui de paraquedas, trata-se de uma série de posts que começamos &lt;a href="https://dev.to/meucodigoagil/agile-sem-as-ferramentas-certas-e-so-mais-uma-forma-desorganizada-de-produzir-software-35ii"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Esse post não tem nem mesmo a pretensão de ensinar você a fazer um mero “Hello World” em Angular. A intenção aqui é apenas introduzir um conjunto pequeno de conceitos básicos do Angular para que os desenvolvedores que não têm a menor desenvoltura com frontend possam acompanhar menos agoniados as análises de código gerado pelo JHipster.&lt;/p&gt;

&lt;p&gt;Durante as descrições dos conceitos abaixo, quando eu fizer referência a “nossa aplicação”, estou me referindo a uma aplicação monolítica exemplo que foi gerada com o JHipster 8 durante essa série de posts que citei acima. O post da geração da aplicação em si é este aqui, mas se preferir, o código também está no Github.&lt;/p&gt;

&lt;p&gt;Estando tudo isso esclarecido, vamos começar? :)&lt;/p&gt;

&lt;h1&gt;
  
  
  Componente
&lt;/h1&gt;

&lt;p&gt;uase tudo é um componente no Angular. Podemos entendê-lo como um código que encapsula HTML, CSS e lógica em Typescript. Não por acaso, tipicamente, um componente no Angular é formado por 3 arquivos: um HTML, um arquivo de estilos (CSS ou SCSS) e um arquivo TS. Tomemos como exemplo o componente &lt;code&gt;app/home&lt;/code&gt; da nossa aplicação:&lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;home.component.scss&lt;/code&gt;, não tem nada além da definição de classes de estilos que vão estipular todas aquelas coisinhas que a galera de UI se amarra: posicionamento, tamanho, fontes, cores … nada que desperte encantos em um Dev do back, mas se for só pra dar uma olhadinha sem compromisso, também não assusta.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.hipster&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;347px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;497px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url('../../content/images/jhipster_family_member_3.svg')&lt;/span&gt; 
    &lt;span class="nb"&gt;no-repeat&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt; &lt;span class="nb"&gt;top&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;contain&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No arquivo &lt;code&gt;home.component.html&lt;/code&gt;, como você já deve ter imaginado, tem um monte de tags HTML, textos, referências a classes CSS. Nada que nós &lt;em&gt;backenders&lt;/em&gt; não tenhamos visto antes, certo?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hipster img-fluid rounded"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-9"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"display-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;jhiTranslate=&lt;/span&gt;&lt;span class="s"&gt;"home.title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Bem vindo, Java Hipster!&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt; 
      (Minha Aplicacao Monolitica)
    &lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"lead"&lt;/span&gt; &lt;span class="na"&gt;jhiTranslate=&lt;/span&gt;&lt;span class="s"&gt;"home.subtitle"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      Esta é a página principal
    &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;  
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com exceção de coisinhas como esse &lt;code&gt;@if (....)&lt;/code&gt; no trecho a seguir. Mas que, muito provavelmente, você já viu algo parecido em soluções que usavam templates como ASP, JSP etc … é só uma lógica de exibição de um trecho de HTML ou outro que faz referência a uma variável/atributo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
      @if (account() !== null) {
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"alert alert-success"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          @if (account()) {
            &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"home-logged-message"&lt;/span&gt; &lt;span class="na"&gt;jhiTranslate=&lt;/span&gt;&lt;span class="s"&gt;"home.logged.message"&lt;/span&gt; &lt;span class="na"&gt;[translateValues]=&lt;/span&gt;&lt;span class="s"&gt;"{ username: account()!.login }"&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Você está logado como &lt;span class="ni"&gt;&amp;amp;quot;&lt;/span&gt;{{ account()!.login }}&lt;span class="ni"&gt;&amp;amp;quot;&lt;/span&gt;.&lt;span class="nt"&gt;&amp;lt;/span&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          }
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      } @else {
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"alert alert-warning"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;jhiTranslate=&lt;/span&gt;&lt;span class="s"&gt;"global.messages.info.authenticated.prefix"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Se deseja &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"alert-link"&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"login()"&lt;/span&gt; &lt;span class="na"&gt;jhiTranslate=&lt;/span&gt;&lt;span class="s"&gt;"global.messages.info.authenticated.link"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;entrar&lt;span class="nt"&gt;&amp;lt;/a&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;jhiTranslate=&lt;/span&gt;&lt;span class="s"&gt;"global.messages.info.authenticated.suffix"&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;, utilize as seguintes contas padrões:&lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;- Administrador (usuário=&lt;span class="ni"&gt;&amp;amp;quot;&lt;/span&gt;admin&lt;span class="ni"&gt;&amp;amp;quot;&lt;/span&gt; and senha=&lt;span class="ni"&gt;&amp;amp;quot;&lt;/span&gt;admin&lt;span class="ni"&gt;&amp;amp;quot;&lt;/span&gt;) &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;-
            Usuário (usuário=&lt;span class="ni"&gt;&amp;amp;quot;&lt;/span&gt;user&lt;span class="ni"&gt;&amp;amp;quot;&lt;/span&gt; e senha=&lt;span class="ni"&gt;&amp;amp;quot;&lt;/span&gt;user&lt;span class="ni"&gt;&amp;amp;quot;&lt;/span&gt;).&lt;span class="nt"&gt;&amp;lt;/span&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"alert alert-warning"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;jhiTranslate=&lt;/span&gt;&lt;span class="s"&gt;"global.messages.info.register.noaccount"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Não possui uma conta ainda?&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;span class="ni"&gt;&amp;amp;nbsp;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"alert-link"&lt;/span&gt; &lt;span class="na"&gt;routerLink=&lt;/span&gt;&lt;span class="s"&gt;"/account/register"&lt;/span&gt; &lt;span class="na"&gt;jhiTranslate=&lt;/span&gt;&lt;span class="s"&gt;"global.messages.info.register.link"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Crie uma nova conta&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E adivinhe onde está essa variável … exatamente! Está na classe Typescript declarada no arquivo &lt;code&gt;home.component.ts&lt;/code&gt; resumida a seguir:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;standalone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jhi-home&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./home.component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;styleUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./home.component.scss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;SharedModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;RouterModule&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HomeComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;OnDestroy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;account&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Account&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;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;

  &lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;navigate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perceba que a classe possui uma anotação &lt;code&gt;@Component&lt;/code&gt; onde dois dos atributos que a anotação recebe são exatamente o path relativo dos arquivos HTML e SCSS. Outro atributo que cabe chamarmos atenção é o &lt;code&gt;selector&lt;/code&gt;. Esse atributo define qual será a tag desse componente &lt;code&gt;HomeComponent&lt;/code&gt; que o JHipster criou pra nós. Isso significa que poderíamos utilizar este componente dentro de outro componente utilizando a tag &lt;code&gt;jhi-home&lt;/code&gt; como neste exemplo hipotético:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;jhi-home&amp;gt;&amp;lt;/jhi-home&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você vai encontrar no mesmo diretório o arquivo &lt;code&gt;home.component.spec.ts&lt;/code&gt;. Por ora, basta saber que se trata dos testes unitários do componente.&lt;/p&gt;

&lt;p&gt;Um último ponto para fecharmos a explicação sobre componentes Angular: um componente não precisa necessariamente ter o arquivo de estilos (CSS ou SCSS). Veja, por exemplo, o componente &lt;code&gt;app/login&lt;/code&gt; da nossa aplicação:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jhi-login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;standalone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;SharedModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FormsModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ReactiveFormsModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;RouterModule&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./login.component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoginComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AfterViewInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ViewChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;username&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;static&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ElementRef&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Além de não ter um arquivo de estilos no diretório &lt;code&gt;login&lt;/code&gt;, perceba que na anotação &lt;code&gt;@Component&lt;/code&gt; o atributo &lt;code&gt;styleUrl&lt;/code&gt; também não é setado. Mas olhando o seu template, o arquivo HTML, é possível notar referências a classes de estilo. Entretanto, essas classes vêm da pacote &lt;a href="https://getbootstrap.com/"&gt;Bootstrap&lt;/a&gt; ou de algum dos arquivos da pasta &lt;code&gt;webapp/content/scss&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"d-flex justify-content-center"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-lg-6 col-md-8 col-sm-10"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;jhiTranslate=&lt;/span&gt;&lt;span class="s"&gt;"login.title"&lt;/span&gt; &lt;span class="na"&gt;data-cy=&lt;/span&gt;&lt;span class="s"&gt;"loginTitle"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Autenticação&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
     @if (authenticationError()) {
       &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"alert alert-danger"&lt;/span&gt; &lt;span class="na"&gt;jhiTranslate=&lt;/span&gt;&lt;span class="s"&gt;"login.messages.error.authentication"&lt;/span&gt; &lt;span class="na"&gt;data-cy=&lt;/span&gt;&lt;span class="s"&gt;"loginError"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;Erro de autenticação!&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; Por favor verifique suas credenciais e tente novamente.
       &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
     }
     &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt; &lt;span class="na"&gt;(ngSubmit)=&lt;/span&gt;&lt;span class="s"&gt;"login()"&lt;/span&gt; &lt;span class="na"&gt;[formGroup]=&lt;/span&gt;&lt;span class="s"&gt;"loginForm"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Serviço
&lt;/h1&gt;

&lt;p&gt;Aqui está um conceito que não vai deixar nenhum Dev backend desconfortável. Afinal, um Serviço é tão somente uma classe Typescript que fornece funcionalidades específicas para serem reutilizadas por distintas partes da aplicação. Não tem HTML, não tem CSS … é tão somente: CÓ-DI-GO!&lt;/p&gt;

&lt;p&gt;Veja, por exemplo, o serviço &lt;code&gt;app/core/auth/state-storage.service.ts&lt;/code&gt; que, basicamente, encapsula funcionalidades de ler, escrever e apagar dados na &lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/API/Window/sessionStorage"&gt;sessionStorage&lt;/a&gt; do navegador.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StateStorageService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;previousUrlKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;previousUrl&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;authenticationKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jhi-authenticationToken&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;localeKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;locale&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;storeUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;previousUrlKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;getUrl&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;previousUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;previousUrlKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;previousUrl&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;previousUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;previousUrl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;clearUrl&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;previousUrlKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sabe outro tipo de funcionalidade que também fica a cargo de Serviços? Requisições HTTP a APIs! Veja abaixo um trecho do serviço &lt;code&gt;app/entities/produto/service/produto.service.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProdutoService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 

  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nx"&gt;applicationConfigService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ApplicationConfigService&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nx"&gt;resourceUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;applicationConfigService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getEndpointFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;api/produtos&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NewProduto&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;EntityResponseType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&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="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IProduto&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resourceUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;response&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;EntityResponseType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&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="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IProduto&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resourceUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;response&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apenas para ficar mais claro, selecionei um método do componente &lt;code&gt;app/entities/produto/update/produto-update.component.ts&lt;/code&gt; que mostra o método &lt;code&gt;create&lt;/code&gt; do nosso &lt;code&gt;ProdutoService&lt;/code&gt; sendo utilizado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;standalone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jhi-produto-update&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./produto-update.component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;SharedModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FormsModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ReactiveFormsModule&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProdutoUpdateComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nx"&gt;produtoService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ProdutoService&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isSaving&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;produto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;produtoFormService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getProduto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;editForm&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribeToSaveResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;produtoService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribeToSaveResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;produtoService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Interceptador
&lt;/h1&gt;

&lt;p&gt;Mais um treco que não vai assustar nenhum Dev do back, afinal, é só código também. Um interceptador tem o papel de interceptar e modificar requisições HTTP, tem função semelhante a dos &lt;em&gt;filters&lt;/em&gt; da API Servlet do Java.&lt;/p&gt;

&lt;p&gt;Com um interceptor, você pode por exemplo, inserir um cabeçalho Authorization em todas as requisições destinadas aos endpoints do backend. Se você abrir o interceptador &lt;code&gt;app/core/interceptor/auth-interceptor.ts&lt;/code&gt;, vai constatar que é exatamente isso que ele está fazendo na implementação do método &lt;code&gt;intercept&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthInterceptor&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;HttpInterceptor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;stateStorageService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;StateStorageService&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;applicationConfigService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ApplicationConfigService&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;intercept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpRequest&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpHandler&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HttpEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;serverApiUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;applicationConfigService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getEndpointFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;serverApiUrl&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;serverApiUrl&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stateStorageService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAuthenticationToken&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;setHeaders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Rota
&lt;/h1&gt;

&lt;p&gt;Uma rota define como o Angular responderá a diferentes URLs. Em outras palavras, uma rota define qual componente Angular será apresentado para um caminho de URL específico. Simples assim!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HomeComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;LoginComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima, quando o usuário digitar no navegador &lt;code&gt;http://localhost:4200/&lt;/code&gt;, o componente exibido pelo Angular será o &lt;code&gt;HomeComponent&lt;/code&gt;. Já quando ele digitar ou for redirecionado para &lt;code&gt;http://localhost:4200/login&lt;/code&gt;, é o &lt;code&gt;LoginComponent&lt;/code&gt; que será exibido na interface do usuário.&lt;/p&gt;

&lt;p&gt;Além de declarar as rotas da aplicação, elas precisam ser registradas para que a aplicação tenha o comportamento esperado.&lt;/p&gt;

&lt;p&gt;As rotas que coloquei acima como exemplo estão declaradas da forma mais simples possível. Uma rota pode ser bem mais complexa que isso, ela pode por exemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;definir dados a serem enviados para o componente especificado na rota;&lt;/li&gt;
&lt;li&gt;carregar outro conjunto de rotas dinamicamente;&lt;/li&gt;
&lt;li&gt;implementar lógica a ser executada antes do carregamento do componente da rota. Por exemplo, para validar se o usuário tem as roles de acesso necessárias;&lt;/li&gt;
&lt;li&gt;implementar lógica a ser executada antes de sair do componente da rota. Por exemplo, para pedir uma confirmação do usuário caso ele esteja abandonando um formulário no meio de uma edição sem salvar os dados.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enfim … uma rota nos dá muitas possibilidades, mas acho que para a nano introdução do Angular à turma do backend que pretendíamos, podemos parar por aqui antes de causarmos uma repulsa indesejada rs&lt;/p&gt;

&lt;p&gt;Mas se você chegou até aqui e ficou interessado em se aprofundar mais no assunto, o que não falta é gente gabaritada por aí ensinando Angular, até mesmo de graça. E, na boa? Aprender nunca é demais. Ainda que você não tenha intenção de (re)direcionar a sua carreira para o frontend, o conhecimento sobre o framework vai agregar muito na sua interação com os colegas responsáveis por esse nicho nos seus projetos.&lt;/p&gt;

&lt;p&gt;Duas fontes que me ajudaram a entender melhor esse mundo (sim, apenas entender, eu não fui convertido rsrs) foram: &lt;a href="https://www.youtube.com/@loianegroner"&gt;o canal da Loiane Groner no YouTube&lt;/a&gt; e a &lt;a href="https://www.alura.com.br/formacao-angular-14"&gt;Formação Angular na Alura&lt;/a&gt;. Sem falar, claro, nos próprios canais oficiais do Angular: o &lt;a href="https://blog.angular.io/"&gt;blog&lt;/a&gt; e o &lt;a href="https://www.youtube.com/@Angular"&gt;canal no YouTube&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>frontend</category>
      <category>component</category>
      <category>service</category>
    </item>
    <item>
      <title>JHipster 8 - Analisando o código da nossa primeira aplicação monolítica - Parte 2/3</title>
      <dc:creator>Meu Código Ágil</dc:creator>
      <pubDate>Tue, 07 May 2024 00:23:13 +0000</pubDate>
      <link>https://dev.to/meucodigoagil/jhipster-8-analisando-o-codigo-da-nossa-primeira-aplicacao-monolitica-parte-23-2kan</link>
      <guid>https://dev.to/meucodigoagil/jhipster-8-analisando-o-codigo-da-nossa-primeira-aplicacao-monolitica-parte-23-2kan</guid>
      <description>&lt;p&gt;Dando continuidade à nossa análise do código-fonte da aplicação monolítica que criamos utilizando o JHipster, vamos agora explorar o código Java do nosso backend. É importante lembrar que o código do backend é baseado no framework &lt;a href="https://spring.io/projects/spring-boot"&gt;Spring Boot&lt;/a&gt;. No caso do JHipster 8, no Spring Boot 3.2.3 mais especificamente.&lt;/p&gt;

&lt;p&gt;Conforme mencionado no &lt;a href="https://dev.to/meucodigoagil/jhipster-8-analisando-o-codigo-da-nossa-primeira-aplicacao-monolitica-parte-13-2380"&gt;primeiro post&lt;/a&gt; desta sequência voltada para a análise do código do nosso monolito, o volume de código gerado é bastante extenso, o que torna inviável abordar todos os detalhes sem se tornar cansativo. Portanto, selecionei criteriosamente os pacotes e classes que julgo mais importantes neste estágio em que nos encontramos nesta jornada de apresentação do JHipster 8.&lt;/p&gt;

&lt;h1&gt;
  
  
  Java
&lt;/h1&gt;

&lt;h2&gt;
  
  
  MinhaAplicacaoMonoliticaApp.java
&lt;/h2&gt;

&lt;p&gt;Conforme definido durante os prompts do JHipster CLI ao construirmos nossa aplicação, o pacote base das classes da aplicação é &lt;code&gt;br.com.meucodigoagil.minhapp&lt;/code&gt;, assim, nosso código fonte Java estará localizado no diretório &lt;code&gt;src/main/java/br/com/meucodigoagil/minhapp&lt;/code&gt; e é exatamente aí que estará a classe principal da nossa aplicação: &lt;code&gt;MinhaAplicacaoMonoliticaApp&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Como uma aplicação Spring Boot, é pela sua classe principal que a aplicação é inicializada. Esta classe deve ser anotada com &lt;code&gt;@SpringBootApplication&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;@SpringBootApplication&lt;/span&gt;
&lt;span class="nd"&gt;@EnableConfigurationProperties&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt; &lt;span class="nc"&gt;LiquibaseProperties&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="nc"&gt;ApplicationProperties&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;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MinhaAplicacaoMonoliticaApp&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;Como uma classe principal, podemos notar que ela também conta com um método estático &lt;code&gt;main&lt;/code&gt; que cria uma instância de &lt;code&gt;SpringApplication&lt;/code&gt; passando a própria classe como parâmetro, executa a instância criada e imprime no console aquela mensagem que vimos ao inicializar a nossa aplicação informando, entre outros, host e porta.&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;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;SpringApplication&lt;/span&gt; &lt;span class="n"&gt;app&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;SpringApplication&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MinhaAplicacaoMonoliticaApp&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="nc"&gt;DefaultProfileUtil&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addDefaultProfile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;Environment&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;getEnvironment&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;logApplicationStartup&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&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;
  
  
  br.com.meucodigoagil.minhapp.config.*
&lt;/h2&gt;

&lt;p&gt;Dentro do pacote &lt;code&gt;br.com.meucodigoagil.minhapp.config&lt;/code&gt;, você poderá conferir um grande número de classes destinadas a configurar a nossa aplicação.&lt;/p&gt;

&lt;p&gt;A classe &lt;code&gt;CacheConfiguration&lt;/code&gt; habilita cache na nossa aplicação e configura o Ehcache conforme selecionamos durante os prompts do JHipster CLI.&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;@Configuration&lt;/span&gt;
&lt;span class="nd"&gt;@EnableCaching&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;CacheConfiguration&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;GitProperties&lt;/span&gt; &lt;span class="n"&gt;gitProperties&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;BuildProperties&lt;/span&gt; &lt;span class="n"&gt;buildProperties&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;final&lt;/span&gt; &lt;span class="n"&gt;javax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;configuration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Configuration&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;jcacheConfiguration&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;CacheConfiguration&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JHipsterProperties&lt;/span&gt; &lt;span class="n"&gt;jHipsterProperties&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;JHipsterProperties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Ehcache&lt;/span&gt; &lt;span class="n"&gt;ehcache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jHipsterProperties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getCache&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getEhcache&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;jcacheConfiguration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Eh107Configuration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromEhcacheCacheConfiguration&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="nc"&gt;CacheConfigurationBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newCacheConfigurationBuilder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="nc"&gt;Object&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="nc"&gt;Object&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="nc"&gt;ResourcePoolsBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;heap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ehcache&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMaxEntries&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="na"&gt;withExpiry&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ExpiryPolicyBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;timeToLiveExpiration&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofSeconds&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ehcache&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTimeToLiveSeconds&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;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A classe &lt;code&gt;DatabaseConfiguration&lt;/code&gt; possui um bean que configura servidor do banco de dados H2 (usado em tempo de desenvolvimento) para escutar em uma porta TCP.&lt;/p&gt;

&lt;p&gt;Perceba no código a seguir que a anotação &lt;code&gt;@Profile&lt;/code&gt; restringe a aplicação desta configuração apenas quando a aplicação está sendo executada sob o perfil de desenvolvimento.&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;@Bean&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;initMethod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"start"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;destroyMethod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"stop"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Profile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JHipsterConstants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SPRING_PROFILE_DEVELOPMENT&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;Object&lt;/span&gt; &lt;span class="nf"&gt;h2TCPServer&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;SQLException&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;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getValidPortForH2&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"H2 database is available on port {}"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&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;H2ConfigurationHelper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createServer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port&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;A classe &lt;code&gt;SecurityConfiguration&lt;/code&gt; faz uma série de configurações relacionadas à segurança da aplicação, como a liberação ou a restrição de certos endpoints. Enquanto a &lt;code&gt;SecurityJwtConfiguration&lt;/code&gt; cria beans relacionados à autenticação por JWT, incluindo codificador e decodificador do token.&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;@Configuration&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;SecurityJwtConfiguration&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;final&lt;/span&gt; &lt;span class="nc"&gt;Logger&lt;/span&gt; &lt;span class="n"&gt;log&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;SecurityJwtConfiguration&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;@Value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"${jhipster.security.authentication.jwt.base64-secret}"&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;jwtKey&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;JwtDecoder&lt;/span&gt; &lt;span class="nf"&gt;jwtDecoder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SecurityMetersService&lt;/span&gt; &lt;span class="n"&gt;metersService&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;NimbusJwtDecoder&lt;/span&gt; &lt;span class="n"&gt;jwtDecoder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NimbusJwtDecoder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withSecretKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getSecretKey&lt;/span&gt;&lt;span class="o"&gt;()).&lt;/span&gt;&lt;span class="na"&gt;macAlgorithm&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;JWT_ALGORITHM&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;jwtDecoder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;decode&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="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid signature"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;metersService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;trackTokenInvalidSignature&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;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Jwt expired at"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;metersService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;trackTokenExpired&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;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid JWT serialization"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
                    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Malformed token"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
                    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid unsecured/JWS/JWE"&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="n"&gt;metersService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;trackTokenMalformed&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;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unknown JWT error {}"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;};&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;JwtEncoder&lt;/span&gt; &lt;span class="nf"&gt;jwtEncoder&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;NimbusJwtEncoder&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;ImmutableSecret&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;getSecretKey&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;h2&gt;
  
  
  br.com.meucodigoagil.minhapp.domain.*
&lt;/h2&gt;

&lt;p&gt;No pacote &lt;code&gt;br.com.meucodigoagil.minhapp.domain&lt;/code&gt; encontraremos nossas classes de domínio, ou seja, as entidades da nossa aplicação anotadas com &lt;code&gt;@Entity&lt;/code&gt; . Além das entidades que fazem parte do domínio da nossa aplicação, como a nossa &lt;code&gt;Produto&lt;/code&gt;, encontraremos entidades relacionadas a funcionalidades de segurança criadas automaticamente pelo JHipster, como &lt;code&gt;User&lt;/code&gt; e &lt;code&gt;Authority&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ao analisarmos a classe &lt;code&gt;Produto&lt;/code&gt;, podemos notar que o atributo &lt;code&gt;nome&lt;/code&gt; possui a anotação com as regras de tamanho que solicitamos ao JHipster CLI.&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;@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;"produto"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Cache&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;usage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CacheConcurrencyStrategy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;READ_WRITE&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@SuppressWarnings&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"common-java:DuplicatedBlocks"&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;Produto&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Serializable&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="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;serialVersionUID&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="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;SEQUENCE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;generator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"sequenceGenerator"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@SequenceGenerator&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;"sequenceGenerator"&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;"id"&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;Long&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;@NotNull&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;3&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;100&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;"nome"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unique&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="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;nome&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;h2&gt;
  
  
  br.com.meucodigoagil.minhapp.repository.*
&lt;/h2&gt;

&lt;p&gt;Neste pacote temos as classes que farão o papel de repositório de dados, ou seja, que terão a responsabilidade de buscar os dados no banco de dados e que são anotadas com &lt;code&gt;@Repository&lt;/code&gt;. Temos repositório para cada uma das classes de domínio. Perceba que se trata apenas de uma interface que, além de anotada, estende a interface &lt;code&gt;JpaRepository&lt;/code&gt; do Spring, que proverá por baixo dos panos um conjunto de métodos básicos de acesso e manutenção de dados.&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;@Repository&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;ProdutoRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;JpaRepository&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;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  br.com.meucodigoagil.minhapp.service.*
&lt;/h2&gt;

&lt;p&gt;Neste pacote ficam as classes &lt;code&gt;@Service&lt;/code&gt; que, no Spring, são responsáveis pela implementação de regras de negócio, bem como as classes DTO. Ao visualizar as classes deste pacote na nossa aplicação, você notará que se trata apenas do &lt;code&gt;UserService&lt;/code&gt;, relacionada à entidade &lt;code&gt;User&lt;/code&gt; padrão do JHipster e &lt;code&gt;MailService&lt;/code&gt;, além de algumas classes Exception. Isso se deve ao fato de que durante o prompt do JHipster CLI nós escolhemos que as nossas classes &lt;code&gt;@RestController&lt;/code&gt; chamariam as &lt;code&gt;@Repository&lt;/code&gt; de forma direta. Lembra?&lt;/p&gt;

&lt;h2&gt;
  
  
  br.com.meucodigoagil.minhapp.web.*
&lt;/h2&gt;

&lt;p&gt;Neste pacote, teremos a implementação de classes do tipo Filter e Controllers do nosso MVC. Falando em controllers, eles estão mais especificamente no pacote &lt;code&gt;br.com.meucodigoagil.minhapp.web.rest&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Encontramos o controller que expõe endpoints da nossa entidade &lt;code&gt;Produto&lt;/code&gt; e também outros controllers com endpoints voltados para mecanismos de autenticação e autorização da aplicação.&lt;/p&gt;

&lt;p&gt;Conforme citado anteriormente, podemos ver no código que a &lt;code&gt;ProdutoResource&lt;/code&gt; tem injetada uma instância de &lt;code&gt;ProdutoRepository&lt;/code&gt; em seu construtor e que este será invocado, por exemplo, no método &lt;code&gt;getAllProdutos()&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;@RestController&lt;/span&gt;
&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/produtos"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Transactional&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;ProdutoResource&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;final&lt;/span&gt; &lt;span class="nc"&gt;Logger&lt;/span&gt; &lt;span class="n"&gt;log&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;ProdutoResource&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="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;ENTITY_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"produto"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"${jhipster.clientApp.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;applicationName&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;final&lt;/span&gt; &lt;span class="nc"&gt;ProdutoRepository&lt;/span&gt; &lt;span class="n"&gt;produtoRepository&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;ProdutoResource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ProdutoRepository&lt;/span&gt; &lt;span class="n"&gt;produtoRepository&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;produtoRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;produtoRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * {@code GET  /produtos} : get all the produtos.
     *
     * @return the {@link ResponseEntity} with status {@code 200 (OK)}
     * and the list of produtos in body.
     */&lt;/span&gt;
    &lt;span class="nd"&gt;@GetMapping&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="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;Produto&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getAllProdutos&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"REST request to get all Produtos"&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;produtoRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findAll&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;
  
  
  Resources
&lt;/h1&gt;

&lt;p&gt;Além dos arquivos Java, também fazem parte do backend os arquivos de configuração, que ficam sob o diretório &lt;code&gt;src/main/resources&lt;/code&gt;. Passemos pelos principais pontos.&lt;/p&gt;

&lt;h2&gt;
  
  
  config/application*.yml
&lt;/h2&gt;

&lt;p&gt;Na raiz do diretório &lt;code&gt;src/main/resources/config&lt;/code&gt;, temos um conjunto de arquivos YML para configuração da nossa aplicação. O arquivo &lt;code&gt;application.yml&lt;/code&gt;, detêm as configurações aplicáveis a qualquer que seja o profile sob o qual a aplicação está em execução, seja desenvolvimento ou produção.&lt;/p&gt;

&lt;p&gt;Já os arquivos com algum sufixo, são aplicados de acordo com o profile sob o qual a aplicação está em execução. Assim, o arquivo &lt;code&gt;application-dev.yml&lt;/code&gt; armazenará valores de configuração especificamente para quando a aplicação está executando sob o perfil &lt;code&gt;dev&lt;/code&gt;. Note que sob a chave &lt;code&gt;spring.datasource&lt;/code&gt; encontramos uma configuração do banco de dados H2:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;spring&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;...&lt;/span&gt;
  &lt;span class="s"&gt;datasource&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;com.zaxxer.hikari.HikariDataSource&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jdbc:h2:file:./target/h2db/db/minhaAplicacaoMonolitica;DB_CLOSE_DELAY=-1&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;minhaAplicacaoMonolitica&lt;/span&gt;
    &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;hikari&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;poolName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Hikari&lt;/span&gt;
      &lt;span class="na"&gt;auto-commit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="na"&gt;h2&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# disable spring boot built-in h2-console since we start it manually with correct configuration&lt;/span&gt;
      &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por outro lado, o &lt;code&gt;application-prod.yml&lt;/code&gt; será utilizado quando a aplicação estiver sob o profile &lt;code&gt;prod&lt;/code&gt;. Se verificarmos a mesma chave &lt;code&gt;spring.datasource&lt;/code&gt;, encontraremos a configuração para uma base PostgreSQL conforme nós escolhemos em um dos prompts do JHipster CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;spring&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;...&lt;/span&gt;
  &lt;span class="s"&gt;datasource&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;com.zaxxer.hikari.HikariDataSource&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jdbc:postgresql://localhost:5432/minhaAplicacaoMonolitica&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;minhaAplicacaoMonolitica&lt;/span&gt;
    &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;hikari&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;poolName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Hikari&lt;/span&gt;
      &lt;span class="na"&gt;auto-commit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  config/liquibase/
&lt;/h2&gt;

&lt;p&gt;Sob o diretório &lt;code&gt;src/resources/config/liquibase&lt;/code&gt;, temos os changelogs do &lt;a href="https://www.liquibase.com"&gt;Liquibase&lt;/a&gt;, a ferramenta utilizada pelas aplicações geradas pelo JHipster para o gerenciamento de mudanças no esquema do banco de dados.&lt;/p&gt;

&lt;p&gt;No subdiretório &lt;code&gt;changelog&lt;/code&gt;, temos os arquivos com os conjunto de instruções para criação e modificação do esquema de banco de dados conforme podemos ver a seguir a criação da tabela &lt;code&gt;Produto&lt;/code&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;changeSet&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"20240324155937-1"&lt;/span&gt; &lt;span class="na"&gt;author=&lt;/span&gt;&lt;span class="s"&gt;"jhipster"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;createTable&lt;/span&gt; &lt;span class="na"&gt;tableName=&lt;/span&gt;&lt;span class="s"&gt;"produto"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;column&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"bigint"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;constraints&lt;/span&gt; &lt;span class="na"&gt;primaryKey=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt; &lt;span class="na"&gt;nullable=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/column&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;column&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"nome"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"varchar(100)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;constraints&lt;/span&gt; &lt;span class="na"&gt;nullable=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt; &lt;span class="na"&gt;unique=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt; &lt;span class="na"&gt;uniqueConstraintName=&lt;/span&gt;&lt;span class="s"&gt;"ux_produto__nome"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/column&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;column&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"tipo"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"varchar(255)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;constraints&lt;/span&gt; &lt;span class="na"&gt;nullable=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/column&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- jhipster-needle-liquibase-add-column - JHipster will add columns here --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/createTable&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/changeSet&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Já na raiz, temos no arquivo &lt;code&gt;master.xml&lt;/code&gt;, além de declarar algumas propriedades que podem ser utilizadas dentro dos changelogs, também faz referência aos próprios changelogs que serão executados:&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;databaseChangeLog&lt;/span&gt;
    &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.liquibase.org/xml/ns/dbchangelog"&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://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"now"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"now()"&lt;/span&gt; &lt;span class="na"&gt;dbms=&lt;/span&gt;&lt;span class="s"&gt;"h2"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    ...

    &lt;span class="nt"&gt;&amp;lt;include&lt;/span&gt; &lt;span class="na"&gt;file=&lt;/span&gt;&lt;span class="s"&gt;"config/liquibase/changelog/00000000000000_initial_schema.xml"&lt;/span&gt; &lt;span class="na"&gt;relativeToChangelogFile=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;include&lt;/span&gt; &lt;span class="na"&gt;file=&lt;/span&gt;&lt;span class="s"&gt;"config/liquibase/changelog/20240324155937_added_entity_Produto.xml"&lt;/span&gt; &lt;span class="na"&gt;relativeToChangelogFile=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/databaseChangeLog&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  config/i18n/
&lt;/h2&gt;

&lt;p&gt;Sob este diretório encontramos arquivos de propriedades com mensagens nos idiomas que selecionamos para a aplicação. A seguir, mostramos parcialmente os arquivos com mensagens em português e em inglês:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; # Reset email
email.reset.title=A Senha da aplicação minhaAplicacaoMonolitica foi redifinida
email.reset.greeting=Caro {0}
email.reset.text1=Foi solicitado a redefinição de senha da sua conta minhaAplicacaoMonolitica. Por favor clique na url abaixo para alterá-la:
email.reset.text2=Atenciosamente,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; # Reset email
# Reset email
email.reset.title=minhaAplicacaoMonolitica password reset
email.reset.greeting=Dear {0}
email.reset.text1=For your minhaAplicacaoMonolitica account a password reset was requested, please click on the URL below to reset it:
email.reset.text2=Regards,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Os textos contidos nas chaves desses arquivos serão lidos com auxílio do Spring Boot para retornar textos de acordo com o idioma do usuário final. A seguir um exemplo de como isso poderia ser realizado considerando que os arquivos de mensagens tivessem uma mensagem sob a chave &lt;code&gt;error.message&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ApenasExemplo&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;final&lt;/span&gt; &lt;span class="nc"&gt;MessageSource&lt;/span&gt; &lt;span class="n"&gt;messageSource&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;ApenasExemplo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MessageSource&lt;/span&gt; &lt;span class="n"&gt;messageSource&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;messageSource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;messageSource&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;facaAlgo&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="nc"&gt;Locale&lt;/span&gt; &lt;span class="n"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Locale&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forLanguageTag&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;getLangKey&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;RuntimeException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;messageSource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"error.message"&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="n"&gt;locale&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Finalizamos aqui a análise do código backend gerado pelo JHipster. Passamos pelas principais classes Java da aplicação, classes do domínio, classes de configuração, classes de acesso a dados, controllers, e também pelos arquivos de configuração do nosso backend.&lt;/p&gt;

&lt;p&gt;Na próxima publicação, vamos nos aprofundar no código-fonte do nosso frontend Angular. Até lá, explore mais o código do nosso backend e mande suas dúvidas nos comentários ;)&lt;/p&gt;

</description>
      <category>jhipster</category>
      <category>java</category>
      <category>spring</category>
      <category>agile</category>
    </item>
    <item>
      <title>JHipster 8 - Analisando o código da nossa primeira aplicação monolítica - Parte 1/3</title>
      <dc:creator>Meu Código Ágil</dc:creator>
      <pubDate>Sun, 28 Apr 2024 23:26:06 +0000</pubDate>
      <link>https://dev.to/meucodigoagil/jhipster-8-analisando-o-codigo-da-nossa-primeira-aplicacao-monolitica-parte-13-2380</link>
      <guid>https://dev.to/meucodigoagil/jhipster-8-analisando-o-codigo-da-nossa-primeira-aplicacao-monolitica-parte-13-2380</guid>
      <description>&lt;p&gt;No último post, nós passamos por um tutorial que nos levou a criar a nossa primeira aplicação, uma aplicação monolítica muito simples com apenas uma entidade cujo propósito era apenas apresentar a vocês o JHipster.&lt;/p&gt;

&lt;p&gt;Percorremos passo a passo a construção desta aplicação e, por fim, mostrei para vocês como executá-la e também os prints das telas. Se você não está entendendo nada desses dois primeiros parágrafos, certamente você não conferiu ainda o post onde mostro passo a passo como utilizar o JHipster para gerar uma aplicação com mínimo esforço. Confere lá e depois volte aqui que eu prometo que tudo vai fazer mais sentido: &lt;a href="https://dev.to/meucodigoagil/jhipster-8-criando-uma-aplicacao-monolitica-128p-temp-slug-5281691?preview=595b9974d1fd68c3534222d2d0b645da60ff0512f07e162ff65c8b5e2d6f6e4b02b378de46eeadf8ec454bf70a6831926530d53d0b3ba01bc832a387"&gt;JHipster 8 — Criando uma aplicação monolítica&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Pois bem … naquele post nós criamos a aplicação utilizando JHipster CLI, colocamos ela pra rodar, visualizamos as telas, interagimos, mas … ficou faltando algo bem importante para nós DEVs: abrir o capô dessa aplicação e verificar o que afinal o JHipster produziu. Sim, faltou olhar o código fonte que foi produzido pra nós. É isso que vamos fazer aqui!&lt;/p&gt;

&lt;h1&gt;
  
  
  Números
&lt;/h1&gt;

&lt;p&gt;Vamos começar por uma análise quantitativa do código fonte gerado e vamos considerar dois momentos distintos: o primeiro quando geramos a base da nossa aplicação, sem entidades. E o segundo quando criamos a entidade Produto na aplicação.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aplicação monolítica base
&lt;/h2&gt;

&lt;p&gt;Na criação da aplicação base (sem entidades), foram gerados 532 arquivos distribuídos em 158 diretórios e subdiretórios.&lt;/p&gt;

&lt;p&gt;Dividindo-se por extensão dos arquivos, as maiores quantidades de arquivos gerados foram:&lt;/p&gt;

&lt;p&gt;.ts: 217&lt;br&gt;
.java: 109&lt;br&gt;
.html: 50&lt;br&gt;
.json: 45&lt;/p&gt;

&lt;p&gt;E os diretórios com maior número de arquivos gerados, somando-se os arquivos em seus subdiretórios, são:&lt;/p&gt;

&lt;p&gt;&amp;lt;diretório da aplicação&amp;gt;/src/main/webapp: 308&lt;br&gt;
&amp;lt;diretório da aplicação&amp;gt;/src/main/java: 70&lt;br&gt;
&amp;lt;diretório da aplicação&amp;gt;/src/test/java: 39&lt;br&gt;
&amp;lt;diretório da aplicação&amp;gt;/: 27&lt;/p&gt;
&lt;h2&gt;
  
  
  Aplicação monolítica final
&lt;/h2&gt;

&lt;p&gt;Agora o quantitativo refere-se à versão final da aplicação monolítica que criamos, ou seja, após a inclusão da entidade Produto. Agora, a aplicação totaliza 571 arquivos distribuídos em 169 diretórios e subdiretórios.&lt;/p&gt;

&lt;p&gt;A divisão por extensão dos arquivos foi ajustada para:&lt;/p&gt;

&lt;p&gt;.ts: 236&lt;br&gt;
.java: 118&lt;br&gt;
.html: 54&lt;br&gt;
.json: 50&lt;/p&gt;

&lt;p&gt;E os diretórios com maior número de arquivos gerados, somando-se os arquivos em seus subdiretórios, são:&lt;/p&gt;

&lt;p&gt;&amp;lt;diretório da aplicação&amp;gt;/src/main/webapp: 334&lt;br&gt;
&amp;lt;diretório da aplicação&amp;gt;/src/main/java: 75&lt;br&gt;
&amp;lt;diretório da aplicação&amp;gt;/src/test/java: 43&lt;br&gt;
&amp;lt;diretório da aplicação&amp;gt;/: 27&lt;/p&gt;

&lt;p&gt;A primeira conclusão a qual podemos chegar é que o volume de código e configuração gerado é bastante significativo. Fazer tudo isso na mão levaria bem mais tempo do que aquele que gastamos respondendo aos prompts do JHipster :)&lt;/p&gt;
&lt;h1&gt;
  
  
  Estrutura e Organização
&lt;/h1&gt;

&lt;p&gt;A fim de melhor nos localizarmos quando formos analisar o código, é importante começarmos pela estrutura e organização dos arquivos na estrutura de diretórios da aplicação.&lt;/p&gt;

&lt;p&gt;Começando pelo diretório raiz da aplicação, veremos que ele possui uma quantidade grande arquivos. Em sua grande maioria, arquivos de configuração das próprias ferramentas de desenvolvimento. Por exemplo: pom.xml, .gitignore, .prettierrc, jest.config.js, cypress.config.ts, tsconfig.json, .eslintrc.json e por aí vai.&lt;/p&gt;

&lt;p&gt;Em relação aos subdiretórios da raiz, entendo que, ao menos nesta nossa primeira análise, vale a pena focarmos apenas no diretório onde estão os fontes da nossa aplicação: o diretório &lt;code&gt;./src/&lt;/code&gt;no qual damos um “zoom in” abaixo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├─ src
   ├── main
   │   ├── docker
   │   ├── java
   │   ├── resources
   │   │   ├── config
   │   │   ├── i18n
   │   │   └── templates
   │   └── webapp
   │       ├── WEB-INF
   │       ├── app
   │       ├── content
   │       ├── i18n
   │       └── swagger-ui
   └── test
       ├── java
       ├── javascript
       │   └── cypress
       └── resources
           ├── META-INF
           ├── config
           ├── i18n
           └── templates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos ver que o diretório &lt;code&gt;src&lt;/code&gt; se divide em &lt;code&gt;main&lt;/code&gt; e &lt;code&gt;test&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;main&lt;/code&gt;: abaixo deste diretório estão os arquivos fontes que se relacionam com a aplicação em si. Podemos perceber que ele se subdivide em:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;docker&lt;/code&gt;: onde encontramos alguns arquivos YML a serem utilizados pelo Docker Compose para subir diferentes serviços relacionados à aplicação, por exemplo, uma instância do banco PostgreSQL.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;java&lt;/code&gt;: onde está o código fonte Java da nossa aplicação em uma estrutura que inicia com o nome do pacote Java que demos na criação da aplicação: &lt;code&gt;br/com/meucodigoagil/minhapp&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;resources&lt;/code&gt;: que contém os arquivos de recursos tais como arquivos YAML de configuração da aplicação, os arquivos de mensagem de internacionalização (um pra cada idioma selecionado durante os prompts), configuração da biblioteca de logging &lt;a href="https://logback.qos.ch/"&gt;Logback&lt;/a&gt; etc.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;webapp&lt;/code&gt;: aqui está o código fonte do nosso frontend Angular com todos os seus arquivos Typescript, HTML, CSS, imagens, entre outros.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;test&lt;/code&gt;: abaixo deste diretório está o código que não faz parte da aplicação em si mas que apoiará o processo de garantia e controle da qualidade. Assim como o diretório “main”, ele também está subdivido para melhor organização:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;java&lt;/code&gt;: aqui se encontram os testes automatizados, unitários e de integração, do nosso backend.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;javacript&lt;/code&gt;: aqui temos os nossos testes de frontend e2e utilizando o Cypress.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;resources&lt;/code&gt;: assim como no diretório “main”, aqui temos os arquivos de YAML de configuração da aplicação, os arquivos de mensagem de internacionalização etc … mas que são aplicáveis apenas quando a aplicação está em execução durante os testes automatizados.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Arquivos de Configuração
&lt;/h1&gt;

&lt;p&gt;Vamos começar a análise da nossa aplicação pelos seus principais arquivos de configuração:&lt;/p&gt;

&lt;h2&gt;
  
  
  pom.xml
&lt;/h2&gt;

&lt;p&gt;Durante os prompts, escolhemos o Maven como a ferramenta de build do backend Java da nossa aplicação. Dentre outras características, uma aplicação Maven é organizada em estrutura padronizada de diretórios e conta com a presença de um ou mais arquivos de configuração pom.xml.&lt;/p&gt;

&lt;p&gt;Entre outras coisas, este arquivo vai conter a lista de dependências da aplicação, plugins utilizados e suas configurações etc. Percebemos logo no início do arquivo a identificação da nossa aplicação.&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;groupId&amp;gt;&lt;/span&gt;br.com.meucodigoagil.minhapp&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;minha-aplicacao-monolitica&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.0.1-SNAPSHOT&lt;span class="nt"&gt;&amp;lt;/version&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;name&amp;gt;&lt;/span&gt;Minha Aplicacao Monolitica&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;Description for Minha Aplicacao Monolitica&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na sequência, temos uma lista de propriedades com seus respectivos valores. Essa seção sozinha não alterada nada na aplicação, mas entenda essas propriedades como variáveis que serão utilizadas ao longo do pom.xml para configurar a aplicação como, por exemplo, na definição da versão de plugins, de dependências, de ferramentas de desenvolvimento e do próprio Java.&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;properties&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;maven.version&amp;gt;&lt;/span&gt;3.2.5&lt;span class="nt"&gt;&amp;lt;/maven.version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;java.version&amp;gt;&lt;/span&gt;17&lt;span class="nt"&gt;&amp;lt;/java.version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;node.version&amp;gt;&lt;/span&gt;v20.11.1&lt;span class="nt"&gt;&amp;lt;/node.version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;npm.version&amp;gt;&lt;/span&gt;10.5.0&lt;span class="nt"&gt;&amp;lt;/npm.version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;project.build.sourceEncoding&amp;gt;&lt;/span&gt;UTF-8&lt;span class="nt"&gt;&amp;lt;/project.build.sourceEncoding&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;project.reporting.outputEncoding&amp;gt;&lt;/span&gt;UTF-8&lt;span class="nt"&gt;&amp;lt;/project.reporting.outputEncoding&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;maven.build.timestamp.format&amp;gt;&lt;/span&gt;yyyyMMddHHmmss&lt;span class="nt"&gt;&amp;lt;/maven.build.timestamp.format&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;maven.compiler.source&amp;gt;&lt;/span&gt;${java.version}&lt;span class="nt"&gt;&amp;lt;/maven.compiler.source&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;maven.compiler.target&amp;gt;&lt;/span&gt;${java.version}&lt;span class="nt"&gt;&amp;lt;/maven.compiler.target&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;start-class&amp;gt;&lt;/span&gt;br.com.meucodigoagil.minhapp.MinhaAplicacaoMonoliticaApp&lt;span class="nt"&gt;&amp;lt;/start-class&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;argLine&amp;gt;&lt;/span&gt;-Djava.security.egd=file:/dev/./urandom -Xmx1G&lt;span class="nt"&gt;&amp;lt;/argLine&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A seguir, temos a seção &lt;code&gt;&amp;lt;dependencyManagement&amp;gt;&lt;/code&gt; que serve para gerenciar as dependências transitivas do projeto. Ela não adiciona diretamente as dependências ao projeto, mas define as versões que devem ser usadas por todos os módulos ou subprojetos e, assim, evita repetição de versões de dependências em vários lugares e ajuda a manter a consistência.&lt;/p&gt;

&lt;p&gt;Na &lt;code&gt;&amp;lt;dependencyManagement&amp;gt;&lt;/code&gt;da nossa aplicação, temos declarada a dependência &lt;code&gt;tech.jhipster:jhipster-dependencies&lt;/code&gt; versão 8.2.0. Essa dependência é chave em uma aplicação gerada com o JHipster. É nela que o JHipster estabelece, por exemplo, que o pacote Spring Boot utilizado na aplicação será a versão 3.2.3.&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;properties&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;jhipster-dependencies.version&amp;gt;&lt;/span&gt;8.2.0&lt;span class="nt"&gt;&amp;lt;/jhipster-dependencies.version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/properties&amp;gt;&lt;/span&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;tech.jhipster&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;jhipster-dependencies&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;${jhipster-dependencies.version}&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;Como podemos ver na seção seguinte, &lt;code&gt;&amp;lt;dependencies&amp;gt;&lt;/code&gt;, temos mais uma grande quantidade de dependências onde boa parte não tem especificada a versão pois isso já está estabelecido pela &lt;code&gt;jhipster-dependencies&lt;/code&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;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;tech.jhipster&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;jhipster-framework&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;org.springframework.boot&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;spring-boot-starter-actuator&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;Também temos a seção &lt;code&gt;&amp;lt;build&amp;gt;&lt;/code&gt;, onde temos a definição do &lt;code&gt;defaultGoal&lt;/code&gt;do Maven como &lt;code&gt;spring-boot:run&lt;/code&gt;,  a declaração e configuração de diversos plugins do Maven, tais como, plugin de compilação, testes unitários e de integração, Sonar, Liquibase e muitos outros.&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;build&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;defaultGoal&amp;gt;&lt;/span&gt;spring-boot:run&lt;span class="nt"&gt;&amp;lt;/defaultGoal&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;plugin&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&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;spring-boot-maven-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&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-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;${maven-surefire-plugin.version}&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="c"&gt;&amp;lt;!-- Force alphabetical order to have a reproducible build --&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;runOrder&amp;gt;&lt;/span&gt;alphabetical&lt;span class="nt"&gt;&amp;lt;/runOrder&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;excludes&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;exclude&amp;gt;&lt;/span&gt;**/*IT*&lt;span class="nt"&gt;&amp;lt;/exclude&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;exclude&amp;gt;&lt;/span&gt;**/*IntTest*&lt;span class="nt"&gt;&amp;lt;/exclude&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;/excludes&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;systemPropertyVariables&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;java.util.logging.config.file&amp;gt;&lt;/span&gt;src/test/resources/logback.xml&lt;span class="nt"&gt;&amp;lt;/java.util.logging.config.file&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;/systemPropertyVariables&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  package.json
&lt;/h2&gt;

&lt;p&gt;Quem já desenvolveu um simple “Hello World” em Node.js já conhece este arquivo. Ele contém a lista de dependências do frontend da nossa aplicação, tanto em tempo de produção quando de desenvolvimento.&lt;/p&gt;

&lt;p&gt;Logo no início do arquivo encontramos a identificação da nossa aplicação.&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"minha-aplicacao-monolitica"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.0.1-SNAPSHOT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"private"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Description for Minha Aplicacao Monolitica"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"license"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"UNLICENSED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Também encontraremos um conjunto de scripts que facilitam a vida do desenvolvedor. Para disparar os scripts, basta que o desenvolvedor execute o comando &lt;code&gt;npm run &amp;lt;nome do script&amp;gt;&lt;/code&gt;.&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="nl"&gt;"scripts"&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;"app:start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./mvnw"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"app:up"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"docker compose -f src/main/docker/app.yml up --wait"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"backend:build-cache"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./mvnw dependency:go-offline -ntp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"backend:debug"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./mvnw -Dspring-boot.run.jvmArguments=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&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;"backend:doc:test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./mvnw -ntp javadoc:javadoc --batch-mode"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"backend:info"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./mvnw -ntp enforcer:display-info --batch-mode"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"backend:nohttp:test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./mvnw -ntp checkstyle:check --batch-mode"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"backend:start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./mvnw -Dskip.installnodenpm -Dskip.npm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"backend:unit:test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./mvnw -ntp -Dskip.installnodenpm -Dskip.npm verify --batch-mode -Dlogging.level.ROOT=OFF -Dlogging.level.tech.jhipster=OFF -Dlogging.level.br.com.meucodigoagil.minhapp=OFF -Dlogging.level.org.springframework=OFF -Dlogging.level.org.springframework.web=OFF -Dlogging.level.org.springframework.security=OFF"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run webapp:prod --"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"webapp:build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run clean-www &amp;amp;&amp;amp; npm run webapp:build:dev"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"webapp:build:dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ng build --configuration development"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"webapp:build:prod"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ng build --configuration production"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"webapp:dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ng serve"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"webapp:dev-ssl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ng serve --ssl"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"webapp:dev-verbose"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ng serve --verbose"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prewebapp:instrumenter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run clean-www &amp;amp;&amp;amp; npm run clean-coverage"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"webapp:instrumenter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ng build --configuration instrumenter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"webapp:prod"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run clean-www &amp;amp;&amp;amp; npm run webapp:build:prod"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"webapp:test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run test --"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por fim, temos as dependências onde podemos notar claramente que nosso frontend se baseia no Angular 17.3.0.&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="nl"&gt;"dependencies"&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;"@angular/common"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"17.3.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@angular/compiler"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"17.3.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@angular/core"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"17.3.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@angular/forms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"17.3.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@angular/localize"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"17.3.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@angular/platform-browser"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"17.3.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@angular/platform-browser-dynamic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"17.3.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@angular/router"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"17.3.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@fortawesome/angular-fontawesome"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.14.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@fortawesome/fontawesome-svg-core"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"6.5.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@fortawesome/free-solid-svg-icons"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"6.5.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@ng-bootstrap/ng-bootstrap"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"16.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  angular.json
&lt;/h2&gt;

&lt;p&gt;Neste arquivo encontramos configurações do framework Angular, como a especificação do diretório raiz dos arquivos fonte Angular, o diretório onde estão armazenados assets (imagens, arquivos de estilo etc), configurações de build etc.&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;"$schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./node_modules/@angular/cli/lib/config/schema.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"newProjectRoot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"projects"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"projects"&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;"minha-aplicacao-monolitica"&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;"projectType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"application"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"schematics"&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="err"&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;"root"&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="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"sourceRoot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"src/main/webapp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jhi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"architect"&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;"build"&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;"builder"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@angular-builders/custom-webpack:browser"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"options"&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="err"&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;"outputPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"target/classes/static/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"src/main/webapp/index.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"src/main/webapp/main.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"polyfills"&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="s2"&gt;"zone.js"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"tsConfig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsconfig.app.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"inlineStyleLanguage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"scss"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"assets"&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="s2"&gt;"src/main/webapp/content"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="s2"&gt;"src/main/webapp/favicon.ico"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="s2"&gt;"src/main/webapp/manifest.webapp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="s2"&gt;"src/main/webapp/robots.txt"&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="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Vamos encerrando aqui a primeira parte da nossa análise do código da aplicação monolítica gerada pelo JHipster. Fizemos uma análise quantitativa dos arquivos gerados, exploramos a estrutura de diretórios e organização dos arquivos da aplicação e, por fim, mergulhamos nos principais arquivos de configuração da aplicação localizados no diretório raiz.&lt;/p&gt;

&lt;p&gt;Mas não acabou por aqui! Na próxima postagem, vamos nos aprofundar no código-fonte Java do backend da nossa aplicação. Fique ligado!&lt;/p&gt;

&lt;p&gt;Enquanto isso, faça você mesmo um mergulho solo nos elementos que exploramos neste post e mande suas dúvidas nos comentários ;)&lt;/p&gt;

</description>
      <category>jhipster</category>
      <category>java</category>
      <category>angular</category>
      <category>agile</category>
    </item>
    <item>
      <title>JHipster 8 - Criando uma aplicação monolítica</title>
      <dc:creator>Meu Código Ágil</dc:creator>
      <pubDate>Thu, 11 Apr 2024 15:33:00 +0000</pubDate>
      <link>https://dev.to/meucodigoagil/jhipster-8-criando-uma-aplicacao-monolitica-1gl</link>
      <guid>https://dev.to/meucodigoagil/jhipster-8-criando-uma-aplicacao-monolitica-1gl</guid>
      <description>&lt;p&gt;Se você chegou até aqui, é por que está interessado nas vantagens que a ferramenta JHipster pode trazer aos seus projetos de desenvolvimento de aplicações como, por exemplo, ganho de produtividade, utilização de tecnologias modernas, robustez, desempenho e boas práticas de mercado. Mas caso você tenha caído de paraquedas neste conteúdo, talvez queira dar uma conferida neste outro artigo onde apresento a ferramenta e detalho melhor essas vantagens: &lt;a href="https://dev.to/meucodigoagil/introducao-ao-jhipster-4hcb"&gt;Introdução ao JHipster&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Dando início à nossa jornada, vale lembrar que para percorrê-la você vai precisar do &lt;a href="https://adoptium.net/temurin/releases/?version=17"&gt;Java 17&lt;/a&gt; e do &lt;a href="https://nodejs.org/download/release/v18.19.1/"&gt;Node.js 18&lt;/a&gt; ou versões mais recentes destes, além, claro, do próprio JHipster. Como utilizaremos o utilitário &lt;a href="https://maven.apache.org/"&gt;Maven&lt;/a&gt;, sua instalação também será necessária.&lt;/p&gt;

&lt;h1&gt;
  
  
  Informações sobre o ambiente
&lt;/h1&gt;

&lt;p&gt;Este tutorial foi realizado em um Ubuntu 22.04.1 executando dentro do WSL em um host com Windows 11. As linhas de comando apresentadas são compatível com o Zsh (Z shell). Abaixo um quadro com a configuração utilizada para criar e executar o presente tutorial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open JDK: 21.0.2 2024–01–16&lt;/li&gt;
&lt;li&gt;Maven: 3.9.6&lt;/li&gt;
&lt;li&gt;Node.js: 20.11.1&lt;/li&gt;
&lt;li&gt;npm: 10.2.4&lt;/li&gt;
&lt;li&gt;JHipster (generator-jhipster): 8.2.1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;IMPORTANTE:&lt;/strong&gt; caso ao executar o comando “jhipster” no terminal ele não seja reconhecido, confirme que o path “/bin/” esteja na sua variável de ambiente PATH. Para obter o HOME_NODE, execute o comando a seguir:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm config get prefix
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Iniciando a saga
&lt;/h1&gt;

&lt;p&gt;O primeiro passo é criar um diretório onde será gerado o código da nossa aplicação e mover-se para dentro deste diretório:&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="nb"&gt;mkdir &lt;/span&gt;minha-aplicacao-monolitica
&lt;span class="nb"&gt;cd &lt;/span&gt;minha-aplicacao-monolitica
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Já dentro do diretório da futura aplicação, executamos o JHipster para iniciar a brincadeira:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Conforme é possível ver no  print logo a seguir, o JHipster exibirá uma sequência de prompts para o desenvolvedor responder. O primeiro deles é o nome da aplicação que, se não informado, usará uma variante do nome da pasta como resposta padrão. Em seguida, pede para o desenvolvedor selecionar um de três tipos de aplicação oferecidos pela ferramenta:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monolithic application&lt;/li&gt;
&lt;li&gt;Gateway application&lt;/li&gt;
&lt;li&gt;Microservice application&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para o propósito deste artigo, onde estamos criando uma aplicação simples, selecionaremos a primeira opção: Monolithic application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkmgyqavjm32dzdjntits.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkmgyqavjm32dzdjntits.png" alt="JHipster CLI — Seleção do tipo de aplicação" width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Moldando o backend
&lt;/h2&gt;

&lt;p&gt;A partir deste ponto, o desenvolvedor será questionado sobre um conjunto de opções de configuração voltadas para o backend da sua aplicação. A primeira delas é se o desenvolvedor quer utilizar outros frameworks de teste para a aplicação além do JUnit. Aqui poderíamos selecionar &lt;a href="https://gatling.io/"&gt;Gatling&lt;/a&gt;, &lt;a href="https://cucumber.io/"&gt;Cucumber&lt;/a&gt; ou mesmo ambos. Para o nosso primeiro tutorial, vamos dispensar esses frameworks adicionais.&lt;/p&gt;

&lt;p&gt;Na sequência, questiona se quer utilizar o framework Spring Webflux para tornar a aplicação reativa. Para este tutorial, vamos recusar e, assim, nossa aplicação utilizará o Spring MVC.&lt;/p&gt;

&lt;p&gt;Ele pergunta então qual o nome padrão do pacote Java, vamos de: &lt;code&gt;br.com.meucodigoagil.minhapp&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A seguir, ele pede para o desenvolvedor selecionar o tipo de autenticação que a aplicação deverá utilizar dando três opções:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JWT authentication (stateless)&lt;/li&gt;
&lt;li&gt;OAuth 2.0 / OIDC Authentication (stateful)&lt;/li&gt;
&lt;li&gt;HTTP Session Authentication (stateful)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ficamos com a primeira opção.&lt;/p&gt;

&lt;p&gt;Então ele questiona sobre o tipo de banco de dados que a aplicação utilizará, tendo como opções SQL, algumas opções NoSQL e até mesmo a opção da aplicação não utilizar banco de dados:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQL (H2, PostgreSQL, MySQL, MariaDB, Oracle, MSSQL)&lt;/li&gt;
&lt;li&gt;MongoDB&lt;/li&gt;
&lt;li&gt;Cassandra&lt;/li&gt;
&lt;li&gt;Couchbase&lt;/li&gt;
&lt;li&gt;Neo4j&lt;/li&gt;
&lt;li&gt;No database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Após selecionar o tipo SQL, que é o que queremos para este tutorial, ele questionará qual banco SQL será utilizado em produção e, logo em seguida, pergunta se utilizaremos o mesmo banco em desenvolvimento ou se selecionaremos um banco de dados H2 com persistência em disco ou em memória. Selecionamos PostgreSQL e H2 com persistência em disco.&lt;/p&gt;

&lt;p&gt;Na sequência, devemos selecionar uma das opções de cache suportadas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ehcache&lt;/li&gt;
&lt;li&gt;Caffeine&lt;/li&gt;
&lt;li&gt;Hazelcast&lt;/li&gt;
&lt;li&gt;Infinispan&lt;/li&gt;
&lt;li&gt;Memcached&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;li&gt;No cache&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para nosso tutorial, a primeira opção, Ehcache, nos atende. Logo a seguir, o JHipster questiona se queremos utilizar cache de segundo nível do Hibernate. Ficaremos com a reposta default: “Y” (sim).&lt;/p&gt;

&lt;p&gt;A seguir podemos escolher entre Maven e Gradle como a ferramenta de build para o backend deste projeto. Selecionamos Maven.&lt;/p&gt;

&lt;p&gt;Então, o JHipster nos oferece um cardápio de diversas outras tecnologias que queiramos acrescentar ao projeto:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Elasticsearch&lt;/li&gt;
&lt;li&gt;WebSockets&lt;/li&gt;
&lt;li&gt;Apache Kafka&lt;/li&gt;
&lt;li&gt;Apache Pulsar&lt;/li&gt;
&lt;li&gt;API first development using OpenAPI-generator&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Por ora, vamos manter a simplicidade do nossa aplicação e não marcaremos nenhuma opção.&lt;/p&gt;

&lt;p&gt;A seguir uma imagem resumindo tudo que definimos até aqui e que será utilizado para geração do backend da nossa aplicação.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgljbrl2sfidb4krrkaxm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgljbrl2sfidb4krrkaxm.png" alt="JHipster CLI — Prompts e respostas da configuração do backend" width="800" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Moldando o frontend
&lt;/h2&gt;

&lt;p&gt;Enfim, o CLI do JHipster começa a fazer questionamentos sobre o frontend da nossa aplicação. Começando por pedir que se escolha uma das opções de frontend possíveis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Angular&lt;/li&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Vue&lt;/li&gt;
&lt;li&gt;No client&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Das quais selecionaremos o Angular.&lt;/p&gt;

&lt;p&gt;De forma semelhante ao que fez em relação ao backend, o JHipster também questionará se será utilizado um framework de testes adicional para o frontend, além do padrão Jest/Vitest. Para este caso, temos como opção a inclusão do &lt;a href="https://www.cypress.io/"&gt;Cypress&lt;/a&gt;. Vamos marcá-lo!&lt;/p&gt;

&lt;p&gt;A seguir, será questionado se deve ser gerada ou não uma UI para administração da aplicação. Marcamos: “Y” (sim).&lt;/p&gt;

&lt;p&gt;Na sequência, o JHipster lista um conjunto de temas &lt;a href="https://bootswatch.com/"&gt;Bootswatch&lt;/a&gt; para seleção. Deixamos marcada a opção padrão “Default JHipster”.&lt;/p&gt;

&lt;p&gt;Quase perto do fim, temos a opção de internacionalizar nossa aplicação, selecionar o idioma nativo e os idiomas adicionais que serão suportados. Respondemos respectivamente: “Y” (sim), “Portuguese (Brazilian)” e “English”.&lt;/p&gt;

&lt;p&gt;Finalmente, ele questiona se gostaríamos de utilizar uma funcionalidade experimental de cobertura de código para os testes do Cypress e, em seguida, se queremos auditar os testes Cypress. Respondemos “Y” (sim) para ambos.&lt;/p&gt;

&lt;p&gt;No próximo print podemos visualizar todas as definições relacionadas ao frontend da nossa aplicação.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm65n3kugiycz86dr15w7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm65n3kugiycz86dr15w7.png" alt="JHipster CLI — Prompts e respostas da configuração do frontend" width="800" height="143"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pronto! Após responder a última pergunta, a mágica começa! Pode demorar alguns bons minutos dependendo da configuração da máquina sendo utilizada e da conexão com a internet.&lt;/p&gt;

&lt;p&gt;Enquanto o JHipster trabalha duro nos bastidores, serão geradas várias mensagens de log no console. Ao final, se tudo correu bem, você deve visualizar mensagens semelhantes às da imagem a seguir.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5vz194byfkm4k8mv2j2y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5vz194byfkm4k8mv2j2y.png" alt="JHipster CLI — Mensagem conclusão" width="800" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Primeiros resultados
&lt;/h1&gt;

&lt;p&gt;Finalmente, vamos ver o que o JHipster construiu pra nós. Para isso, vamos compilar a aplicação e executá-la para ver o que temos sob o ponto de vista do usuário. Para tal, basta executar o comando abaixo no diretório raiz da nossa aplicação recém nascida:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./mvnw
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na primeira vez, o Maven fará download das dependências para poder compilar o backend, o que pode demorar um pouco. Quando concluir todo o build e a aplicação for inicializada, você verá uma mensagem semelhante a esta no console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;----------------------------------------------------------
        Application 'minhaAplicacaoMonolitica' is running! Access URLs:
        Local:          http://localhost:8080/
        External:       http://127.0.1.1:8080/
        Profile(s):     [dev, api-docs]
----------------------------------------------------------
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A partir de agora você poderá utilizar o seu navegador para acessar a URL apresentada na mensagem: &lt;a href="http://localhost:8080/"&gt;http://localhost:8080/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ao carregar, será possível visualizar a página inicial da aplicação com três menus na parte superior direita.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx36g1knq6626tjzmf3jp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx36g1knq6626tjzmf3jp.png" alt="UI aplicação — Home não autenticado" width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao acessar o menu “Conta” e a opção “Entrar”, um formulário de login será exibido e você poderá se autenticar utilizando o usuário “admin” e a senha também “admin”. Neste instante, mais dois menus são exibidos: “Entidades” e “Administração”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6q6u3sk9jnbhklvef0z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6q6u3sk9jnbhklvef0z.png" alt="UI aplicação — Home autenticado como admin" width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No menu “Administração”, podemos acessar telas de papéis/roles (Authorities), gerenciamento de usuários, métricas da aplicação, estado do sistema, configurações de níveis de logging, documentação swagger das APIs etc.&lt;/p&gt;

&lt;p&gt;Contudo, você notará que se clicarmos no menu “Entidades”, nada acontece e nenhuma opção é exibida. Bem … você se lembra que passamos por uma variedade de perguntas, mas em nenhuma delas nós informamos quais seriam as entidades que nossa aplicação manteria. Pois chegou a hora!&lt;/p&gt;

&lt;h1&gt;
  
  
  Criando Entidade
&lt;/h1&gt;

&lt;p&gt;Criaremos neste tutorial nossa primeira entidade e, para isso, utilizaremos novamente o JHipster CLI. Mas antes precisamos definir que tipo de aplicação estamos criando … bem … que tal fazermos uma aplicação para gerenciar investimentos, assim podemos cadastrar produtos de investimento, transações de compra e venda/resgate, proventos etc. Vamos nessa!&lt;/p&gt;

&lt;p&gt;Para criar uma entidade basta executar o comando "entity" do JHipster CLI informando seu nome. O nome da nossa primeira entidade será "produto":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jhipster entity produto
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A partir daí, seremos questionados sobre a entidade Produto que estamos criando, começando pela pergunta se queremos adicionar um campo a nossa nova entidade, que respondemos com "Y" (sim).&lt;/p&gt;

&lt;p&gt;Em seguida, informamos qual seria o nome deste campo. Talvez, a primeira opção que veio à sua mente foi um campo identificador da entidade, mas este campo não é necessário pois ele já faz parte de uma entidade criada pelo JHipster. Assim, vamos responder com: “nome” e, para o tipo, “String”.&lt;/p&gt;

&lt;p&gt;A seguir, o JHipster pergunta se queremos incluir alguma regra de validação para o nosso campo “nome”, que responderemos com “Y” (sim). Entre as opções de validação oferecidas para um campo String temos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Required (campo obrigatório)&lt;/li&gt;
&lt;li&gt;Unique (campo de valores únicos na tabela)&lt;/li&gt;
&lt;li&gt;Minimum length (número mínimo de caracteres para os valores)&lt;/li&gt;
&lt;li&gt;Maximum length (número máximo de caracteres para os valores)&lt;/li&gt;
&lt;li&gt;Regular expression pattern (expressão regular)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Podemos marcar múltiplos ou nenhuma. Marcaremos “Required”, “Unique”, “Minimum length” e “Maximum length” e, na sequência, informaremos que o tamanho mínimo são 3 caracteres e o tamanho máximo são 100. Os prompts e respostas do nosso primeiro campo podem ser visualizados na imagem a seguir.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffnp1tzxnv0gey73dngpw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffnp1tzxnv0gey73dngpw.png" alt="JHipster CLI — Prompts e respostas da criação do campo “nome” da entidade “produto”" width="766" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O JHipster repetirá então a primeira pergunta que ele fez logo no início, se gostaríamos de adicionar mais um campo à nossa entidade. Vamos responder “Y” (sim) e desta vez daremos o nome “tipo” e selecionaremos o tipo “Enumeration (Java enum type)”. Então, informamos o nome da classe do nosso enumerador como “TipoProduto” e, em seguida, informamos os valores possíveis separados por vírgulas e sem espaços: “Tesouro,CDB,Fundo,CRI,CRA,Debenture,Acao,FII,ETF,BDR,PGBL”.&lt;/p&gt;

&lt;p&gt;Novamente, adicionaremos regras de validação ao nosso novo campo que, no caso de “Enumeration”, possui apenas as opções:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Required&lt;/li&gt;
&lt;li&gt;Unique&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Marcaremos apenas “Required” e, a fim de simplificarmos e agilizarmos a conclusão da nossa primeira aplicação, encerraremos aqui nossa primeira entidade informando ao JHipster que não adicionaremos mais campos.&lt;/p&gt;

&lt;p&gt;Na sequência, o JHipster questiona se queremos usar uma classe de serviço separada para a lógica de negócio e são oferecidas as seguintes opções:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No, the REST controller should use the repository directly&lt;/li&gt;
&lt;li&gt;Yes, generate a separate service class&lt;/li&gt;
&lt;li&gt;Yes, generate a separate service interface and implementation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se selecionarmos a primeira opção, o controller do nosso Spring MVC chamará de forma direta os métodos da classe de dados anotada com &lt;code&gt;@Repository&lt;/code&gt;. Como o propósito da nossa primeira aplicação é manter a simplicidade, ficaremos com a primeira opção por enquanto. Então, o JHipster CLI questiona se nossa entidade é somente leitura e respondemos com “N” (não).&lt;/p&gt;

&lt;p&gt;Na sequência, seremos questionados se desejamos que nossa entidade tenha funcionalidade de paginação e ordenação de dados e temos as opções:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No&lt;/li&gt;
&lt;li&gt;Yes, with pagination links and sorting headers&lt;/li&gt;
&lt;li&gt;Yes, with infinite scroll and sorting headers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vamos mais uma vez optar pela simplicidade na nossa primeira aplicação: “N” (não) e o JHIpster começará a trabalhar para atender nosso pedido com as especificações que passamos ao longo dos prompts.&lt;/p&gt;

&lt;p&gt;Durante a execução, o JHipster irá gerar novamente mais uma grande quantidade de mensagens de log no console e, em algumas delas, ele reportará conflito ao escrever alguns arquivos. Para esses, devemos responder se desejamos sobrescrever a versão anterior daquele arquivo. Vamos responder “a” (sobrescrever todas).&lt;/p&gt;

&lt;h3&gt;
  
  
  Resultado final
&lt;/h3&gt;

&lt;p&gt;Quando o JHipster concluir seu trabalho, você poderá inicializar novamente a aplicação executado o comando abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./mvnw
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao se autenticar com o usuário “admin” (senha “admin”), você perceberá que o menu “Entidades” agora possui uma opção “Produto”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F77cmj8dhrfoc7fos26eg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F77cmj8dhrfoc7fos26eg.png" alt="UI aplicação — Menu Entidades" width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao clicar em "Produto", será exibida uma lista de produtos com dados sintéticos. Nesta nova tela, você poderá realizar as operações de CRUD na entidade produto: cadastrar, visualizar, atualizar e excluir.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx39eqk7qedek26zm5pjg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx39eqk7qedek26zm5pjg.png" alt="UI aplicação  — Tela de Produtos" width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enfim, chegamos ao final do nosso primeiro tutorial que, diga-se de passagem, produziu uma aplicação bastante simples é verdade. Mas o propósito aqui foi apenas introduzir ainda de forma bem superficial o JHipster.&lt;/p&gt;

&lt;p&gt;Brinque à vontade com a sua mais nova aplicação gerada com o menor esforço. Experimente cada uma das funcionalidades! Tente cadastrar ou alterar um produto de investimento que tenha menos de 3 ou mais de 100 caracteres.&lt;/p&gt;

&lt;p&gt;Continue me acompanhando por aqui pois farei novas publicações a fim de aprofundarmos cada vez mais e, assim, explorarmos todo o potencial desta ferramenta.&lt;/p&gt;

</description>
      <category>jhipster</category>
      <category>java</category>
      <category>angular</category>
      <category>agile</category>
    </item>
    <item>
      <title>Agile: sem as ferramentas certas, é só mais uma forma desorganizada de produzir software</title>
      <dc:creator>Meu Código Ágil</dc:creator>
      <pubDate>Wed, 27 Mar 2024 12:10:58 +0000</pubDate>
      <link>https://dev.to/meucodigoagil/agile-sem-as-ferramentas-certas-e-so-mais-uma-forma-desorganizada-de-produzir-software-35ii</link>
      <guid>https://dev.to/meucodigoagil/agile-sem-as-ferramentas-certas-e-so-mais-uma-forma-desorganizada-de-produzir-software-35ii</guid>
      <description>&lt;p&gt;Olá, Dev/Agilista! Começo pedindo que não dê muita bola para o título desse post, ele é mais uma provocação do que uma verdade em sua totalidade :)&lt;/p&gt;

&lt;p&gt;Sabemos que as metodologias e práticas ágeis, especialmente quando bem aplicadas, trazem contribuições significativas para os projetos e as organizações como um todo. Principalmente, quando comparamos com as alternativas mais burocráticas, seus predecessores. Quando temos um time maduro, que foi além das técnicas e das cerimônias, e incorporou a mentalidade ágil, essa diferença é absolutamente gritante. Na verdade, podemos dizer que é incomparável.&lt;/p&gt;

&lt;p&gt;As metodologias ágeis estão conosco há vários anos, a publicação do famoso &lt;a href="https://agilemanifesto.org/"&gt;Manifesto Ágil&lt;/a&gt;, realizada em 2001, já ultrapassou suas duas décadas. Ao longo deste tempo, é quase impossível que durante sua carreira você não tenha atuado em ao menos um projeto onde se tenha adotado (ou tentado adotar) alguma metodologia ágil.&lt;/p&gt;

&lt;p&gt;Da mesma forma, baseado na minha própria vivência, acredito que seja também improvável que em ao menos uma dessas experiências as coisas não tenham saído como esperado. Mesmo observando de forma bastante disciplinada todos os ritos e cerimônias, elas não garantem o sucesso de um projeto de desenvolvimento. Como já citamos anteriormente e voltamos a repetir, as metodologias ágeis entregam seu valor máximo não com a mera adoção de técnicas e cerimônias, mas quando a mentalidade do time é convertida para uma cultura ágil.&lt;/p&gt;

&lt;p&gt;Contudo, meu ponto é que isso não cobre tudo. Existe uma questão fundamental em projetos de software que não pode ser superada apenas com técnicas, processos ágeis ou mentalidade: a técnica de produzir código de programação, código com qualidade. E já que estamos falando de agilidade, de aproveitar as janelas do mercado, temos que admitir que essa produção de software com qualidade não pode demorar o tempo que Michelangelo levou para pintar a abóboda da Capela Sistina.&lt;/p&gt;

&lt;p&gt;Ainda que o time siga de forma disciplinada o beabá do SCRUM ou qualquer adaptação mais elaborada, abrace e se adapte às mudanças, faça entregas contínuas e frequentes, que o Dono do Produto esteja presente, especifique e priorize bem seu backlog, se o time de desenvolvimento não for capaz de codificar rapidamente e, claro, sem bugs que impeçam a publicação do software em ambiente produtivo, haverá uma lacuna importante que frustará as ambições agilistas e, em última instância, da direção e dos clientes da organização.&lt;/p&gt;

&lt;p&gt;Talvez por isso as plataformas No-Code e Low-Code tenham ganhado holofotes nos últimos anos. Elas oferecem um ambiente onde o time pode produzir telas com lógica de negócio incorporada de forma rápida, em um ambiente controlado onde, supostamente, não haverá grandes riscos técnicos. Não há dúvidas que essas ferramentas estão entregando valor e contribuindo para os projetos avançarem, mas elas não são balas de prata (nenhuma é, certo?). Ao mesmo tempo que este ambiente controlado mitiga riscos técnicos, pois as peças deste “Lego” já estão definidas, ele também pode limitar ou impedir soluções mais criativas. E não vamos nem entrar em questões como vendor lock-in.&lt;/p&gt;

&lt;p&gt;Antes de seguir, vou enfatizar: é indiscutível que essas plataformas No-Code e Low-Code têm contribuído significativamente para o avanço de inúmeros projetos ao redor do mundo e seu sucesso não é em vão, têm entregado valor, o software tem chegado em produção e os objetivos de negócio têm sido alcançados.&lt;/p&gt;

&lt;p&gt;Entretanto, em muitos projetos essa estratégia não será a mais adequada. Nós precisaremos do bom e velho “High Code”, e precisaremos produzir rápido para aproveitar as janelas de oportunidade. Sabidamente, não bastará simplesmente produzir volumes monstruosos de código em espaço de tempo reduzido, é essencial que esse código produzido tenha qualidade. Do contrário, isso levará a débitos técnicos, retrabalho, impacto no tempo de entrega, perda de oportunidades de mercado, prejuízos …&lt;/p&gt;

&lt;p&gt;A proposta deste post é introduzir uma série de outros posts onde iremos explorar uma ferramenta já experimentada no mercado que se propõe a automatizar a produção de software com qualidade, software com conceitos modernos, seguindo as melhores práticas de mercado, construído sobre os melhores e mais difundidos frameworks, bibliotecas e ferramentas de mercado: o JHipster.&lt;/p&gt;

&lt;p&gt;Temos a ousada pretensão de ajudar tornar realidade os sonhos e promessas dos agilistas :)&lt;/p&gt;

&lt;p&gt;Aqui está a lista de links para a série de posts desta jornada que pretendemos incrementar ao longo do tempo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/meucodigoagil/introducao-ao-jhipster-4hcb"&gt;Introdução ao JHipster&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/meucodigoagil/jhipster-8-criando-uma-aplicacao-monolitica-1gl"&gt;JHipster 8 - Criando uma aplicação monolítica&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/meucodigoagil/jhipster-8-analisando-o-codigo-da-nossa-primeira-aplicacao-monolitica-parte-13-2380"&gt;JHipster 8 - Analisando o código da nossa primeira aplicação monolítica - Parte 1/3&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/meucodigoagil/jhipster-8-analisando-o-codigo-da-nossa-primeira-aplicacao-monolitica-parte-23-2kan"&gt;JHipster 8 - Analisando o código da nossa primeira aplicação monolítica - Parte 2/3&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Introdução ao JHipster</title>
      <dc:creator>Meu Código Ágil</dc:creator>
      <pubDate>Thu, 14 Mar 2024 19:03:11 +0000</pubDate>
      <link>https://dev.to/meucodigoagil/introducao-ao-jhipster-4hcb</link>
      <guid>https://dev.to/meucodigoagil/introducao-ao-jhipster-4hcb</guid>
      <description>&lt;p&gt;Olá, dev! Se você está começando sua jornada no mundo do desenvolvimento de software ou se, mesmo com anos de experiência na produção de software, procura uma ferramenta que possa impulsionar sua produtividade e expandir seu conhecimento em tecnologias mais modernas, você precisa conhecer o JHipster.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrdc9i7uyr0b6opaa969.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrdc9i7uyr0b6opaa969.png" alt="Image description" width="408" height="96"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é JHipster?
&lt;/h2&gt;

&lt;p&gt;O JHipster é um gerador de código de alto nível que combina uma lista extensa de ferramentas e plataformas de desenvolvimento de ponta. Ele é construído sobre uma outra ferramenta de geração decódigo, o Yeoman. As aplicações geradas pelo JHipster têm seu backend baseado no framework Spring e, para seu frontend, o desenvolvedor pode escolher entre os frameworks Angular ou Vue ou a biblioteca React. Com o JHipster, você pode criar um projeto web Java completo, com uma interface amigável e reponsiva, API REST documentada, cobertura de testes abrangente, segurança básica e integração com banco de dados relacionais ou NoSQL e sistemas de messageria como Kafka ou Pulsar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Por que usar JHipster?
&lt;/h2&gt;

&lt;p&gt;Aqui estão algumas razões pelas quais o JHipster pode ser a ferramenta ideal para você:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Produtividade:&lt;/strong&gt; com apenas alguns comandos, você pode gerar uma aplicação web ou microserviço totalmente operacional. As aplicações geradas estão configuradas com as ferramentas de desenvolvimento mais apropriadas no ciclo de vida do desenvolvimento, tais como Maven, Gradle, npm, Liquibase etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tecnologias modernas:&lt;/strong&gt; utilização de tecnologias modernas que são demandadas no mercado atual. Aplicações conteinerizadas, com recursos de cache, pooling de conexões para otimização de desempenho, gerenciamento de log, monitoramento da aplicação em tempo de execução e suporte aos principais provedores de nuvem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Robustez e desempenho:&lt;/strong&gt; aplicações robustas, de alto desempenho e escaláveis, capazes de suportar grande número de usuários concorrentes .No frontend, fragmentos das páginas são atualizados de forma dinâmica fazendo com que os usuários da aplicação não precisem esperar pela carga completa de páginas. O backend gerado se baseia nas tecnologias mais recentes de cache e acesso a dados, tendo segurança e desempenho como foco.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Personalização:&lt;/strong&gt; escolha entre uma variedade de opções para personalizar sua aplicação durante a geração do projeto. O desenvolvedor pode escolher, por exemplo, entre uma aplicação monolítica ou um conjunto de microserviços; qual a biblioteca de cache a ser utilizada pela aplicação e até mesmo se a aplicação suportará internacionalização e quais idiomas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Boas Práticas:&lt;/strong&gt; o código gerado segue as melhores práticas da indústria, adota padrões como IoC¹, AOP² e abstrações para facilitar a codificação, além de ser bem comentado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comunidade:&lt;/strong&gt; Uma comunidade ativa e uma ampla documentação estão disponíveis para ajudá-lo a resolver problemas e expandir suas habilidades.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup da estação de desenvolvimento
&lt;/h2&gt;

&lt;p&gt;Antes de começar a utilizar o JHipster para desenvolver sua próxima aplicação, você precisará fazer o setup do ambiente de desenvolvimento instalando pré-requisitos para o funcionamento do JHipster:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Java³&lt;/li&gt;
&lt;li&gt;Node.js⁴&lt;/li&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instaladas estas ferramentas de desenvolvimento, você deverá instalar o JHipster de forma global, o que pode ser feito via linha de comando utilizando o gerenciador de pacotes NPM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; generator-jhipster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Primeiros Passos com JHipster
&lt;/h2&gt;

&lt;p&gt;Uma vez que as dependências e o próprio JHipster estão devidamente instalados, criar um novo projeto é um processo guiado por um assistente de linha de comando que levará o desenvolvedor através de várias opções para configurar sua aplicação conforme ilustrado na imagem a seguir.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7s8v2kd9kla4faoofjkz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7s8v2kd9kla4faoofjkz.png" alt="Image description" width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dentre várias opções, o desenvolvedor poderá escolher entre criar uma aplicação monolítica ou um conjunto de microserviços, dependendo das necessidades do seu projeto.&lt;/p&gt;

&lt;p&gt;Um tutorial detalhado para a geração de uma aplicação utilizando o JHipster 8 será publicado em um próximo post neste mesmo canal.&lt;/p&gt;

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

&lt;p&gt;O JHipster é uma excelente escolha para o desenvolvedor que queira se familiarizar com as tecnologias usadas em aplicações corporativas modernas. Ele não só ajuda a acelerar o processo de desenvolvimento, mas também serve como uma ferramenta de aprendizado valiosa.&lt;/p&gt;

&lt;p&gt;Experimente o JHipster hoje mesmo e dê um grande passo na sua carreira de desenvolvedor! Siga-me e seja notificado sempre que tiver conteúdo novo por aqui 😉&lt;/p&gt;





&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Inversion of Control: princípio de desenvolvimento de software onde o fluxo de controle é invertido. Em vez de um programa ditar o que as classes ou objetos devem fazer, o framework ou container é quem decide. Isso ajuda a criar sistemas mais modulares, extensíveis e fáceis de manter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Aspect-Oriented Programming: técnica de programação que visa melhorar a modularidade do código separando preocupações transversais.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Para utilizar o JHipster 8, última versão do JHipster na data da publicação deste post, você precisará instalar o Java v17 ou mais recente, um pré-requisito do Spring Boot 3.2.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Para utilizar o JHipster 8, você precisará instalar o Node.js v18 ou mais recente&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>jhipster</category>
      <category>java</category>
      <category>agile</category>
    </item>
  </channel>
</rss>
