Menu Docs
Página inicial do Docs
/ /

Tutorial: Integração com o Spring Boot

O Spring Boot é uma estrutura Java de código aberto que simplifica o desenvolvimento de aplicativos prontos para produção. Quando combinada com o Spring Data MongoDB, essa estrutura fornece uma maneira eficiente de interagir com bancos de dados MongoDB .

Este tutorial demonstra como construir um aplicação reativo de inicialização de inicialização que utiliza o Spring Data MongoDB para executar operações em um banco de dados MongoDB . Você pode usar esse exemplo de aplicação de saldo de caixa para chamar APIs REST que executam as seguintes ações:

  • Criar ou buscar uma conta

  • Realizar transações em uma conta ou entre duas contas

Spring Data MongoDB fornece suporte de repositório para MongoDB, oferecendo duas maneiras principais de interagir com o banco de dados:

  • ReactiveMongoRepository: Uma abstração de nível superior que fornece acesso a operações comuns do banco de dados

  • ReactiveMongoTemplate: Uma abstração de nível inferior que oferece mais controle sobre as operações do MongoDB e a construção de queries

O MongoDB oferece suporte a transações ACID de vários documentos, que permitem executar várias operações que atendem garantias de atomicidade, consistência, isolamento e durabilidade. O Spring Data MongoDB oferece suporte integrado para transações por meio da anotação @Transactional ou da classe TransactionalOperator. O aplicação de amostra neste tutorial configura o suporte a transações para garantir a atomicidade das operações do banco de dados .

Para saber mais sobre transações MongoDB , consulte Transações no manual do MongoDB Server .

Este tutorial mostra como baixar um exemplo de aplicação que implementa um sistema simplificado de saldo de caixa. O aplicação permite criar, recuperar e atualizar o saldo de contas bancárias. Para visualizar a aplicação completa, consulte o repositório GitHub mdb-spring-boot-reactive.

Conclua o tutorial para saber como executar as seguintes ações:

  • Baixe um exemplo de aplicação Spring Boot

  • Configure o aplicação para se conectar ao MongoDB

  • Compreender a estrutura do aplicação e os principais componentes

  • Execute o aplicativo

  • Enviar solicitações POST para criar contas bancárias e realizar transações

1

Antes de iniciar este tutorial, verifique se você tem os seguintes componentes preparados:

2

Clone o aplicação de exemplo do repositório do MongoDB Developer GitHub executando o seguinte comando:

git clone git@github.com:mongodb-developer/mdb-spring-boot-reactive.git

Este repositório contém um aplicação reativo Spring Boot que usa o Spring Data MongoDB para interagir com um banco de dados MongoDB .

3

Navegue até o arquivo src/main/resources/application.properties no diretório do aplicação de exemplo . Neste arquivo, defina a propriedade spring.data.mongodb.uri para seu URI de conexão do Atlas , conforme mostrado no código a seguir:

spring.data.mongodb.uri=<connection URI>

Substitua o espaço reservado <connection URI> pelo URI de conexão do Atlas .

4

No diretório raiz, execute o seguinte comando para configurar a validação de esquema para seu aplicação:

mongosh "<connection URI>" --file setup.js

Este comando cria uma restrição que garante que o saldo da conta bancária nunca fique abaixo de 0. Substitua o espaço reservado <connection URI> pelo URI de conexão do Atlas .

1

O arquivo AccountController.java contém endpoints da API REST para criar e buscar contas. O arquivo define um endpoint de método POST que insere um documento na coleção txn-demo.accounts e um endpoint de método GET que encontra um documento com base em seu valor de accountNum. O seguinte código mostra estes métodos:

@RestController
public class AccountController {
//...
@PostMapping("/account")
public Mono<Account> createAccount(@RequestBody Account account) {
return accountRepository.save(account);
}
@GetMapping("/account/{accountNum}")
public Mono<Account> getAccount(@PathVariable String accountNum) {
return accountRepository.findByAccountNum(accountNum)
.switchIfEmpty(Mono.error(new AccountNotFoundException()));
}
//...
}

