Pular para o conteúdo principal

Quiz: Camada de Serviço e Arquitetura

Teste seus conhecimentos sobre a camada de serviço, validação e arquitetura MVC.

30 questões - Clique em cada pergunta para revelar a resposta.


Questões 1-10: Camada de Serviço​

Pergunta 1: Qual é o papel da camada Service na arquitetura MVC?

Resposta: A camada Service contém a lógica de negócio da aplicação. Ela:

  • Orquestra as operações entre controllers e repositories
  • Aplica as regras de negócio
  • Gerencia transações
  • É independente do protocolo HTTP

Pergunta 2: Qual anotação é usada para declarar um service no Spring?

Resposta: @Service - É um estereótipo especializado de @Component que indica que a classe contém lógica de negócio.

@Service
public class UserService {
// lógica de negócio
}

Pergunta 3: Por que não colocar a lógica de negócio no controller?

Resposta: Separar a lógica de negócio do controller permite:

  • Reutilização: o service pode ser chamado por vários controllers
  • Testabilidade: testar a lógica sem HTTP
  • Manutenibilidade: código mais organizado
  • Separação de responsabilidades: cada camada tem um papel definido

Pergunta 4: Como injetar um Repository em um Service?

Resposta: Por injeção via construtor (recomendado):

@Service
public class UserService {

private final UserRepository userRepository;

public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}

Pergunta 5: O que é um DTO (Data Transfer Object)?

Resposta: Um DTO é um objeto simples usado para transferir dados entre as camadas. Ele:

  • Não contém lógica de negócio
  • Expõe apenas os dados necessários
  • Protege a entidade JPA de exposição direta
  • Permite formatar os dados para a API

Pergunta 6: Por que usar DTOs em vez das entidades JPA diretamente?

Resposta:

  1. Segurança: não expor campos sensíveis (senha)
  2. Performance: evitar carregamento lazy de relações
  3. Flexibilidade: formato diferente da entidade
  4. Desacoplamento: mudanças internas não afetam a API
  5. Validação: regras específicas para entrada/saída

Pergunta 7: Como converter uma entidade em DTO?

Resposta: Várias abordagens:

// 1. Método manual
public UserDto toDto(User user) {
return new UserDto(user.getId(), user.getName(), user.getEmail());
}

// 2. Com MapStruct
@Mapper
public interface UserMapper {
UserDto toDto(User user);
}

// 3. Com ModelMapper
modelMapper.map(user, UserDto.class);

Pergunta 8: Qual a diferença entre um RequestDTO e um ResponseDTO?

Resposta:

  • RequestDTO: dados de entrada (criação, atualização), contém validação
  • ResponseDTO: dados de saída, formatados para o cliente
// Request
public class CreateUserRequest {
@NotBlank
private String email;
@Size(min = 8)
private String password;
}

// Response
public class UserResponse {
private Long id;
private String email;
// Sem senha!
}

Pergunta 9: Como tratar erros na camada Service?

Resposta: Lançar exceções personalizadas:

@Service
public class UserService {

public User findById(Long id) {
return userRepository.findById(id)
.orElseThrow(() -> new UserNotFoundException("User not found: " + id));
}
}

Essas exceções são tratadas por @ControllerAdvice.


Pergunta 10: O que é @Transactional em um service?

Resposta: @Transactional gerencia automaticamente as transações:

  • Inicia uma transação no começo do método
  • Faz commit se tiver sucesso
  • Faz rollback se houver exceção
@Service
@Transactional
public class OrderService {
// Todos os métodos são transacionais
}

Questões 11-20: Validação​

Pergunta 11: Qual dependência adicionar para validação?

Resposta: spring-boot-starter-validation

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

Pergunta 12: Como ativar a validação em um controller?

Resposta: Com @Valid ou @Validated no parâmetro:

@PostMapping
public ResponseEntity<User> create(@Valid @RequestBody CreateUserRequest request) {
// Se a validação falhar, MethodArgumentNotValidException é lançada
}

Pergunta 13: Quais são as anotações de validação mais comuns?

Resposta:

AnotaçãoDescrição
@NotNullNão pode ser null
@NotBlankNão null, não vazio, sem espaços
@NotEmptyNão null e não vazio
@Size(min, max)Tamanho entre min e max
@Min, @MaxValor numérico mínimo/máximo
@EmailFormato de e-mail válido
@PatternRegex personalizada
@Past, @FutureData no passado/futuro

Pergunta 14: Como personalizar a mensagem de erro de validação?

Resposta: Com o atributo message:

public class CreateUserRequest {

@NotBlank(message = "O e-mail é obrigatório")
@Email(message = "Formato de e-mail inválido")
private String email;

@Size(min = 8, message = "A senha deve ter pelo menos 8 caracteres")
private String password;
}

Pergunta 15: Como criar uma validação personalizada?

Resposta: Criar uma anotação e um validador:

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = UniqueEmailValidator.class)
public @interface UniqueEmail {
String message() default "E-mail já utilizado";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

public class UniqueEmailValidator implements ConstraintValidator<UniqueEmail, String> {
@Override
public boolean isValid(String email, ConstraintValidatorContext context) {
// Verificar se o e-mail existe
}
}

Pergunta 16: Qual a diferença entre @Valid e @Validated?

Resposta:

