Arquitetura Hexagonal: o guia definitivo para isolar sua lógica de negócio e parar de sofrer com dependências

Entenda o que é Arquitetura Hexagonal, como funciona o conceito de Ports and Adapters e como implementar na prática.

Sumário

Todo desenvolvedor que trabalhou em um sistema que cresceu sem arquitetura clara conhece o momento: você precisa trocar o banco de dados, ou integrar um novo serviço de pagamento, ou adicionar uma interface de linha de comando além da API REST existente — e descobre que a lógica de negócio está tão entrelaçada com a infraestrutura que qualquer mudança parece uma cirurgia de coração aberto.

Esse problema tem nome. Chama-se acoplamento. E ele não surge de programadores negligentes — surge da ausência de uma estrutura que impeça que lógica de negócio e detalhes técnicos se misturem ao longo do tempo.

A Arquitetura Hexagonal, proposta por Alistair Cockburn no início dos anos 2000, foi concebida exatamente para resolver esse problema. Também conhecida como Ports and Adapters, ela organiza o código em torno de um princípio central: a lógica de negócio não deve saber nada sobre a infraestrutura que a envolve. Banco de dados, framework web, serviço de mensageria, interface de usuário — tudo isso são detalhes que podem mudar. A lógica de negócio é o que não muda, e é ela que precisa ser protegida.

Neste artigo, você vai entender os fundamentos conceituais da Arquitetura Hexagonal, a estrutura de portas e adaptadores e como cada componente se relaciona, como implementar na prática com exemplos de código reais, as vantagens concretas em termos de testabilidade e manutenção, os padrões que se combinam naturalmente com esse modelo e quando adotá-la — e quando não vale o esforço. Se você está projetando um sistema novo ou refatorando um sistema legado que está ficando difícil de manter, este guia vai te dar uma base sólida para tomar decisões arquiteturais melhores.

O problema que a Arquitetura Hexagonal resolve

Para entender por que a Arquitetura Hexagonal existe, é útil entender o que acontece sem ela.

Em uma arquitetura em camadas tradicional — o modelo mais comum em aplicações corporativas — o código é organizado em camadas horizontais: apresentação, negócio e persistência. Parece organizado. E é, enquanto o sistema é pequeno e os requisitos são estáveis.

O problema aparece quando as camadas começam a vazar. Um controlador web que acessa diretamente o repositório para “economizar uma camada”. Uma entidade de domínio que importa uma classe JPA porque é mais conveniente. Um serviço de negócio que acessa o HttpRequest porque precisa de algum dado do contexto da requisição. Cada uma dessas decisões parece pequena no momento — e cada uma delas cria um fio de arame farpado que vai complicar cada mudança futura.

💡 Dica: O sintoma mais revelador de acoplamento excessivo entre lógica de negócio e infraestrutura é o custo de escrever testes unitários. Se você precisa de um banco de dados em memória, de um servidor HTTP simulado ou de um container Docker rodando só para testar uma regra de negócio, seu domínio está acoplado à infraestrutura. A Arquitetura Hexagonal resolve isso estruturalmente.

A premissa central

A Arquitetura Hexagonal parte de uma premissa simples e poderosa: existem dois tipos de código em qualquer aplicação.

O primeiro tipo é a lógica de negócio — as regras que definem o que o sistema faz, independentemente de como ele é acessado ou onde os dados são armazenados. Essa lógica deveria ser a mesma se o sistema fosse uma API REST, um serviço de linha de comando ou um worker assíncrono.

O segundo tipo é a infraestrutura — os detalhes técnicos que conectam a lógica de negócio ao mundo externo: frameworks web, bancos de dados, serviços externos, filas de mensagens, interfaces de usuário. Esses detalhes mudam com frequência, têm dependências específicas de tecnologia e não devem contaminar a lógica de negócio.

A Arquitetura Hexagonal define uma fronteira clara entre esses dois tipos de código. Tudo que pertence ao domínio fica dentro do hexágono. Tudo que pertence à infraestrutura fica fora. E a comunicação entre os dois lados só acontece através de interfaces bem definidas — as portas.

Portas e Adaptadores: o vocabulário da Arquitetura Hexagonal

O nome alternativo da Arquitetura Hexagonal — Ports and Adapters — é mais descritivo do que parece. Ele define com precisão os dois mecanismos que tornam possível o isolamento do domínio.

