Projeto-Teste-Maxxmobi

Projeto API REST para gerenciamento de Candidatos.

Stars
0
Committers
2

API REST FULL Candidatos

Este um projeto de uma API REST para gerenciar candidatos, desenvolvido como parte do teste da Maxxmobi. A API permite realizar operaes CRUD (Create, Read, Update, Delete) em candidatos.

Tecnologias Utilizadas

  • Java 17
  • Spring Boot 3.3.2
  • Spring Data JPA
  • Spring Security
  • Spring Boot DevTools
  • Swagger/OpenAPI
  • PostgreSQL
  • MySQL
  • JUnit
  • H2 Database
  • JWT (Json Web Token)
  • Docker

Dependncias

Gerenciamento de Dependncias

As dependncias do projeto so gerenciadas atravs do Maven. Abaixo est um resumo das principais dependncias utilizadas:

  • Spring Boot Starter Web: para construir a aplicao web.
  • Spring Boot Starter Data JPA: para persistncia de dados.
  • Spring Boot Starter Validation: para validao de dados.
  • Spring Boot DevTools: para facilitar o desenvolvimento.
  • PostgreSQL: driver JDBC para o banco de dados PostgreSQL.
  • MySQL: driver JDBC para o banco de dados MySQL.
  • H2 Database: banco de dados em memria utilizado para testes.
  • Spring Boot Starter Test: para testes unitrios e de integrao.
  • Spring Boot Starter Security: para segurana da aplicao.
  • JWT: para gerao e validao de tokens JWT.
  • Swagger/OpenAPI: para documentao da API.
  • Docker: para containerizao da aplicao.

Configurao do Projeto

Banco de Dados

A aplicao est configurada para utilizar MySQL em desenvolvimento local e PostgreSQL em produo no Render.

Configurao para Desenvolvimento Local (MySQL)

No arquivo src/main/resources/application-dev.properties:

spring.jpa.hibernate.ddl-auto=update
spring.jpa.database=mysql
spring.datasource.url=jdbc:mysql://localhost/db_maxxmobi?createDatabaseIfNotExist=true&serverTimezone=America/Sao_Paulo&useSSl=false
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect

spring.jpa.properties.jakarta.persistence.sharedCache.mode=ENABLE_SELECTIVE

spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=Brazil/East

Configurao para Produo (PostgreSQL)

No arquivo src/main/resources/application-pro.properties:

spring.jpa.generate-ddl=true
spring.jpa.database=postgresql
spring.datasource.url=jdbc:postgresql://${POSTGRESHOST}:${POSTGRESPORT}/${POSTGRESDATABASE}
spring.datasource.username=${POSTGRESUSER}
spring.datasource.password=${POSTGRESPASSWORD}

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.jakarta.persistence.sharedCache.mode=ENABLE_SELECTIVE

spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=Brazil/East

Configurao Geral

Configurao Geral e Swagger

No arquivo src/main/resources/application.properties:

spring.profiles.active=prod

springdoc.api-docs.path=/v3/api-docs
springdoc.swagger-ui.path=/swagger-ui.html
springdoc.swagger-ui.operationsSorter=method
springdoc.swagger-ui.disable-swagger-default-url=true
springdoc.swagger-ui.use-root-path=true
springdoc.packagesToScan=br.com.maxxmobi.teste.controller

Docker

Este projeto inclui um Dockerfile para facilitar a criao de contineres Docker. O Dockerfile configurado para construir e rodar a aplicao em produo com OpenJDK 17.0.1.

Dockerfile

FROM openjdk:17.0.1-jdk-oracle as build

WORKDIR /workspace/app

COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
COPY src src

RUN chmod -R 777 ./mvnw

RUN ./mvnw install -DskipTests

RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)

FROM openjdk:17.0.1-jdk-oracle

VOLUME /tmp

ARG DEPENDENCY=/workspace/app/target/dependency

COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app

ENTRYPOINT ["java","-cp","app:app/lib/*","br.com.maxxmobi.teste.ApiRestFullCantidatosApplication"]

Executando o Projeto

  1. Clone o repositrio:

    git clone <URL_DO_REPOSITORIO>
    cd <NOME_DO_PROJETO>
    
  2. Configure o banco de dados conforme descrito acima.

  3. Execute o projeto usando Maven:

    mvn spring-boot:run
    

