Como criar tópicos no Kafka pelo Spring Boot

Data da publicação: 13/09/2025.

Neste tutorial vou explicar e exemplificar como que funciona a arquitetura do Kafka

1 Arquitetura básica do Kafka - Cluster, Tópicos, Partições e Réplica

Antes mesmo de criar os tópicos, é bom entender como que o Kafka funciona.

Para cada tópico existirá um número de partições, e para cada partição existirá um número de replicações.

As partições dos tópicos do Kafka são uma forma de você conseguir consumir dados de forma paralela, ou seja, você poderá ter um consumidor que subscreva cada partição, fazendo assim que você consiga consumir uma quantidade maior de mensagens em um menor tempo, pois as mensagens serão consumidas paralelamente.

Entretanto, caso você precisa considerar que ao ter mais de uma partição e mais de um consumidor para o mesmo tópico, as mensagens NÃO serão consumidas na ordem de chegada, o que acontecerá é que para cada partição sim, elas serão consumidas na ordem de chegada, mas caso tenha chego uma mensagem em uma partição e outra em outra partição, poderá acontecer da segunda mensagem ser consumida primeiro, caso o consumidor responsável pela segunda partição seja "mais rápido".

Outro ponto que é importante salientar sobre as partições, é que você pode ter um consumidor para cada partição, ou seja, caso você tenha três partições, então você poderá ter até três consumidores e, caso você coloque um quarto consumidor, esse quarto consumidor ficará em espera, então ele NÃO consumirá nenhuma mensagem, ele só começará a consumir em caso de algum dos outros três consumidores, por algum motivo, pare de consumir mensagens.

Além das partições, existe também o número de replicações. Lembre-se que a idéia do Kafka é ser um cluster, ou seja, ter várias máquinas para distribuir o processamento, sendo assim o número de replicações se refere a quantidade de replicas que você deseja ter para cada partição. Definindo um número maior que 1, você conseguirá ter duplicação de dados, tornando seu cluster maior tolerante a falha e perda dados, pois o Kafka utilizará esse número para replicar o dado em mais de nó (máquina) do cluster. Por exemplo, caso você defina o número de replicação para 2 e você tenha 4 máquinas no cluster, isso significa que a mensagem será entregue em duas máquinas desse cluster, caso aconteça algum problema em uma dessas duas máquinas, o dado ainda estará salvo na outra máquina, evitando assim a perda do dado.

Desenho da arquitetura do Kafka exemplificando um cluster com 4 máquinas, 1 tópico com 2 partições e com 2 replicações.

Agora que você já entendeu o conceito básico atrás do Kafka, vamos por a mão na massa!

2 Criação do tópico - Partições e Replicação

É importante informar que vou considerar que você já possui conhecimento em como utilizar o Kafka, como rodá-lo no Docker, como fazer a integração com o Kafka no Java e Spring Boot. Caso tenha dúvidas, por favor veja meu outro tutorial de como integrar Kafka com Java e Spring Boot

Comece subindo o servidor do Kafka no seu Docker, então o próximo passo será criar um novo tópico.

Para a criação de um novo tópico no Kafka vamos utilizar a classe do Spring Boot chamada KafkaAdmin. Como nós estamos rodando o Kafka em localhost e com a porta padrão 9092, então não precisamos alterar nada no application properties para rodar o projeto. Garanta que você possua as dependências do Kafka para o Spring Boot e então você poderá utilizar a injeção de dependência para criar um objeto da classe KafkaAdmin.

Print screen da tela do Eclipse exibindo as dependências do arquivo pom.xml

Crie um novo pacote chamado "controller", e dentro desse pacote crie a classe "TopicoController". Vamos criar Rest APIs para criar um novo tópico e listar os tópicos existentes. Caso queira ver mais detalhes em como criar APIs, veja meu tutorial de como criar sua primeira API.

A rota será "/topicos", e dentro do controller injete a dependência do KafkaAdmin.

Agora crie um outro pacote chamado "dto", e dentro desse pacote crie a classe "ReplicaDto", dentro dessa classe crie os atributos privados host do tipo String e porta do tipo int. Crie os gets e sets para eles.

Print screen da tela do Eclipse exibindo a classe ReplicaDto

Ainda no pacote "dto", crie outra classe chamada "ParticaoDto" e dentro dessa classe crie os atributos privados numeroDaParticao do tipo int e replicacoes do tipo List de ReplicacaoDto. Crie os gets e sets.

Print screen da tela do Eclipse exibindo a classe ParticaoDto

Por último, ainda dentro do pacote "dto", crie a classe "TopicoDto" e dentro dela crie os atributos privados nome do tipo String e particoes do tipo List de ParticaoDto. Crie os gets e sets.

Print screen da tela do Eclipse exibindo a classe TopicoDto

Volte para a classe "TopicoController" e crie um método público chamado "criar" e que retorne "TopicoDto". Esse método vai receber três parâmetros, String nome, Integer quantidadeDeParticoes e Short quantidadeDeReplicas. Anote cada parâmetro com "@RequestParam", e no caso do segundo e terceiro coloque "@RequestParam( required = false )", indicando que eles são opcionais. Dentro do método adicione a lógica de quando receber null no parâmetro opcional, atribua o valor de "-1". Para criar o tópico no Kafka, você precisará criar um objeto da classe NewTopic e atribuir os valores do nome, quantidadeDeParticoes e quantidadeDeReplicas, então basta chamar o método "createOrModifyTopics" do objeto que foi injetado "kafkaAdmin" e passar esse objeto que você acabou de criar como parâmetro. Nesse primeiro momento retorn nulo. Agora anote o método com "@PutMapping", execute o seu programa e teste a chamada via Postman utilizando "http://localhost:8080/topicos". Repare que utilizamos o método "createOrModifyTopics", sendo assim, ele irá criar o tópico se não existir, mas se existir ele irá alterá-lo, por isso utilizamos o método HTTP PUT ao invés de POST.