Portas: as interfaces do domínio

Uma porta é uma interface que define como o mundo externo pode interagir com o domínio — ou como o domínio pode interagir com o mundo externo. Ela é definida dentro do núcleo da aplicação e faz parte do domínio, não da infraestrutura.

Existem dois tipos de portas:

Portas de entrada (inbound ports) — definem as operações que podem ser executadas no domínio. São a API do seu domínio para o mundo externo. Um controlador web que recebe uma requisição HTTP, um consumer de fila que processa uma mensagem ou um CLI que executa um comando — todos eles invocam o domínio através de portas de entrada.

Portas de saída (outbound ports) — definem o que o domínio precisa de fora para funcionar. Um repositório de dados, um serviço de envio de e-mail, um cliente de API externa — o domínio os enxerga apenas como interfaces que cumprem um contrato, sem saber nada sobre a implementação concreta.

Adaptadores: as implementações concretas

Um adaptador é a implementação concreta de uma porta. Ele vive fora do domínio, na camada de infraestrutura, e é responsável por traduzir entre o mundo externo e o contrato definido pela porta.

Adaptadores de entrada (inbound adapters) convertem estímulos externos em chamadas ao domínio. Um controlador Spring MVC que recebe uma requisição HTTP e chama um caso de uso. Um consumer Kafka que deserializa uma mensagem e aciona um serviço de domínio. Uma task agendada que dispara uma operação periódica.

Adaptadores de saída (outbound adapters) implementam as portas de saída, conectando o domínio a serviços concretos. Um repositório JPA que persiste entidades no banco relacional. Um cliente Feign que chama uma API externa. Um producer Kafka que publica eventos em um tópico.

⚠️ Atenção: O erro mais comum ao entender Ports and Adapters é pensar que as portas são apenas interfaces genéricas e os adaptadores são apenas implementações. O ponto crítico é a direção das dependências: o adaptador depende da porta, nunca o contrário. O domínio define o contrato (porta) e não sabe nada sobre quem o implementa (adaptador). Essa inversão de dependência é o que garante o isolamento.

A Regra de dependência

Existe uma regra que, se violada, destrói todas as garantias da Arquitetura Hexagonal: nenhum código do domínio pode importar ou depender de código de infraestrutura.

O domínio pode definir interfaces (portas). O domínio pode usar essas interfaces. O domínio não pode referenciar classes de framework, anotações de persistência, tipos específicos de HTTP ou qualquer outra tecnologia externa. Quando isso acontece, o acoplamento se instala e a fronteira perde seu valor.

Estrutura de pacotes: organizando o código na prática

Antes de ver código de implementação, é útil entender como a estrutura de pacotes reflete os conceitos da Arquitetura Hexagonal. Uma organização comum e amplamente adotada:

src/

├── domain/                          # Núcleo — sem dependências externas

│   ├── model/                       # Entidades, value objects, agregados

│   │   ├── Book.java

│   │   ├── User.java

│   │   └── Loan.java

│   ├── port/

│   │   ├── in/                      # Portas de entrada (casos de uso)

│   │   │   └── LoanBookUseCase.java

│   │   └── out/                     # Portas de saída (repositórios, serviços externos)

│   │       └── LoanRepository.java

│   └── service/                     # Implementação dos casos de uso

│       └── LoanService.java



└── infrastructure/                  # Adaptadores — dependem do domínio, não o contrário

    ├── in/

    │   └── web/                     # Adaptadores de entrada HTTP

    │       └── LoanController.java

    └── out/

        └── persistence/             # Adaptadores de saída (banco de dados)

            └── JpaLoanRepository.java
            

Essa estrutura torna explícita a direção das dependências: tudo em infrastructure pode importar de domain, mas nada em domain pode importar de infrastructure.

Implementação prática: sistema de gerenciamento de biblioteca

Para tornar os conceitos concretos, vamos implementar um sistema de gerenciamento de biblioteca com operações de empréstimo e devolução de livros usando Java, seguindo a Arquitetura Hexagonal.

Passo 1: definindo o domínio

O domínio começa pelas entidades que representam os conceitos do negócio. Note que estas classes não têm nenhuma anotação de framework — são Java puro:

// domain/model/Book.java
public class Book {
    private final String id;
    private final String title;
    private final String isbn;
    private boolean available;

    public Book(String id, String title, String isbn) {
        this.id = id;
        this.title = title;
        this.isbn = isbn;
        this.available = true;
    }

    public void markAsLoaned() {
        if (!available) {
            throw new BookNotAvailableException("Book " + id + " is not available");
        }

        this.available = false;
    }

    public void markAsReturned() {
        this.available = true;
    }

    public boolean isAvailable() {
        return available;
    }

    // getters...
}


// domain/model/Loan.java
public class Loan {
    private final String loanId;
    private final Book book;
    private final User user;
    private final LocalDate loanDate;
    private LocalDate returnDate;

    public Loan(Book book, User user) {
        this.loanId = UUID.randomUUID().toString();
        this.book = book;
        this.user = user;
        this.loanDate = LocalDate.now();
    }

    public void complete() {
        this.returnDate = LocalDate.now();
        this.book.markAsReturned();
    }

    // getters...
}

Passo 2: definindo as portas

As portas são interfaces que vivem no domínio. As portas de entrada definem os casos de uso; as portas de saída definem o que o domínio precisa da infraestrutura:

// domain/port/in/LoanBookUseCase.java
public interface LoanBookUseCase {
    Loan loanBook(String userId, String bookId);
}

// domain/port/in/ReturnBookUseCase.java
public interface ReturnBookUseCase {
    void returnBook(String loanId);
}

// domain/port/out/LoanRepository.java
public interface LoanRepository {
    void save(Loan loan);
    Optional<Loan> findById(String loanId);
    List<Loan> findActiveByUser(String userId);
}

// domain/port/out/BookRepository.java
public interface BookRepository {
    Optional<Book> findById(String bookId);
    void save(Book book);
}

💡 Dica: Perceba que as portas de saída são definidas com base no que o domínio precisa, não com base no que a infraestrutura oferece. LoanRepository existe porque LoanService precisa persistir empréstimos. A interface é moldada pelas necessidades do domínio, não pelas capacidades do banco de dados — o que torna o domínio completamente independente da tecnologia de persistência.

Passo 3: implementando o serviço de domínio

O serviço de domínio implementa a lógica de negócio usando apenas as portas — sem nenhuma dependência de framework ou infraestrutura:

// domain/service/LoanService.java
public class LoanService implements LoanBookUseCase, ReturnBookUseCase {
    private final BookRepository bookRepository;
    private final LoanRepository loanRepository;

    public LoanService(BookRepository bookRepository, LoanRepository loanRepository) {
        this.bookRepository = bookRepository;
        this.loanRepository = loanRepository;
    }

    @Override
    public Loan loanBook(String userId, String bookId) {
        Book book = bookRepository.findById(bookId)
            .orElseThrow(() -> new BookNotFoundException("Book not found: " + bookId));

        book.markAsLoaned(); // Lança exceção se não disponível
        
        Loan loan = new Loan(book, new User(userId));

        bookRepository.save(book);
        loanRepository.save(loan);
        
        return loan;
    }

    @Override
    public void returnBook(String loanId) {

        Loan loan = loanRepository.findById(loanId)
            .orElseThrow(() -> new LoanNotFoundException("Loan not found: " + loanId));
            
        loan.complete(); // Marca o livro como disponível e registra a data de devolução
        loanRepository.save(loan);
    }
}

Note o que não existe nesse código: nenhuma anotação @Service, nenhuma importação de Spring, nenhuma referência a SQL ou JPA. Isso é Java puro executando lógica de negócio. É completamente testável sem nenhum container ou banco de dados.

Passo 4: implementando os adaptadores

Os adaptadores traduzem entre o mundo externo e as portas do domínio. O adaptador de entrada converte uma requisição HTTP em uma chamada ao caso de uso:

// infrastructure/in/web/LoanController.java
@RestController
@RequestMapping("/api/loans")
public class LoanController {
    private final LoanBookUseCase loanBookUseCase;
    private final ReturnBookUseCase returnBookUseCase;

    public LoanController(LoanBookUseCase loanBookUseCase
                          ReturnBookUseCase returnBookUseCase) {

        this.loanBookUseCase = loanBookUseCase;
        this.returnBookUseCase = returnBookUseCase;
    }

