EventoObtenha 50% de desconto no seu ingresso para MongoDB.local Londres em outubro 2. Use o código WEB50Saiba mais >>
Desenvolvedor MongoDB
Central de desenvolvedor do MongoDBchevron-right
Idiomaschevron-right
Javachevron-right

Inicialização reativa do Java Spring com MongoDB

Teo Wen Jie5 min read • Published Apr 02, 2024 • Updated Apr 02, 2024
SpringMongoDBJava
APLICATIVO COMPLETO
Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse exemplo de código
star-empty
star-empty
star-empty
star-empty
star-empty
social-githubVer código

Introdução

Spring Boot + Reactive + Spring Data + MongoDB. Unir essas quatro tecnologias pode ser um desafio, especialmente se você está apenas começando. Sem entrar em detalhes de cada uma dessas tecnologias, este tutorial tem como objetivo ajudá-lo a dar um salto inicial em uma base de código funcional com base nessa pilha de tecnologias. Este tutorial apresenta:
  • Interagindo com o MongoDB usando ReactiveMongoRepositores.
  • Interagindo com o MongoDB usando o ReactiveMongoTemplate.
  • Agrupando consultas em uma transação ACID multidocumento.
Esse aplicativo simplificado de saldo de caixa permite fazer chamadas da REST API para:
  • Criar ou buscar uma conta.
  • Realizar transações em uma conta ou entre duas contas.

Repositório do GitHub

Acesse o README do repositório para obter mais detalhes sobre as especificações funcionais. O README também contém instruções de configuração, uso da API e teste. Para clonar o repositório:

Passo a passo do código

Vamos fazer um passo a passo lógico de como o código funciona. Eu incluiria trechos de código, mas para reduzir a verbosidade, excluirei linhas de código que não são essenciais para nossa compreensão de como o código funciona.

Criando ou buscando uma conta

Esta seção mostra como você pode executar operações de criação e leitura com ReactiveMongoRepository.
Os endpoints da API para criar ou buscar uma conta podem ser encontrados em accountController.java:
Este trecho mostra dois endpoints:
  • Um endpoint do método POST que cria uma conta
  • Um endpoint do método GET que recupera uma conta, mas lança uma exceção se ela não puder ser encontrada
Ambos simplesmente retornam um Mono<Account> de AccountRepository.java, uma interfaceReactiveMongoRespository que atua como uma abstração do Reactive Streams Driversubjacente.
  • .save(...) O método cria um novo documento na coleção de contas em nosso MongoDB database.
  • .findByAccountNum() O método busca um documento que corresponde ao accountNum.
A anotação @Query permite especificar uma query do MongoDB com espaços reservados para que ela possa ser substituída dinamicamente por valores de argumentos de método. ?0 seria substituído pelo valor do primeiro argumento de método e ?1 seria substituído pelo segundo, e assim por diante.
O mecanismo de construtor de queryembutido pode realmente determinar a query destinada com base no nome do método. Nesse caso, poderíamos excluir a anotação @Query, mas deixei-a lá para maior clareza e para ilustrar o ponto anterior.
Observe que não há necessidade de declarar um métodosave(...), embora estejamos usando accountRepository.save() no accountcontroller.java. O métodosave(...) e muitos outros métodos básicos já estão declarados por interfaces na cadeia de herança de ReactiveMongoRepository.

Debit, crédito e transferência

Esta seção mostra:
  • Atualizar operações com ReactiveMongoRepository.
  • Operações de criação, leitura e atualização com ReactiveMongoTemplate.
Voltar para AccountController.java:
Este snippet mostra três endpoints:
  • Um endpoint.../debit que adiciona ao saldo de uma conta
  • Um endpoint.../credit que subtrai do saldo de uma conta
  • Um endpoint.../transfer que executa uma transferência de uma conta para outra