Documentao da API

A documentao da API est disponvel no Swagger. Aps iniciar a aplicao, acesse a seguinte URL para visualizar a documentao:

http://localhost:8080/swagger-ui.html

Para acessar a documentao da API hospedada na plataforma Render, utilize a URL:

https://projeto-teste-maxxmobi.onrender.com/swagger-ui.html

Credenciais de Acesso

Para acessar a API, utilize as seguintes credenciais:

Criando um Novo Usurio

Para acessar a API localmente devemos criar um novo usurio, utilize o Insomnia ou outra ferramenta similar para fazer uma requisio POST para a URL:

http://localhost:8080/usuarios/cadastrar

Segurana

A segurana da aplicao gerenciada pelo Spring Security. A autenticao e autorizao so feitas atravs de tokens JWT.

Testes com JUnit

Os testes unitrios e de integrao foram realizados utilizando JUnit. Para executar os testes, utilize o comando:

mvn test

Foram realizados testes para garantir o funcionamento correto dos endpoints relacionados aos usurios. A seguir, esto descritos os testes realizados com o UsuarioController:

Testes Realizados

1. Cadastro de Usurio

@Test
@DisplayName("Cadastrar um Usurio")
public void deveCriarUmUsuario() {
    HttpEntity<Usuario> corpoRequisicao = new HttpEntity<Usuario>(new Usuario(0L, "Edvaldo Junior", "[email protected]", "12345678"));

    ResponseEntity<Usuario> corpoResposta = testRestTemplate
            .exchange("/usuarios/cadastrar", HttpMethod.POST, corpoRequisicao, Usuario.class);

    assertEquals(HttpStatus.CREATED, corpoResposta.getStatusCode());
}

Descrio: Testa a criao de um novo usurio.

Expectativa: O status HTTP retornado deve ser 201 Created.

  1. No Permitir Duplicao de Usurio

@Test
@DisplayName("No deve permitir duplicao do Usurio")
public void naoDeveDuplicarUsuario() {
    usuarioService.cadastrarUsuario(new Usuario(0L, "Maria da Silva", "[email protected]", "12345678"));

HttpEntity<Usuario> corpoRequisicao = new HttpEntity<Usuario>(new Usuario(0L, "Maria da Silva", "[email protected]", "12345678"));

ResponseEntity<Usuario> corpoResposta = testRestTemplate
        .exchange("/usuarios/cadastrar", HttpMethod.POST, corpoRequisicao, Usuario.class);

assertEquals(HttpStatus.BAD_REQUEST, corpoResposta.getStatusCode());
}

Descrio: Testa a tentativa de cadastro de um usurio com dados duplicados.

Expectativa: O status HTTP retornado deve ser 400 Bad Request.

  1. Atualizao de Usurio

    @Test
    @DisplayName("Atualizar um Usurio")
    public void deveAtualizarUmUsuario() {
        Optional<Usuario> usuarioCadastrado = usuarioService.cadastrarUsuario(new Usuario(0L, "Juliana Andrews", "[email protected]", "juliana123"));
    
        Usuario usuarioUpdate = new Usuario((usuarioCadastrado.get().getId()),
                "Juliana Andrews", "[email protected]", "juliana123");
    
        HttpEntity<Usuario> corpoRequisicao = new HttpEntity<Usuario>(usuarioUpdate);
    
        ResponseEntity<Usuario> corpoResposta = testRestTemplate
                .withBasicAuth("[email protected]", "rootroot")
                .exchange("/usuarios/atualizar", HttpMethod.PUT, corpoRequisicao, Usuario.class);
    
        assertEquals(HttpStatus.OK, corpoResposta.getStatusCode());
    }
    
    

Descrio: Testa a atualizao dos dados de um usurio existente.