    @PostMapping
    public ResponseEntity<LoanResponse> loanBook(@RequestBody LoanRequest request) {
        Loan loan = loanBookUseCase.loanBook(request.getUserId(), request.getBookId());

        return ResponseEntity.ok(LoanResponse.from(loan));
    }

    @PutMapping("/{loanId}/return")
    public ResponseEntity<Void> returnBook(@PathVariable String loanId) {
        returnBookUseCase.returnBook(loanId);
        return ResponseEntity.noContent().build();
    }
}

O adaptador de saída implementa a porta de repositório com JPA:

// infrastructure/out/persistence/JpaLoanRepository.java
@Repository
public class JpaLoanRepository implements LoanRepository {

    private final LoanJpaEntityRepository jpaRepository; // Spring Data JPA repository

    public JpaLoanRepository(LoanJpaEntityRepository jpaRepository) {
        this.jpaRepository = jpaRepository;
    }

    @Override
    public void save(Loan loan) {
        LoanJpaEntity entity = LoanJpaEntity.from(loan);
        jpaRepository.save(entity);
    }

    @Override
    public Optional<Loan> findById(String loanId) {
        return jpaRepository.findById(loanId)
            .map(LoanJpaEntity::toDomain);
    }

    @Override
    public List<Loan> findActiveByUser(String userId) {
        return jpaRepository.findByUserIdAndReturnDateIsNull(userId)
            .stream()
            .map(LoanJpaEntity::toDomain)
            .collect(Collectors.toList());
    }
}

⚠️ Atenção: Note a presença de LoanJpaEntity — uma classe de mapeamento separada da entidade de domínio Loan. Esse é um detalhe crítico: a entidade JPA pertence à infraestrutura e não deve ser a mesma classe da entidade de domínio. Misturar as duas coloca anotações JPA (@Entity, @Column, @Table) no domínio, que é exatamente o acoplamento que queremos evitar.

Testabilidade: o benefício mais tangível da Arquitetura Hexagonal

Uma das promessas mais concretas da Arquitetura Hexagonal é a testabilidade superior. Com a lógica de domínio isolada em classes que dependem apenas de interfaces, escrever testes unitários se torna direto e rápido.

Testando o domínio em isolamento

// LoanServiceTest.java
class LoanServiceTest {
    private BookRepository bookRepository;
    private LoanRepository loanRepository;
    private LoanService loanService;

    @BeforeEach
    void setUp() {

        // Mockito cria implementações fake das portas — sem banco, sem Spring
        bookRepository = mock(BookRepository.class);
        loanRepository = mock(LoanRepository.class);
        loanService = new LoanService(bookRepository, loanRepository);
    }

    @Test
    void shouldCreateLoanWhenBookIsAvailable() {
        // Arrange
        Book availableBook = new Book("book-1", "Clean Code", "978-0132350884");
        when(bookRepository.findById("book-1")).thenReturn(Optional.of(availableBook));

        // Act
        Loan result = loanService.loanBook("user-1", "book-1");

        // Assert
        assertNotNull(result);
        assertFalse(availableBook.isAvailable());
        verify(loanRepository).save(any(Loan.class));
    }

    @Test
    void shouldThrowExceptionWhenBookIsNotAvailable() {
    
        // Arrange
        Book unavailableBook = new Book("book-1", "Clean Code", "978-0132350884");
        unavailableBook.markAsLoaned(); // Livro já emprestado
        when(bookRepository.findById("book-1")).thenReturn(Optional.of(unavailableBook));

        // Act & Assert
        assertThrows(BookNotAvailableException.class, 
            () -> loanService.loanBook("user-1", "book-1"));
    }
}

Esses testes rodam em milissegundos, sem banco de dados, sem servidor HTTP, sem Spring context. A cobertura é precisa, o feedback é imediato e a manutenção é simples — porque o teste testa exatamente o que precisa testar: a lógica de negócio.

Vantagens concretas para times e projetos

Substituição de infraestrutura sem impacto no domínio

Precisa migrar do MySQL para o PostgreSQL? Trocar o banco relacional por um banco de documentos? Substituir o serviço de e-mail? Em um sistema com Arquitetura Hexagonal, essas mudanças se limitam a criar um novo adaptador de saída que implementa a porta existente. O domínio não muda. Os testes de domínio continuam passando. O risco é contido.