Cada endpoint retorna um tipo Mono<Account> de AccountRepository, uma interface ReactiveMongoRepository que atua como uma abstração do driver Java Reactive Streams subjacente.

2

A classe AccountController também inclui os seguintes endpoints de transação:

  • Um endpoint .../debit que adiciona ao saldo de uma conta

  • Um endpoint .../credit que subtrai de um saldo de conta

  • Um endpoint .../transfer que executa uma transferência de uma conta para outra

Esses endpoints têm as seguintes definições:

@RestController
public class AccountController {
//...
@PostMapping("/account/{accountNum}/debit")
public Mono<Txn> debitAccount(@PathVariable String accountNum,
@RequestBody Map<String, Object> requestBody) {
//...
txn.addEntry(new TxnEntry(accountNum, amount));
return txnService.saveTransaction(txn).flatMap(txnService::executeTxn);
}
@PostMapping("/account/{accountNum}/credit")
public Mono<Txn> creditAccount(@PathVariable String accountNum,
@RequestBody Map<String, Object> requestBody) {
//...
txn.addEntry(new TxnEntry(accountNum, -amount));
return txnService.saveTransaction(txn).flatMap(txnService::executeTxn);
}
@PostMapping("/account/{from}/transfer")
public Mono<Txn> transfer(@PathVariable String from,
@RequestBody TransferRequest transferRequest) {
//...
txn.addEntry(new TxnEntry(from, -amount));
txn.addEntry(new TxnEntry(to, amount));
return txnService.saveTransaction(txn).flatMap(txnService::executeTxn);
}
//...
}

Um objeto TxnEntry representa uma alteração em uma única conta, e um Txn pode consistir em um ou vários objetos TxnEntry. No código de amostra, os endpoints de crédito e crédito criam um novo objeto TxnEntry, e o endpoint de transferência cria dois objetos TxnEntry.

3

A interface do AccountRepository estende o ReactiveMongoRepository e define os seguintes métodos de query:

public interface AccountRepository extends ReactiveMongoRepository<Account, String> {
@Query("{accountNum:'?0'}")
Mono<Account> findByAccountNum(String accountNum);
@Update("{'$inc':{'balance': ?1}}")
Mono<Long> findAndIncrementBalanceByAccountNum(String accountNum, double increment);
}

Os códigos usam as seguintes anotações que permitem usar espaços reservados ao executar query do MongoDB, que são dinamicamente substituídos por argumentos do método:

  • @Query: Anota o método findByAccountNum() e especifica os critérios de query para localizar documentos. O espaço reservado ?0 é substituído pelo valor de parâmetro accountNum .

  • @Update: anota o método findAndIncrementBalanceByAccountNum() e especifica a operação de atualização a ser executada nos documentos correspondentes. O espaço reservado ?1 é substituído pelo valor do parâmetro increment para aumentar o equilíbrio usando o operador $inc do MongoDB.

Observação

Embora o endpoint POST descrito em uma etapa anterior utilize o accountRepository.save() método, você não precisa definir este método. O save() método e muitos outros métodos básicos já estão declarados por interfaces na cadeia de herança ReactiveMongoRepository de.

4

A classe TxnService lida com a execução da transação. Esta classe inclui o seguinte código:

@Service
public class TxnService {
//...
public Mono<Txn> saveTransaction(Txn txn) {
return txnTemplate.save(txn);
}
public Mono<Txn> executeTxn(Txn txn) {
return updateBalances(txn)
.onErrorResume(DataIntegrityViolationException.class
/*lambda expression to handle error*/)
.onErrorResume(AccountNotFoundException.class
/*lambda expression to handle error*/)
.then(txnTemplate.findAndUpdateStatusById(txn.getId(), TxnStatus.SUCCESS));
}
public Flux<Long> updateBalances(Txn txn) {
Flux<Long> updatedCounts = Flux.fromIterable(txn.getEntries()).concatMap(
entry -> accountRepository.findAndIncrementBalanceByAccountNum(
entry.getAccountNum(), entry.getAmount())
);
return updatedCounts.handle(/*...*/);
}
}