Expectativa: O status HTTP retornado deve ser 200 OK.

  1. Listar Todos os Usurios

    @Test
    @DisplayName("Listar todos os Usurios")
    public void deveMostrarTodosUsuarios() {
        usuarioService.cadastrarUsuario(new Usuario(0L, "Sabrina Sanches", "[email protected]", "sabrina123"));
        usuarioService.cadastrarUsuario(new Usuario(0L, "Ricardo Marques", "[email protected]", "ricardo123"));
    
        ResponseEntity<String> resposta = testRestTemplate
                .withBasicAuth("[email protected]", "rootroot")
                .exchange("/usuarios/all", HttpMethod.GET, null, String.class);
    
        assertEquals(HttpStatus.OK, resposta.getStatusCode());
    }
    
    
    • Descrio: Testa a listagem de todos os usurios cadastrados.
    • Expectativa: O status HTTP retornado deve ser 200 OK.

    Configurao dos Testes

    • Ambiente: O teste executado em um ambiente de aplicao configurado para usar uma porta aleatria (SpringBootTest.WebEnvironment.RANDOM_PORT).
    • Autenticao: Alguns testes requerem autenticao bsica para acessar endpoints protegidos.

    Esses testes garantem que o controle de usurios est funcionando conforme o esperado e validam o comportamento da aplicao em cenrios tpicos de operao.

Cdigos SQL Gerados pelo JPA Repository

Abaixo esto os cdigos SQL que correspondem criao da tabela tb_candidatos baseada na entidade CandidadosModel:

CREATE TABLE tb_candidatos (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    nome VARCHAR(100) NOT NULL,
    nascimento DATE NOT NULL,
    data_criacao TIMESTAMP NOT NULL,
    sexo CHAR(1) DEFAULT 'M' NOT NULL,
    nota INT NOT NULL,
    logradouro VARCHAR(200),
    bairro VARCHAR(50),
    cidade VARCHAR(50),
    uf CHAR(2)
);

Detalhes da Tabela

  • id: Identificador nico da entidade, gerado automaticamente pelo banco de dados.
  • nome: Nome do candidato, com comprimento mximo de 100 caracteres.
  • nascimento: Data de nascimento do candidato, armazenada como DATE.
  • data_criacao: Data e hora em que o registro foi criado, armazenada como TIMESTAMP.
  • sexo: Sexo do candidato, com valor padro 'M' (Masculino), armazenado como CHAR(1).
  • nota: Nota do candidato, armazenada como INT.
  • logradouro: Endereo do candidato, armazenado como VARCHAR(200).
  • bairro: Bairro do candidato, armazenado como VARCHAR(50).
  • cidade: Cidade do candidato, armazenada como VARCHAR(50).
  • uf: Unidade Federativa (estado) do candidato, armazenada como CHAR(2).

Notas

  • Valores Padro: O campo sexo tem um valor padro definido como 'M' (Masculino).
  • Nulabilidade: Campos como logradouro, bairro, cidade, e uf so opcionais e podem ser NULL.

Entidade Usuario

Aqui esto os cdigos SQL que correspondem criao da tabela tb_usuarios baseada na entidade Usuario:

CREATE TABLE tb_usuarios (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    nome VARCHAR(255) NOT NULL,
    usuario VARCHAR(255) NOT NULL UNIQUE,
    senha VARCHAR(255) NOT NULL
);

Detalhes da Tabela

  • id: Identificador nico da entidade, gerado automaticamente pelo banco de dados.
  • nome: Nome do usurio, com comprimento mximo de 255 caracteres.
  • usuario: Email do usurio, com comprimento mximo de 255 caracteres e deve ser nico.
  • senha: Senha do usurio, com comprimento mximo de 255 caracteres.

Notas

  • Valores Padro: O campo nome, usuario, e senha so obrigatrios e no podem ser nulos.
  • Restries: O campo usuario deve ser nico e deve seguir o formato de um email vlido.

Caso queira verificar os cdigos SQL gerados, voc pode habilitar a exibio de SQL no Hibernate atravs da configurao spring.jpa.show-sql=true no arquivo application.properties.

Anlise da Estrutura de Pastas e Classes do Projeto

Estrutura de Pastas

A estrutura de pastas apresenta uma organizao comum em projetos Spring Boot, com as seguintes responsabilidades:

  • config: Contm configuraes gerais do projeto, como a configurao do Swagger (para documentao da API).
  • controller: Contm os controladores, que so responsveis por receber as requisies HTTP e retornar as respostas.
  • model: Contm as classes que representam os dados do domnio do negcio (entidades).
  • repository: Contm as interfaces e classes que interagem com o banco de dados (geralmente utilizando JPA ou outra ORM).
  • security: Contm classes relacionadas segurana da aplicao, como filtros para autenticao e autorizao.
  • service: Contm as classes de servio, que encapsulam a lgica de negcio e podem chamar os repositrios para acessar os dados.
  • resources: Contm arquivos estticos (imagens, CSS, JavaScript) e templates para a camada de apresentao (se houver).
  • test: Contm os testes unitrios e de integrao.