Desenvolvimento paralelo

Com portas bem definidas, diferentes membros do time podem trabalhar em paralelo sem bloquear uns aos outros. Um desenvolvedor implementa a lógica de domínio contra interfaces; outro implementa o adaptador de persistência; um terceiro implementa o controller HTTP. Enquanto as interfaces estiverem definidas, o trabalho pode acontecer em paralelo com mínima coordenação.

Onboarding mais rápido

Um novo desenvolvedor que entra no projeto consegue entender a lógica de negócio lendo apenas o código do domínio — sem precisar decodificar anotações de framework, queries SQL ou lógica de retry de HTTP embutida no meio das regras de negócio. O domínio é autoexplicativo porque é puro.

Longevidade do sistema

Frameworks envelhecem. Bancos de dados são substituídos. APIs de terceiros mudam ou deixam de existir. A Arquitetura Hexagonal isola o domínio dessas mudanças inevitáveis. O núcleo de negócio bem projetado pode sobreviver a múltiplas gerações de infraestrutura.

Padrões que combinam com a Arquitetura Hexagonal

A Arquitetura Hexagonal não existe no vácuo — ela se integra naturalmente com outros padrões de design que compartilham os mesmos princípios de separação de responsabilidades.

Domain-Driven Design (DDD) é a combinação mais natural. DDD fornece a linguagem e as ferramentas para modelar o domínio com riqueza — entidades, value objects, agregados, serviços de domínio, eventos de domínio. A Arquitetura Hexagonal fornece a estrutura que protege esse domínio da infraestrutura. Os dois juntos produzem sistemas onde o código reflete fielmente o negócio e é ao mesmo tempo altamente testável e evolutível.

CQRS (Command Query Responsibility Segregation) separa operações de escrita (commands) de operações de leitura (queries). Em combinação com a Arquitetura Hexagonal, CQRS define portas distintas para cada tipo de operação, permitindo otimizações independentes — como usar um modelo de leitura desnormalizado sem contaminar o modelo de domínio responsável pelas regras de negócio.

Event Sourcing representa o estado do sistema como uma sequência imutável de eventos em vez de estado atual. Combinado com a Arquitetura Hexagonal, os eventos de domínio são publicados pelo núcleo e consumidos por adaptadores — criando uma fronteira clara entre o que aconteceu (domínio) e o que fazer com isso (infraestrutura).

Microservices e Arquitetura Hexagonal se complementam: cada microsserviço implementado com Arquitetura Hexagonal tem seu domínio isolado internamente, enquanto a comunicação entre serviços acontece através de adaptadores (HTTP, mensageria) — o mesmo padrão de portas e adaptadores, aplicado em escala maior.

Quando adotar e quando não vale o esforço?

A Arquitetura Hexagonal tem custos reais. Mais classes, mais interfaces, mais mapeamento entre entidades de domínio e entidades de infraestrutura, mais abstração para navegar. Esses custos são justificados em muitos contextos — e não são justificados em outros.

Quando adotar:

  • Sistemas com lógica de negócio complexa que precisa ser testada de forma isolada e confiável
  • Projetos com longevidade esperada alta, onde a infraestrutura vai mudar ao longo do tempo
  • Times que trabalham com DDD e precisam de uma estrutura que proteja o modelo de domínio
  • Aplicações que precisam suportar múltiplos adaptadores de entrada (API REST + CLI + consumer de fila, por exemplo)
  • Sistemas que podem precisar migrar de tecnologia de banco de dados ou de framework no futuro

Quando reconsiderar:

  • CRUDs simples sem lógica de negócio significativa — o overhead de portas e adaptadores adiciona complexidade sem valor correspondente
  • Protótipos, MVPs e projetos de prazo curtíssimo onde o objetivo é validar uma ideia rapidamente
  • Scripts e ferramentas simples onde a separação de domínio e infraestrutura não tem sentido prático
  • Times sem familiaridade com o padrão que não têm tempo para a curva de aprendizado

💡 Dica: Uma abordagem pragmática para projetos novos é começar com uma estrutura mais simples e introduzir a Arquitetura Hexagonal progressivamente à medida que a lógica de negócio cresce e os pontos de acoplamento problemáticos ficam visíveis. Refatorar para Hexagonal é mais difícil do que começar com ela, mas é possível — e às vezes é a escolha certa quando a complexidade justifica o investimento.