A classe TxnService inclui os seguintes métodos:

  • saveTransaction(): salva um documento Txn na coleção transactions

  • executeTxn(): chama o método updateBalances() e atualiza o status da transação no documento Txn

  • updateBalances(): Itera por cada TxnEntry e faz as atualizações correspondentes a cada documento account

5

Os métodos saveTransaction() e executeTxn() descritos na etapa anterior usam métodos definidos na classe TxnTemplate . Esses métodos têm as seguintes definições:

@Service
public class TxnTemplate {
//...
public Mono<Txn> save(Txn txn) {
return template.save(txn);
}
public Mono<Txn> findAndUpdateStatusById(String id, TxnStatus status) {
Query query = query(where("_id").is(id));
Update update = update("status", status);
FindAndModifyOptions options = FindAndModifyOptions.options().returnNew(true);
return template.findAndModify(query, update, options, Txn.class);
}
//...
}

Estes métodos interagem com MongoDB utilizando o ReactiveMongoTemplate.

6

Ao transferir dinheiro entre contas, você pode usar uma transação com vários documentos. As atualizações em duas contas devem ser atômicas, e as transações garantem a atomicidade dos dados.

Para acessar o suporte a transações do Spring, o aplicação de amostra adiciona o ReactiveMongoTransactionManager bean ao arquivo ReactiveMongoConfig.java:

@Configuration
public class ReactiveMongoConfig extends AbstractReactiveMongoConfiguration {
//...
@Bean
ReactiveMongoTransactionManager transactionManager(ReactiveMongoDatabaseFactory dbFactory) {
return new ReactiveMongoTransactionManager(dbFactory);
}
}

Você pode definir o escopo de uma transação usando um objeto TransactionalOperator ou a anotação @Transactional. A classe TxnService mostra ambas as abordagens.

Dica

Transações de dados da primavera

Para saber mais sobre transações e sessões no Spring Data MongoDB, consulte Sessões e transações na documentação do Spring Data.

1

Para iniciar o aplicação, execute os seguintes comandos no diretório raiz do projeto:

mvn spring-boot:run

Após iniciar o aplicação, você pode acessá-lo em http://localhost:8080. Em seguida, você pode usar os endpoints da API REST para criar contas e executar transações.

2

Para criar uma nova conta bancária que tenha um número de conta de 12345, execute o seguinte comando na sua shell:

curl --location 'localhost:8080/account' \
--header 'Content-Type: application/json' \
--data '{
"accountNum": "12345"
}'

Este comando envia uma solicitação POST para o endpoint /account para criar um novo documento de conta bancária na coleção accounts.

3

Para devolver o valor à conta criada na etapa anterior, execute o seguinte comando em seu shell:

curl --location 'localhost:8080/account/12345/debit' \
--header 'Content-Type: application/json' \
--data '{
"amount": 1000
}'

Este comando envia uma solicitação ao endpoint .../debit para aumentar o valor amount do documento account correspondente em 1000.

4

Para transferir dinheiro de uma conta para outra, crie uma nova conta que tenha um número de conta de 67890:

curl --location 'localhost:8080/account' \
--header 'Content-Type: application/json' \
--data '{
"accountNum": "67890"
}'

Em seguida, transfira 500 dólares para esta nova conta executando o seguinte comando:

curl --location 'localhost:8080/account/12345/transfer' \
--header 'Content-Type: application/json' \
--data '{
"to": "67890",
"amount": 500
}'

Este comando envia uma solicitação para o endpoint .../transfer para concluir a transferência de saldo.

Para saber mais sobre o Spring Data MongoDB, consulte a documentação de referência do Spring Data MongoDB .

Para visualizar o aplicação de exemplo completo, consulte o repositório GitHub mdb-spring-boot-reactive.

Voltar

Criptografia em execução

Nesta página