🚀 Capítulo 20: Projeto Final Integrado

🎯 Objetivo da Aula

Ao final desta aula, você será capaz de construir uma API REST completa do zero, aplicando todos os conceitos aprendidos no curso: Orientação a Objetos, Banco de Dados, Padrão de Camadas e Regras de Negócio.


🏢 O Cenário Prático (Seu Desafio)

Você foi recrutado por Nick Fury para ser o engenheiro de software chefe da S.H.I.E.L.D.! O seu desafio final é criar o sistema de gerenciamento da Iniciativa Vingadores. Você deve construir uma API que permita cadastrar Heróis, gerenciar Missões e relacioná-los, garantindo que o código esteja organizado em camadas profissionais.


🧠 Fundamentos: A Teoria Traduzida

Este capítulo é a consolidação de tudo o que vimos ao longo das 20 semanas. Não há teoria nova, apenas a aplicação prática de:

  1. Spring Boot para subir o servidor web.
  2. Spring Data JPA para persistir os dados no banco H2 sem usar SQL manual.
  3. Camadas (Controller, Service, Repository) para organizar as responsabilidades.
  4. Relacionamentos (@ManyToOne) para ligar heróis a missões.

Arquitetura do Projeto Final

flowchart TD
    A["Cliente (Postman/Navegador)"] --> B["HeroiController"]
    B --> C["HeroiService"]
    C --> D["HeroiRepository"]
    D --> E[("Banco de Dados H2")]
    C --> F["Regra de Negócio: Validar Nível de Poder"]

📖 Exemplo Guiado

Vamos estruturar o projeto base da S.H.I.E.L.D.

🛠️ Passo a Passo para Criar o Projeto no VS Code

  1. Abra o VS Code.
  2. Pressione as teclas Ctrl + Shift + P.
  3. Digite Spring Initializr: Create Maven Project e pressione Enter.
  4. Selecione a versão estável do Spring Boot e a linguagem Java.
  5. Group ID: com.shield e Artifact ID: vingadores.
  6. Selecione a versão do Java instalada.
  7. Dependências: Adicione Spring Web, Spring Data JPA e H2 Database. Pressione Enter.
  8. Gere o projeto e abra no VS Code.

📂 Estrutura Inicial de Pastas

vingadores/
├── src/
│   └── main/
│       ├── java/
│       │   └── com/shield/vingadores/
│       │       └── VingadoresApplication.java
│       └── resources/
│           └── application.properties
└── pom.xml

Siga os passos para criar a base do sistema:

  1. Crie a entidade Heroi.java na pasta com/shield/vingadores/:
package com.shield.vingadores;
 
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
 
@Entity
public class Heroi {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String codinome;
    private String poder;
    private int nivelPoder; // De 1 a 5
 
    // Construtores
    public Heroi() {}
    public Heroi(String codinome, String poder, int nivelPoder) {
        this.codinome = codinome;
        this.poder = poder;
        this.nivelPoder = nivelPoder;
    }
 
    // Getters e Setters
    public Long getId() { return id; }
    public String getCodinome() { return codinome; }
    public String getPoder() { return poder; }
    public int getNivelPoder() { return nivelPoder; }
}
  1. Crie a interface HeroiRepository.java:
package com.shield.vingadores;
 
import org.springframework.data.jpa.repository.JpaRepository;
 
public interface HeroiRepository extends JpaRepository<Heroi, Long> {
}
  1. Crie a classe HeroiService.java com uma regra de segurança:
package com.shield.vingadores;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
 
@Service
public class HeroiService {
 
    @Autowired
    private HeroiRepository repository;
 
    public List<Heroi> listarTodos() {
        return repository.findAll();
    }
 
    public Heroi salvar(Heroi heroi) {
        // Regra de Negócio: O nível de poder deve ser entre 1 e 5
        if (heroi.getNivelPoder() < 1 || heroi.getNivelPoder() > 5) {
            throw new IllegalArgumentException("Nível de poder inválido! Deve ser entre 1 e 5.");
        }
        return repository.save(heroi);
    }
}

🕹️ Como Executar e Testar no VS Code

  1. Abra o arquivo VingadoresApplication.java.
  2. Clique em Run logo acima do método main.
  3. Como este passo foca na criação da estrutura (Model, Repository e Service), o teste completo com requisições Web será feito após você criar o Controller na Prática 1!

