Aplicação completa usando um front moderno e uma plataforma de back poderosa, irei explanar tudo sobre “como” implementei, com mais volume no front (pois o back é simples).

O que a aplicação faz?

Existe um login, listagem de usuários existentes (gerados automaticamente), listagem de empresas, listagem de ciclos por empresas, inclusão de ciclos.

Front end — Angular 4, JWT, Typescript ebootstrap

Onde o front começa? App.router

Define oroteamento da aplicação que possui ‘login’ e ‘ciclos’ aos respectivos componentes.

Temos a implementação de uma url “protegida”, que será acessada somente com usuário logado, utilizo o conceito de AuthGuard.

{path: ‘ciclos’, component: CicloListComponent, canActivate: AuthGuard]}

Inicio da aplicação app.component.html

Este html será o primeiro executado pelo Angular, aqui na linha 19 estará a variação do Router (Classe interna do angular que é usada para fazermos a navegação)

<router-outlet></router-outlet>

Sendo assim, o router-outlet irá mostrar o componente de login, pois é a primeira url do sistema.

Funcionalidade de login

A dinâmica do login é comum, a diferença é que o backend gera um Json Web Token após validação de usuário e senha no H2.

O front armazena o token no , verifica se está válido e o logout remove. Estas são responsabilidades definidas no .

Para ver se o usuário está logado, uso a biblioteca do JwtHelper que valida otoken, já o logout simplesmente remove o item do local storage. Demonstração do AuthService.

isLogged() {
    const token = localStorage.getItem('token');
    if (token) {
        return new JwtHelper().isTokenExpired(token) == false;
    }
    return false;
}
logout() {
    localStorage.removeItem('token');
}

Após o login, o redirecionamento para a tela de ciclos é realizado, sendo que o AuthGuard irá ‘interceptar’ e validará que o token está válido.

this.router.navigate([‘ciclos’]);

Funcionalidade de listagem de ciclo

Tela principal com uma listagem de empresas, os ciclos da empresa selecionada e inclusão de um novo ciclo.

No Componente de listagem estão os requisições ao backend, que no Angular elas são assíncronas, usando o RxJS e o operador subscribe a atribuição as listas retornadas do backend seguem o mesmo padrão.

this.empresaService.getList()
    .subscribe( 
      data => this.empresas = data 
);

Entretanto, após a inclusão de um novo ciclo, um evento é enviado e o ouvinte é acionado, atualizando a tabela de ciclos.

listenerCicloListChanged() {     
    this.eventsService.ciclosEvent
        .subscribe( 
          (novoCiclo: Ciclo) => { 
             if (novoCiclo.codigo) {  
                  this.loadCiclosByEmpresa(
                     this.empresaSelecionada.codigoEmpresa); 
            }
        }); 
}

Funcionalidade de listagem de inclusão de ciclo

Na listagem de ciclo, a ação de inserir um novo ciclo é controlada pelo componente de listagem, sendo exibido em um modal, usando o conceito de property binding vistos nos dois trechos abaixo.

// Variável definida no typescript
@ViewChild('cicloSaveItem')    
private cicloSaveComponent: CicloSaveComponent;
// Componente definido no html

Na inclusão a principal funcionalidade é a gerência do modal através do typescript, repare o uso do jquery com os trechos abaixo:

declare var $: any;
// Elemento injetado pelo construtor
private rootNode: ElementRef
// Inicialização da variável referência do modal
this.saveModal = $(this.rootNode.nativeElement).find('#saveModal');
// Close modal
this.saveModal.modal('hide');

Back end — Java, Spring boot, Swagger e H2

O Backend está estruturado para na sua inicialização incluir empresas e usuários, toda persistência é realizada no h2.

Todos endpoints (API) recebem a request e devolve com Json. Sem guardar a sessão do usuário.

CQRS — Command Query Responsibility Segregation.

As services que terminam com CommandService (escrita) e QueryService (leitura) implementam o conceito acima.

JWT — Json Web token

JWT.create()
   .withClaim(“login”, user.getLogin())    
   .withExpiresAt(
       Timestamp.valueOf(LocalDateTime.now().plusMinutes(5)))
   .sign(Algorithm.HMAC256(user.getPassword()));

Banco de dados

O banco de dados usado nesta aplicação é o H2, a persistência é com hibernate gerenciado pelo spring data.

Docker Back

From centos

Run yum install -y java

VOLUME /tmp
ADD /target/vestibular-backend-1.0.0.jar vestibular-backend.jar
RUN sh -c 'touch /vestibular-backend.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/;/urandom","-jar","/vestibular-backend.jar"]

Docker Front — Nginx

Nginx faz o proxy da porta 80 para a aplicação, configurado aqui.

### STAGE 1: Build ###

# We label our stage as 'builder'
FROM node:9-alpine as builder

COPY package.json package-lock.json ./

RUN npm set progress=false && npm config set depth 0 && npm cache clean --force

## Storing node modules on a separate layer will prevent unnecessary npm installs at each build
RUN npm i && mkdir /ng-app && cp -R ./node_modules ./ng-app

WORKDIR /ng-app

COPY . .

## Build the angular app in production mode and store the artifacts in dist folder
RUN $(npm bin)/ng build --prod

### STAGE 2: Setup ###

FROM nginx:1.13.3-alpine

## Copy our default nginx config
COPY nginx/default.conf /etc/nginx/conf.d/

## Remove default nginx website
RUN rm -rf /usr/share/nginx/html/*

## From 'builder' stage copy over the artifacts in dist folder to default nginx public folder
COPY --from=builder /ng-app/dist /usr/share/nginx/html

CMD ["nginx", "-g", "daemon off;"]

User guide

BackEnd 
git clone https://github.com/lelodois/vest-backend.gitmvn install
docker build -t vestback-docker .
docker run -d -p 9099:9099 vestback-docker
Front
git clone https://github.com/lelodois/vest-frontend.gitsudo docker build -t vestfront-docker .
sudo docker run -d -p 80:80 vestfront-dockerUrl’s

Links e Referências

  1. [Aplicação] — http://localhost/login
  2. [Swagger] — http://localhost:9099/swagger-ui.html
  3. [Frontend] — https://github.com/lelodois/vest-frontend
  4. [Backend] — https://github.com/lelodois/vest-backend
  5. [Curso de angular] —  The-complete-angular-master-class
  6. [Curso de docker] — Docker-for-java-developers
  7. [JWT] — Json Web Token
  8. [Spring boot] — Spring boot documentation

Bem, tentei explanar os pontos que considero mais importantes do projeto, que está funcional e próximo de uma aplicação do mundo real.