Descrio das Classes e Interfaces

  • config.SwaggerConfig:

  • Configura a gerao da documentao da API utilizando o Swagger.

  • controller.CandidatoController:

  • Controla as requisies relacionadas a candidatos, como listar, criar, atualizar e excluir candidatos.

  • controller.UsuarioController:

  • Controla as requisies relacionadas a usurios, como login, cadastro e gerenciamento de perfis.

  • model.CandidatosModel:

  • Representa um candidato, com atributos como nome, email, etc.

  • model.Usuario:

  • Representa um usurio do sistema, com atributos como nome de usurio, senha, etc.

  • model.UsuarioLogin:

  • Pode ser utilizado para representar os dados de login de um usurio (nome de usurio e senha).

  • repository.CandidatosRepository:

  • Interface que define os mtodos para acessar e manipular os dados de candidatos no banco de dados.

  • repository.UsuarioRepository:

  • Interface que define os mtodos para acessar e manipular os dados de usurios no banco de dados.

  • security.BasicSecurityConfig:

  • Configura a segurana bsica da aplicao, como autenticao por basic authentication.

  • security.JwtAuthFilter:

  • Filtro que realiza a autenticao utilizando tokens JWT.

  • security.JwtService:

  • Servio responsvel por gerar, validar e armazenar tokens JWT.

  • security.UserDetailsImpl:

  • Implementao da interface UserDetails, que representa um usurio autenticado.

  • security.UserDetailsServiceImpl:

  • Servio responsvel por carregar os detalhes do usurio a partir do banco de dados.

  • service:

  • Responsvel por gerenciar usurios do sistema. Ela prov mtodos para cadastro.

  • service.ApiRestFullCandidatosApplication:

  • Classe principal da aplicao Spring Boot.

Anlise Detalhada dos Endpoints do Controlador de Usurios

Entendendo os Endpoints

  • GET /usuarios/{id}

    • Objetivo: Buscar um usurio especfico pelo seu ID.

    • Exemplo de Requisio:

      GET /usuarios/1
      
    • Exemplo de Resposta (Sucesso):

      {
          "id": 1,
          "nome": "Joo da Silva",
          "email": "[email protected]"
          // ... outros atributos do usurio
      }
      
    • Exemplo de Resposta (Erro):

      {
          "mensagem": "Usurio no encontrado"
      }
      

    GET /usuarios/all

    • Objetivo: Listar todos os usurios cadastrados.

    • Exemplo de Requisio:

      GET /usuarios/all
      
    • Exemplo de Resposta (Sucesso):

      [
          {
              "id": 1,
              "nome": "Joo da Silva",
              "email": "[email protected]"
          },
          {
              "id": 2,
              "nome": "Maria da Silva",
              "email": "[email protected]"
          }
          // ... outros usurios
      ]
      

    POST /usuarios/logar

    • Objetivo: Realizar o login de um usurio.

    • Exemplo de Requisio:

      {
          "email": "[email protected]",
          "senha": "minhaSenha123"
      }
      
    • Exemplo de Resposta (Sucesso):

      {
          "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJqb2FvQGVtYWlsLmNvbSIsInJvbGUiOiJ1c2VyIiwiaWF0IjoxNjYxNTE2NTEyLCJleHAiOjE2NjE1MjAzMTJ9.yJmM1O854aGzvZ3X-ywOo97b0nmTvjNuuo6qwU7AiM"
      }
      
    • Exemplo de Resposta (Erro):

      {
          "mensagem": "Credenciais invlidas"
      }
      

    POST /usuarios/cadastrar

    • Objetivo: Cadastrar um novo usurio.

    • Exemplo de Requisio:

      {
          "nome": "Novo Usurio",
          "email": "[email protected]",
          "senha": "minhaNovaSenha"
      }
      
    • Exemplo de Resposta (Sucesso):

      {
          "mensagem": "Usurio cadastrado com sucesso"
      }
      
    • Exemplo de Resposta (Erro):

      {
          "mensagem": "Email j cadastrado"
      }
      

    PUT /usuarios/atualizar

    • Objetivo: Atualizar os dados de um usurio existente.

    • Exemplo de Requisio:

      {
          "id": 1,
          "nome": "Joo da Silva Atualizado",
          "email": "[email protected]"
      }
      
    • Exemplo de Resposta (Sucesso):

      {
          "mensagem": "Usurio atualizado com sucesso"
      }
      
    • Exemplo de Resposta (Erro):

      {
          "mensagem": "Usurio no encontrado"
      }
      