Resultado Esperado: O Spring Boot iniciará com sucesso e você verá no console que o banco de dados foi inicializado e a tabela HEROI foi criada.


🛠️ Prática Obrigatória 1

Crie a classe HeroiController.java com os métodos para Listar (GET) e Cadastrar (POST) heróis, chamando os métodos do HeroiService. Lembre-se de configurar o console do H2 no arquivo application.properties para testar!


🛠️ Prática Obrigatória 2

Crie uma nova entidade chamada Missao (com atributos id e descricao). Crie um relacionamento @ManyToOne na classe Heroi apontando para Missao (um herói pode ser enviado para uma missão). Atualize os controladores para permitir essa associação.


📤 Instruções de Entrega (GitHub Desktop + Microsoft Teams)

Neste curso, você entregará suas atividades enviando o código para o seu repositório no GitHub usando o aplicativo GitHub Desktop. Siga o passo a passo detalhado:

  1. Verifique a estrutura: Certifique-se de que sua estrutura de pastas final está idêntica à mostrada abaixo.
  2. Abra o GitHub Desktop: Certifique-se de que o repositório do seu curso está selecionado no canto superior esquerdo.
  3. Visualize as alterações: Na aba Changes (à esquerda), você verá todos os arquivos que criou ou modificou nesta aula.
  4. Faça o Commit:
    • No campo Summary (na parte inferior esquerda), digite uma mensagem curta descrevendo o que fez, ex: Finaliza atividades do Capítulo 20.
    • Clique no botão azul Commit to main (ou o nome da sua branch).
  5. Envie para a Nuvem (Push): No topo da tela, clique no botão Push origin. Isso enviará seu código do seu computador para o seu perfil no GitHub.
  6. ⚠️ IMPORTANTE (Repositório Público): Para que o professor consiga corrigir, o seu repositório no GitHub DEVE SER PÚBLICO. Repositórios privados não podem ser visualizados por quem não foi convidado.
  7. Como entregar no Microsoft Teams:
    • Copie o link do seu repositório no GitHub (ex: https://github.com/seu-usuario/seu-repositorio).
    • Abra a tarefa correspondente no Microsoft Teams.
    • Clique no botão Adicionar trabalho (ou Add work).
    • Selecione a opção Link no menu lateral.
    • Cole o link do GitHub no campo “Endereço Web” e digite um texto (ex: Meu Repositório) no campo “Texto a ser exibido”.
    • Clique em Anexar.
    • MUITO IMPORTANTE: Clique no botão Entregar (ou Turn in) no canto superior direito para concluir o envio!

📂 Estrutura Final de Pastas

vingadores/
├── src/
│   └── main/
│       ├── java/
│       │   └── com/shield/vingadores/
│       │       ├── VingadoresApplication.java
│       │       ├── Heroi.java
│       │       ├── Missao.java
│       │       ├── HeroiRepository.java
│       │       ├── MissaoRepository.java
│       │       ├── HeroiService.java
│       │       ├── HeroiController.java
│       │       └── MissaoController.java
│       └── resources/
│           └── application.properties
└── pom.xml

💡 Checkpoint de Lógica

Parabéns! Você concluiu o curso construindo uma aplicação completa, do banco de dados até a exposição na Web. Esse projeto serve como o seu primeiro grande portfólio para o mercado de trabalho. Você agora domina as bases do ecossistema Java e Spring Boot!


🔥 Desafio de Fixação (Opcional)

Pesquise como criar uma classe de teste unitário (usando o que aprendeu no Capítulo 12) para validar se a regra de negócio do HeroiService (nível de poder) está realmente bloqueando valores inválidos.


🔑 Gabarito de Código/Fórmulas

Prática 1:

@RestController
@RequestMapping("/herois")
public class HeroiController {
    @Autowired
    private HeroiService service;
 
    @GetMapping
    public List<Heroi> listar() { return service.listarTodos(); }
 
    @PostMapping
    public Heroi criar(@RequestBody Heroi h) { return service.salvar(h); }
}

Prática 2:

// Na classe Heroi:
@ManyToOne
@JoinColumn(name = "missao_id")
private Missao missao;

Desafio:

// Exemplo de teste unitário para o Service:
@Test
public void deveLancarExcecaoParaPoderInvalido() {
    Heroi h = new Heroi("Thor", "Deus do Trovão", 10); // Poder 10 é inválido
    assertThrows(IllegalArgumentException.class, () -> {
        service.salvar(h);
    });
}

Capitulo Anterior