Perguntas frequentes sobre Arquitetura Hexagonal

Qual é a diferença entre Arquitetura Hexagonal e Clean Architecture?


As duas compartilham o mesmo princípio central — isolar a lógica de negócio de dependências externas através de inversão de dependência. A Clean Architecture de Robert C. Martin é mais prescritiva sobre camadas (Entities, Use Cases, Interface Adapters, Frameworks & Drivers) e sobre a direção das dependências entre elas. A Arquitetura Hexagonal é mais agnóstica sobre a estrutura interna do domínio, focando principalmente na fronteira entre domínio e infraestrutura. Na prática, as duas se complementam bem e muitas implementações combinam conceitos das duas.

A Arquitetura Hexagonal é adequada para projetos pequenos?


Para projetos muito simples — CRUDs sem lógica de negócio, protótipos, scripts — o overhead de portas, adaptadores e mapeamentos pode não se justificar. A Arquitetura Hexagonal entrega mais valor quando existe lógica de negócio real para proteger e quando a longevidade do projeto justifica o investimento em testabilidade e flexibilidade. A questão não é o tamanho do projeto, mas a complexidade da lógica de negócio e a expectativa de vida do sistema.

Como lidar com o mapeamento entre entidades de domínio e entidades de persistência?


O mapeamento é uma das partes mais trabalhosas da Arquitetura Hexagonal e um ponto onde times frequentemente buscam atalhos. A abordagem mais limpa é ter classes separadas: a entidade de domínio (sem anotações de framework) e a entidade JPA (com todas as anotações de persistência), com métodos de conversão nos adaptadores. Ferramentas como MapStruct podem reduzir o código de mapeamento. Em casos onde a simplicidade é prioritária, algumas equipes optam por usar a entidade JPA no domínio e aceitar a contaminação — uma decisão consciente de trade-off.

Como a Arquitetura Hexagonal se relaciona com injeção de dependências?


A injeção de dependências (DI) é o mecanismo que torna possível conectar adaptadores às portas em tempo de execução sem que o domínio precise conhecer as implementações concretas. Frameworks como Spring (Java), Dagger (Android) ou equivalentes em outras linguagens injetam os adaptadores nas portas corretas na inicialização da aplicação. O domínio recebe interfaces através do construtor e não sabe — nem precisa saber — qual implementação concreta está sendo usada.

É possível aplicar Arquitetura Hexagonal em sistemas legados?


Sim, mas exige uma estratégia de migração gradual. A abordagem mais comum é o “strangler fig pattern”: identificar um módulo ou funcionalidade, extrair a lógica de negócio para um domínio isolado, criar portas e adaptadores para encapsular as dependências externas, e migrar progressivamente. Tentar refatorar o sistema inteiro de uma vez raramente funciona — a migração incremental, módulo a módulo, é mais segura e entrega valor ao longo do caminho.

Arquitetura Hexagonal é sobre preservar o que importa

Ao longo deste artigo, ficou claro que a Arquitetura Hexagonal não é uma bala de prata nem uma solução para todos os problemas de arquitetura de software. É uma resposta específica e bem fundamentada para um problema específico: como isolar a lógica de negócio da infraestrutura para que ela possa ser desenvolvida, testada e evoluída independentemente.

Os três benefícios centrais que ela entrega quando bem implementada são: testabilidade superior (lógica de negócio testável sem infraestrutura), flexibilidade de infraestrutura (adaptadores substituíveis sem impacto no domínio) e clareza de responsabilidades (cada classe tem um papel inequívoco no sistema).

O custo é real — mais abstração, mais classes, mais mapeamento. Mas em sistemas com lógica de negócio complexa e expectativa de vida longa, esse custo é um investimento com retorno claro: menos bugs em produção por mudanças de infraestrutura, onboarding mais rápido, e código que ainda faz sentido dois anos depois de ter sido escrito.

Comece pelo domínio. Defina as portas antes de pensar nos adaptadores. Teste o domínio em isolamento. Deixe a infraestrutura ser um detalhe.

👉 Compartilhe este guia com o time antes de começar o próximo projeto ou refatoração — pode ser a base para uma conversa sobre arquitetura que vai economizar semanas de trabalho no futuro.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *