Explore o novo chatbot do Developer Center! O MongoDB AI chatbot pode ser acessado na parte superior da sua navegação para responder a todas as suas perguntas sobre o MongoDB .

Junte-se a nós no Amazon Web Services re:Invent 2024! Saiba como usar o MongoDB para casos de uso de AI .
Desenvolvedor do MongoDB
Central de desenvolvedor do MongoDBchevron-right
Idiomaschevron-right
Javachevron-right

APIs REST com Java, Spring Boot e MongoDB

Maxime Beugnet4 min read • Published Oct 25, 2023 • Updated Oct 25, 2023
SpringJava
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

Repositório do GitHub

Se você quiser escrever API REST em Java na velocidade da luz, tenho o que você precisa. Escrevi este modelo para você começar. Procurei resolver o maior número possível de problemas nele.
Portanto, se você quiser escrever APIs REST em Java, clone este projeto e estará pronto para começar num instante.
1git clone https://github.com/mongodb-developer/java-spring-boot-mongodb-starter
Isso é tudo, gente! Tudo o que você precisa está neste repositório. A seguir, explicarei alguns dos recursos e detalhes sobre esse modelo, mas fique à vontade para ignorar o que não for necessário para sua compreensão.

README

Todas as informações e comandos adicionais de que você precisa para iniciar este projeto estão no arquivo README.md, que pode ser lido no GitHub.

Configuração do Spring e MongoDB

A configuração pode ser encontrada na classe MongoDBConfiguration.java.
1package com.mongodb.starter;
2
3import [...]
4
5import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
6import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;
7
8@Configuration
9public class MongoDBConfiguration {
10
11 @Value("${spring.data.mongodb.uri}")
12 private String connectionString;
13
14 @Bean
15 public MongoClient mongoClient() {
16 CodecRegistry pojoCodecRegistry = fromProviders(PojoCodecProvider.builder().automatic(true).build());
17 CodecRegistry codecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), pojoCodecRegistry);
18 return MongoClients.create(MongoClientSettings.builder()
19 .applyConnectionString(new ConnectionString(connectionString))
20 .codecRegistry(codecRegistry)
21 .build());
22 }
23
24}
A seção importante aqui, naturalmente, é a configuração do MongoDB. Em primeiro lugar, você notará que a string de conexão é automaticamente recuperada do arquivo application.properties e, em segundo lugar, você notará a configuração do bean MongoClient.
Um Codec é a interface que abstrai os processos de decodificação de um valor BSON em um objeto Java e de codificação de um objeto Java em um valor BSON.
Um CodecRegistry contém um conjunto de instâncias do Codec que são acessadas de acordo com as classes Java que codificam e decodificam.
O driver do MongoDB é capaz de codificar e decodificar BSON para nós, portanto, não precisamos mais lidar com isso. Toda a configuração de que precisamos para que este projeto seja executado está aqui e em nenhum outro lugar.
Você pode ler a documentação do driver se quiser saber mais sobre esse tópico.

Transações ACID multidocumento

Por nenhum motivo especial, também usei transações ACID multidocumento em alguns métodos em que poderia fazer sentido usar transações ACID. Você pode conferir todo o código na classe MongoDBPersonRepository.
Aqui está um exemplo:
1private static final TransactionOptions txnOptions = TransactionOptions.builder()
2 .readPreference(ReadPreference.primary())
3 .readConcern(ReadConcern.MAJORITY)
4 .writeConcern(WriteConcern.MAJORITY)
5 .build();
6
7@Override
8public List<PersonEntity> saveAll(List<PersonEntity> personEntities) {
9 try (ClientSession clientSession = client.startSession()) {
10 return clientSession.withTransaction(() -> {
11 personEntities.forEach(p -> p.setId(new ObjectId()));
12 personCollection.insertMany(clientSession, personEntities);
13 return personEntities;
14 }, txnOptions);
15 }
16}
Como você pode ver, estou usando um try-with-resources com fechamento automático, que fechará automaticamente a sessão do cliente no final. Isso me ajuda a manter o código limpo e simples.
Alguns de vocês podem argumentar que isso é simples demais porque as transação (e operações de gravação, em geral) podem lançar exceções, e não estou lidando com nenhuma delas aqui... Vocês estão absolutamente certos e essa é uma excelente transição para a próxima parte deste artigo.

Gerenciamento de exceções

As transações no MongoDB podem gerar exceções por vários motivos, e não gostaria de entrar muito em detalhes aqui, mas como o MongoDB 3.6, qualquer operação de gravação que falhar poderá ser automaticamente repetida uma vez. E as transações não são diferentes. Consulte a documentação para retryWrites.
Se as gravações repetitivas estiverem desabilitadas ou se uma operação de gravação falhar duas vezes, o MongoDB enviará uma MongoException (extende RuntimeException) que deve ser tratada corretamente.
Felizmente, o Spring fornece a anotação ExceptionHandler para nos ajudar a fazer isso. Veja o código no meu controlador PersonController. É claro que você precisará adaptar e aprimorar isso em seu projeto real, mas a ideia principal está aqui.
1@ExceptionHandler(RuntimeException.class)
2public final ResponseEntity<Exception> handleAllExceptions(RuntimeException e) {
3 logger.error("Internal server error.", e);
4 return new ResponseEntity<>(e, HttpStatus.INTERNAL_SERVER_ERROR);
5}

Pipeline de agregação

O pipeline de agregação do MongoDB é uma maneira muito poderosa e eficiente de executar suas queries complexas o mais próximo possível de seus dados para obter a máxima eficiência. Usá-la pode aliviar a carga computacional em seu aplicativo.
Só para dar um pequeno exemplo, implementei a rota /api/persons/averageAge para mostrar como posso recuperar a idade média das pessoas na minha coleção.
1@Override
2public double getAverageAge() {
3 List<Bson> pipeline = List.of(group(new BsonNull(), avg("averageAge", "$age")), project(excludeId()));
4 return personCollection.aggregate(pipeline, AverageAgeDTO.class).first().averageAge();
5}
Além disso, você pode observar aqui que estou usando o personCollection, que foi inicialmente instanciado assim:
1private MongoCollection<PersonEntity> personCollection;
2
3@PostConstruct
4void init() {
5 personCollection = client.getDatabase("test").getCollection("persons", PersonEntity.class);
6}
Normalmente, minha personCollection deve codificar e decodificar somente o objeto PersonEntity, mas você pode substituir o tipo de objeto que sua coleção está manipulando para retornar algo diferente — no meu caso, AverageAgeDTO.class, pois não estou esperando uma classe PersonEntity aqui, e sim um POJO que contenha apenas a idade média das minhas "pessoas".

Swagger

Swagger é a ferramenta de que você precisa para documentar suas API REST. Você não tem nada para fazer — a configuração é totalmente automatizada. Basta executar o servidor e navegar para http://localhost:8080/swagger-ui.html. A interface estará esperando por você.
A IU do Swagger
Você pode testar as APIs REST a partir desta página da web e explorar os modelos. Não se esqueça de desativá-lo na produção. ;-)
Isso é tudo que fiz para que funcionasse:
1<dependency>
2 <groupId>org.springdoc</groupId>
3 <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
4 <version>2.2.0</version>
5</dependency>
Consulte a documentação para obter mais informações.

Nyan Cat

Sim, há uma seção Nyan Cat nesta publicação. Nyan Cat é amor, e você precisa de um pouco de Nyan Cat em seus projetos. :-)
Você sabia que pode substituir o logotipo do Spring Boot nos registros por praticamente qualquer coisa que quiser?
Nyan Cat
Bem, agora você sabe. Você é bem-vindo.
Dê uma olhada no arquivo banner.txt se quiser substituir este incrível Nyan Cat pelo seu próprio logotipo personalizado.
Gosto de usar patorjk e a fonte "Epic" para cada nome de projeto. É mais fácil identificar qual arquivo de registro estou lendo no momento.

Conclusão

Espero que você goste do meu modelo. Posso ajudá-lo a ser mais produtivo com o MongoDB e a pilha Java.
Se você encontrar algo que pode ser melhorado, fique à vontade para abrir um problema no GitHub ou enviar diretamente uma solicitação de pull. Eles são muito bem-vindos. :-)
Se você for iniciante no MongoDB Atlas, confira nossa publicação de Início rápido para já se familiarizar com o MongoDB Atlas.

Í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

Java encontra Queryable Encryption: desenvolvendo um aplicativo de conta bancária seguro


Oct 08, 2024 | 14 min read
Tutorial

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


Aug 12, 2024 | 10 min read
Tutorial

Uso do Azure Kubernetes Services para microsserviços Java com Spring Boot


Apr 15, 2024 | 9 min read
Artigo

Java 21: desbloqueando o poder do driver Java MongoDB com threads virtuais


Jan 31, 2024 | 2 min read
Tecnologias Utilizadas
Linguagens
Tecnologias
Sumário