Anlise Detalhada dos Endpoints do Controlador de Candidatos

Entendendo os Endpoints

1. DELETE /candidatos/{id}

Descrio: Exclui um candidato especfico, identificado pelo seu ID.

  • Requisio:

    DELETE /candidatos/1
    
  • Resposta (Sucesso):

    {
      "message": "Candidato excludo com sucesso."
    }
    
  • Resposta (Erro, por exemplo, candidato no encontrado):

    {
      "error": "Candidato no encontrado."
    }
    

2. GET /candidatos/{id}

Descrio: Obtm os dados de um candidato especfico, identificado pelo seu ID.

  • Requisio:

    GET /candidatos/1
    
  • Resposta (Sucesso):

    {
      "id": 1,
      "nome": "Marina Barros",
      "nascimento": "2003-10-10",
      "dataCriacao": "2024-07-25",
      "sexo": "F",
      "nota": 9,
      "logradouro": "Avenida dos Ips",
      "bairro": "Ips",
      "cidade": "Manaus",
      "uf": "AM"
    }
    
  • Resposta (Erro, por exemplo, candidato no encontrado):

    {
      "error": "Candidato no encontrado."
    }
    

3. GET /candidatos/buscarPorSexo

Descrio: Busca candidatos por sexo.

  • Requisio:

    GET /candidatos/buscarPorSexo?sexo=F
    
  • Resposta (Sucesso):

    [
      {
        "id": 1,
        "nome": "Marina Barros",
        "nascimento": "2003-10-10",
        "dataCriacao": "2024-07-25",
        "sexo": "F",
        "nota": 9,
        "logradouro": "Avenida dos Ips",
        "bairro": "Ips",
        "cidade": "Manaus",
        "uf": "AM"
      },
      {
        "id": 2,
        "nome": "Ana Souza",
        "nascimento": "1999-05-22",
        "dataCriacao": "2024-07-25",
        "sexo": "F",
        "nota": 8,
        "logradouro": "Rua das Flores",
        "bairro": "Jardim",
        "cidade": "So Paulo",
        "uf": "SP"
      }
    ]
    
  • Resposta (Erro, por exemplo, parmetro invlido):

    {
      "error": "Sexo invlido. Use 'M' para masculino ou 'F' para feminino."
    }
    

4. GET /candidatos/buscarPorNota

Descrio: Busca candidatos por nota.

  • Requisio:

    GET /candidatos/buscarPorNota?nota=9
    
  • Resposta (Sucesso):

    [
      {
        "id": 1,
        "nome": "Marina Barros",
        "nascimento": "2003-10-10",
        "dataCriacao": "2024-07-25",
        "sexo": "F",
        "nota": 9,
        "logradouro": "Avenida dos Ips",
        "bairro": "Ips",
        "cidade": "Manaus",
        "uf": "AM"
      }
    ]
    
  • Resposta (Erro, por exemplo, parmetro invlido):

    {
      "error": "Nota invlida. Deve ser um nmero inteiro."
    }
    

5. GET /candidatos/buscarPorNome

Descrio: Busca candidatos por nome.

  • Requisio:

    GET /candidatos/buscarPorNome?nome=Marina
    
  • Resposta (Sucesso):

    [
      {
        "id": 1,
        "nome": "Marina Barros",
        "nascimento": "2003-10-10",
        "dataCriacao": "2024-07-25",
        "sexo": "F",
        "nota": 9,
        "logradouro": "Avenida dos Ips",
        "bairro": "Ips",
        "cidade": "Manaus",
        "uf": "AM"
      }
    ]
    
  • Resposta (Erro, por exemplo, nome no encontrado):

    {
      "error": "Nenhum candidato encontrado com o nome fornecido."
    }
    