Observe que todos os três métodos são muito semelhantes. A ideia principal é:
  • Um Txn pode consistir em um para muitos TxnEntry.
  • Um TxnEntry é o reflexo de uma alteração que estamos prestes a fazer em uma única conta.
  • Um débito ou crédito Txn terá apenas um TxnEntry.
  • Uma transferência Txn terá dois TxnEntry.
  • Em todas as três operações, primeiro salvamos um registro do Txn que estamos prestes a executar e, em seguida, usamos o TxnService.javapara fazer as alterações desejadas nas contas de destino.
O métodoupdateBalances(...) é responsável por iterar cada TxnEntry e fazer as atualizações correspondentes a cada conta. Isso é feito chamando o métodofindAndIncrementBalanceByAccountNum(...) em accountRespository.java.
Semelhante à declaração de métodosfind, você também pode declarar métodos de manipulação de dados no ReactiveMongoRepository, como métodosupdate . Mais uma vez, o mecanismo do construtor de consultas é capaz de determinar que estamos interessados em consultar por accountNum com base na nomenclatura do método e definimos a ação de uma atualização usando a anotação@Update. Nesse caso, a ação é um $inc e observe que usamos ?1 como espaço reservado porque queremos substituí-lo pelo valor do segundo argumento do método.
Seguindo em frente, em TxnService também temos:
  • Um métodosaveTransaction que salva um documento Txnna collectiontransactions.
  • Um métodoexecuteTxn que chama updateBalances(...) e atualiza o status da transação no documentoTxn criado.
Ambos utilizam o TxnTemplate que contém um ReactiveMongoTemplate.
O ReactiveMongoTemplate nos fornece maneiras mais personalizáveis de interagir com MongoDB e é uma camada mais fina de abstração em comparação com ReactiveMongoRepository.
No métodofindAndUpdateStatusById(...), estamos definindo praticamente a lógica da query por código, mas também podemos especificar que a atualização deve retornar o documento recém-atualizado.

Transações ACID multidocumento

O recurso de transferência neste aplicativo é um caso de uso perfeito para transações com vários documentos, pois as atualizações em duas contas precisam ser atômicas.
Para que o aplicativo obtenha acesso ao suporte de transações do Spring, primeiro precisamos adicionar um ReactiveMongoTransactionManager bean à nossa configuração da seguinte forma:
Com isso, podemos definir o escopo de nossas transações. Mostraremos dois métodos:
1. Como usar o TransactionalOperator
O ReactiveMongoTransactionManager nos fornece um TransactionOperator.
Podemos então definir o escopo de uma transação anexando .as(transactionalOperator::transactional) à chamada do método.
2. Usando a anotação @Transactional
Também podemos simplesmente definir o escopo de nossa transação anotando o método com a anotação@Transactional.
Leia mais sobre transações e sessões no Spring Data MongoDB para obter mais informações.

Conclusão

Terminamos! Esperemos que esta publicação tenha sido útil para você de uma forma ou de outra. Se você tiver alguma dúvida, visite a MongoDB Community, onde os engenheiros do MongoDB e a comunidade podem ajudá-lo com sua próxima grande ideia!
Mais uma vez, você pode acessar o código a partir do repositório GitHube, se estiver apenas começando, pode valer a pena marcar o Spring Data MongoDBcomo favorito.
Principais comentários nos fóruns
Ainda não há comentários sobre este artigo.
Iniciar a conversa

Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse exemplo de código
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Tutorial

Como se conectar ao MongoDB com um proxy SOCKS5 com Java


Aug 29, 2024 | 2 min read
Tutorial

Introdução ao Azure Spring Apps e ao MongoDB Atlas: um guia passo a passo


Jan 27, 2024 | 5 min read
Tutorial

Projetos de coleção única no MongoDB com dados Spring (Parte 1)


Sep 09, 2024 | 10 min read
Tutorial

Construtores de expressões de agregação Java no MongoDB


Apr 02, 2024 | 11 min read
Tecnologias Utilizadas
Linguagens
Tecnologias
Produtos
Sumário
  • Introdução