Print screen da tela do Eclipse exibindo a classe TopicoController

Agora crie um método público chamado "encontrar" que receba uma String nome, retorne uma List de TopicoDto e anote ele com "@GetMapping". Anote o parâmetro com "@RequestParam( required = false)", pois esse parâmetro não será obrigatório, quando ele não for preenchido retornaremos todos os tópicos existentes. Esse método será um pouco mais complicado, primeiro declare uma variável do tipo List de String chamado "nomesTopicos". Então verifique se o nome foi passado, caso positivo atribua o valor para "nomesTopicos" com "List.of(nome)", caso negativo você precisará criar um objeto da classe AdminClient, e para isso use o método estático da classe KafkaAdminClient chamado "create" passando como parâmetro "kafkaAdmin.getConfigurationProperties()", isso fará que seja utilizado as configurações existentes no objeto que foi injetado pelo Spring. Após criar esse objeto, atribua o valor para a variável "nomesTopicos" com o retorno da cadeia de métodos "listTopics().names().get().stream().toList()" do objeto criado da classe AdminClient. Essa cadeia de método significa que você quer a lista de tópicos, então você quer pegar o nome dos tópicos e transformar os nomes em uma lista.

Na próxima linha crie uma variável chamada "mapaTopicDescription" do tipo Map de String e TopicDescription, atribua o valor dessa variável à partir do retorno do método "describeTopics" passando o "nomesTopicos.toArray(new String[0])" como parâmetro do objeto "kafkaAdmin". Repare que usamos o método "toArray" para converter uma List de String em um Array de String. Pronto, com essas linhas já conseguimos retornar do Kafka as informações necessárias para preencher nossa lista de TopicoDto, para isso precisaremos converter a variável que criamos "mapaTopicDescription" na lista que queremos. Na imagem abaixo segue o método com uma forma de conversão utilizando o Lambda.

Print screen da tela do Eclipse exibindo a classe TopicoController - Método encontrar

Execute sua aplicação e teste pelo navegador utilizando "http://localhost:8080/topicos", então deverá retornar a lista de tópicos.

Print screen da tela do Navedor Chrome com os tópicos criados

O último método que vamos fazer será o método para excluir os tópicos. Crie um método público void chamado "excluir" e receba uma String nome como parâmetro. Anote esse paràmetro com "@PathVariable" e anote o método com "@DeleteMapping( "/{nome}" )". Repare que o parâmetro é um "PathVarible" e não um "RequestParam", sendo assim ele será passado diretamente na URL, por exemplo, suponha que você queira excluir um tópico chamado "meu-primeiro-topico", então você deverá chamar a URL "http://localhost:8080/topicos/meu-primeiro-topico". Dentro do método valide se a String não é nula e se esta preenchida, caso positivo crie um objeto com o nome "adminClient" da classe "AdminClient" e receba o retorno do método estático "create" da classe "KafkaAdminClient" passando como parâmetro "kafkaAdmin.getConfigurationProperties()". Na linha seguinte basta chamar o método "deleteTopics" enviando "Collections.singletonList(nome)" do objeto adminClient e pronto, o tópico será excluído.

Print screen da tela do Eclipse exibindo a classe TopicoController

Repare que estamos criando o objeto "adminClient" da classe AdminClient em dois métodos, no encontrar e no excluir, sendo assim vamos extrair esse objeto para uma classe de configurações. Crie um novo pacote chamado "config" e dentro desse pacote crie um classe chamada "KafkaConfig". Anote essa classe com "@Configuration" e crie um metódo público chamado adminClient que retorne AdminClient e que receba um objeto chamado "kafkaAdmin" da classe "KafkaAdmin" e que esse parâmetro esteja anotado com "@Autowired", para garantir que o Spring injete a dependência. Agora anote o método com "@Bean", para que o Spring deixe ele disponível para ser injetado. dentro do método você só precisa retornar o retorno do método estático "create" da classe "KafkaAdminClient" passando como parâmetro "kafkaAdmin.getConfigurationProperties()", que são as propriedades referentes à conexão com o Kafka.

Print screen da tela do Eclipse exibindo a classe KafkaConfig

Volte para a classe TopicoController e remova as linhas que estavam criando o objeto de "adminClient" no método encontrar e no método excluir. Agora crie um atributo privado chamado "adminClient" da classe "AdminClient" e anote ele com "@Autowired". Feito isso você já pode executar novamente a aplicação e testar novamente para ver que tudo está funcionando normalmente!

Print screen da tela do Eclipse exibindo a injeção de dependência do objeto adminClient

Lembre-se que estamos rodando o Kafka localmente, sendo assim não será possível a criação do tópico com mais de uma réplica, pois para isso o cluster do Kafka precisaria ter mais de uma máquina.

Conclusão

Após fazer esse tutorial você conseguiu entender um pouco da arquitetura do Kafka e criar, alterar, excluir e listar os tópicos do Kafka utilizando o Spring Boot, então Parabééééns!! Espero que continue progredindo nos seus estudos!

Assista também o vídeo no youtube