6. GET /candidatos/buscarPorNascimento

Descrio: Busca candidatos por data de nascimento.

  • Requisio:

    GET /candidatos/buscarPorNascimento?nascimento=2003-10-10
    
  • Resposta (Sucesso):

    [
      {
        "id": 1,
        "nome": "Marina Barros",
        "nascimento": "2003-10-10",
        "dataCriacao": "2024-07-25",
        "sexo": "F",
        "nota": 9,
        "logradouro": "Avenida dos Ips",
        "bairro": "Ips",
        "cidade": "Manaus",
        "uf": "AM"
      }
    ]
    
  • Resposta (Erro, por exemplo, data invlida):

    {
      "error": "Data de nascimento invlida. Use o formato YYYY-MM-DD."
    }
    

7. GET /candidatos/busca/ordenada

Descrio: Busca todos os candidatos de forma ordenada (o critrio de ordenao deve ser especificado com ASC ou DESC).

  • Requisio:

    GET /candidatos/busca/ordenada?ordem=nome
    
  • Resposta (Sucesso):

    [
      {
        "id": 2,
        "nome": "Ana Souza",
        "nascimento": "1999-05-22",
        "dataCriacao": "2024-07-25",
        "sexo": "F",
        "nota": 8,
        "logradouro": "Rua das Flores",
        "bairro": "Jardim",
        "cidade": "So Paulo",
        "uf": "SP"
      },
      {
        "id": 1,
        "nome": "Marina Barros",
        "nascimento": "2003-10-10",
        "dataCriacao": "2024-07-25",
        "sexo": "F",
        "nota": 9,
        "logradouro": "Avenida dos Ips",
        "bairro": "Ips",
        "cidade": "Manaus",
        "uf": "AM"
      }
    ]
    
  • Resposta (Erro, por exemplo, critrio de ordenao invlido):

    {
      "error": "Critrio de ordenao invlido. Use 'nome', 'nota', etc."
    }
    

8. POST /candidatos

Descrio: Cria um novo candidato.

  • Requisio:

    POST /candidatos
    

    Corpo da Requisio:

    {
      "nome": "Marina Barros",
      "nascimento": "2003-10-10",
      "dataCriacao": "2024-07-25",
      "sexo": "F",
      "nota": 9,
      "logradouro": "Avenida dos Ips",
      "bairro": "Ips",
      "cidade": "Manaus",
      "uf": "AM"
    }
    
  • Resposta (Sucesso):

    {
      "message": "Candidato criado com sucesso.",
      "id": 3
    }
    
  • Resposta (Erro, por exemplo, dados invlidos):

    jsonCopiar cdigo{
      "error": "Dados invlidos. Verifique os campos e tente novamente."
    }
    

9. PUT /candidatos

Descrio: Atualiza os dados de um candidato (provavelmente, o ID enviado no corpo da requisio).

  • Requisio:

    PUT /candidatos
    

    Corpo da Requisio:

    {
      "id": 1,
      "nome": "Marina Barros",
      "nascimento": "2003-10-10",
      "dataCriacao": "2024-07-25",
      "sexo": "F",
      "nota": 10,
      "logradouro": "Avenida dos Ips",
      "bairro": "Ips",
      "cidade": "Manaus",
      "uf": "AM"
    }
    
  • Resposta (Sucesso):

    {
      "message": "Candidato atualizado com sucesso."
    }
    
  • Resposta (Erro, por exemplo, candidato no encontrado):

    {
      "error": "Candidato no encontrado. Verifique o ID e tente novamente."
    }
    

ACESSE O PDF DA DOCUMENTAO EM SWAGGER E ENTENDA MELHOR CADA ENDPOINT:

https://github.com/edvaldoljr/Projeto-Teste-Maxxmobi/blob/main/Projeto%20Teste%20Maxxmobi.pdf

Prezado Altamiro Santos

Agradeo pela oportunidade de participar do processo seletivo para a vaga de desenvolvedor Java jnior. Estou entregando o teste conforme solicitado e estou disposio para quaisquer esclarecimentos ou dvidas que possam surgir.

Espero que o trabalho realizado esteja alinhado com o que vocs esto buscando. Agradeo a sua considerao e aguardo ansiosamente o retorno.

Atenciosamente, Edvaldo Junior