  • @Valid: padrão Java (JSR-380), faz validação em cascata
  • @Validated: Spring, suporta grupos de validação
// Grupos de validação
public interface OnCreate {}
public interface OnUpdate {}

@NotNull(groups = OnUpdate.class)
private Long id;

@Validated(OnCreate.class)
public void create(...) { }

Pergunta 17: Como validar parâmetros de requisição (query params)?

Resposta: Adicionar @Validated no controller:

@RestController
@Validated
public class UserController {

@GetMapping("/users")
public List<User> search(
@RequestParam @Min(0) int page,
@RequestParam @Max(100) int size) {
// ...
}
}

Pergunta 18: Como validar um objeto aninhado?

Resposta: Usar @Valid no campo aninhado:

public class OrderRequest {

@Valid // Validação em cascata
@NotNull
private AddressDto shippingAddress;
}

public class AddressDto {
@NotBlank
private String street;
@NotBlank
private String city;
}

Pergunta 19: Como recuperar os erros de validação?

Resposta: Via BindingResult ou @ExceptionHandler:

// Opção 1: BindingResult
@PostMapping
public ResponseEntity<?> create(@Valid @RequestBody Request req, BindingResult result) {
if (result.hasErrors()) {
return ResponseEntity.badRequest().body(result.getAllErrors());
}
}

// Opção 2: ControllerAdvice (recomendado)
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> handleValidation(MethodArgumentNotValidException ex) {
// Extrair os erros
}

Pergunta 20: O que é validação na camada de serviço?

Resposta: Validação da lógica de negócio (não apenas do formato):

@Service
public class OrderService {

public Order createOrder(OrderRequest request) {
// Validação de negócio
if (request.getQuantity() > productService.getStock(request.getProductId())) {
throw new InsufficientStockException("Estoque insuficiente");
}
// ...
}
}

Questões 21-30: Arquitetura​

Pergunta 21: Quais são as 3 camadas principais da arquitetura MVC?

Resposta:

  1. Controller (Apresentação): gerencia HTTP, validação de entrada
  2. Service (Negócio): lógica de negócio, transações
  3. Repository (Dados): acesso ao banco de dados
Cliente → Controller → Service → Repository → Database

Pergunta 22: Em qual camada colocar o gerenciamento de transações?

Resposta: Na camada Service. É onde está a lógica de negócio que define o que constitui uma unidade de trabalho atômica.

@Service
@Transactional
public class TransferService {
public void transfer(Long fromId, Long toId, BigDecimal amount) {
// Toda a operação é atômica
}
}

Pergunta 23: Como organizar os packages de um projeto Spring Boot?

Resposta: Por camada ou por funcionalidade:

// Por camada
com.example.app
├── controller/
├── service/
├── repository/
├── model/
└── dto/

// Por funcionalidade (recomendado para projetos grandes)
com.example.app
├── user/
│ ├── UserController
│ ├── UserService
│ └── UserRepository
├── order/
└── product/

Pergunta 24: O que é o princípio da responsabilidade única (SRP)?

Resposta: Uma classe deve ter apenas uma razão para mudar. Cada classe tem uma única responsabilidade:

  • Controller: gerenciar requisições HTTP
  • Service: lógica de negócio
  • Repository: acesso a dados

Exemplo ruim: um controller que faz tudo (HTTP + negócio + banco de dados).


Pergunta 25: Por que usar interfaces para os services?

Resposta:

  1. Desacoplamento: os clientes dependem da abstração
  2. Testabilidade: fácil de mockar
  3. Flexibilidade: trocar a implementação
  4. Proxying: Spring AOP funciona melhor
public interface UserService {
User findById(Long id);
}

@Service
public class UserServiceImpl implements UserService { }

Pergunta 26: O que é um @ControllerAdvice?

Resposta: Um componente que gerencia exceções globalmente para todos os controllers:

@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFound(UserNotFoundException ex) {
return ResponseEntity.status(404).body(new ErrorResponse(ex.getMessage()));
}
}

Pergunta 27: Como estruturar uma resposta de erro padrão?

Resposta: Criar um DTO de erro consistente:

public class ErrorResponse {
private LocalDateTime timestamp;
private int status;
private String error;
private String message;
private String path;
}

// Ou formato ProblemDetail (RFC 7807)

Pergunta 28: Qual a diferença entre @RestController e @Controller?

Resposta:

  • @Controller: retorna views (HTML)
  • @RestController: retorna dados (JSON/XML)

@RestController = @Controller + @ResponseBody

@RestController  // Tudo é JSON
public class UserController { }

@Controller
public class ViewController {
@GetMapping("/")
public String home() {
return "index"; // View Thymeleaf
}
}

Pergunta 29: Como tratar os códigos HTTP apropriados?

Resposta: Usar ResponseEntity:

@PostMapping
public ResponseEntity<User> create(@RequestBody UserRequest req) {
User user = userService.create(req);
return ResponseEntity
.status(HttpStatus.CREATED) // 201
.body(user);
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable Long id) {
userService.delete(id);
return ResponseEntity.noContent().build(); // 204
}

Pergunta 30: Quais são os códigos HTTP comuns em REST?

Resposta:

CódigoSignificadoUso
200OKGET, PUT bem-sucedido
201CreatedPOST bem-sucedido
204No ContentDELETE bem-sucedido
400Bad RequestValidação falhou
401UnauthorizedNão autenticado
403ForbiddenNão autorizado
404Not FoundRecurso inexistente
500Server ErrorErro interno

Pontuação​

PontuaçãoNível
27-30Excelente - Arquitetura dominada
21-26Bom - Algumas revisões
15-20Médio - Releia os capítulos
Menos de 15A revisar - Refaça os fundamentos

Voltar ao Módulo 3