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 .

Desenvolvedor do MongoDB
Central de desenvolvedor do MongoDBchevron-right
Idiomaschevron-right
Javachevron-right

Como criar um aplicativo CRUD com MongoDB, Quarkus e GraalVM

Maxime Beugnet7 min read • Published Aug 29, 2024 • Updated Aug 29, 2024
QuarkusDockerMongoDBJava
APLICATIVO COMPLETO
Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Início rápido
star-empty
star-empty
star-empty
star-empty
star-empty

O que é o Qarkus?

Quando escrevemos um aplicativo Java tradicional, nosso código-fonte Java é compilado e transformado em bytecode Java. Esse bytecode pode ser executado por uma Java virtual machine (JVM) específica para o sistema operacional que você está executando. É por isso que podemos dizer que Java é uma linguagem portátil. Você compila uma vez e pode executá-lo em qualquer lugar, desde que tenha a JVM certa na máquina certa.
Este é um grande mecanismo, mas tem um custo. Iniciar um programa é lento porque o JVM e todo o contexto precisam ser carregados primeiro antes de executar qualquer coisa. Não é eficiente em termos de memória porque precisamos carregar centenas de classes que podem não ser usadas, pois a verificação do caminho de classeocorre somente depois de.
Isso funcionava perfeitamente no antigo reino monolítico, mas é totalmente inaceitável no novo mundo feito de Lambda, cloud, container e Kubernetes. Nesse contexto, um baixo consumo de memória e um tempo de inicialização extremamente rápido são absolutamente obrigatórios.
É aqui que entra oBloco . O Bloco é um framework Java nativo doKubernetes personalizado para GraalVM e hotSpot.
Com o Quarkus, você pode construir binários nativos que podem inicializar e enviar sua primeira resposta no 0.042 segundos versus 9.5 segundos para um aplicativo Java tradicional.
Tempo de inicialização do Quarkus
Neste tutorial, construiremos um aplicativo do Quartokus que pode gerenciar uma collection dopersons no MongoDB. O objetivo é executar quatro operações CRUD simples com uma REST API usando um aplicativo nativo.

Pré-requisitos

Para este tutorial, você precisará de:
Se você não quiser codificar junto e preferir conferir diretamente o código final:
1git clone git@github.com:mongodb-developer/quarkus-mongodb-crud.git

Como configurar o Quarkus com o MongoDB

TL;DR: Use este link e clique em generate your application ou clone o repositório do GitHub.
A maneira mais fácil de colocar seu projeto em funcionamento com o Quarkus e todas as dependências necessárias é usar https://code.4kus.io/.
Semelhante ao Spring initializr, o site inicial do projeto Quartokus ajudará você a selecionar suas dependências e construir seu arquivo de configuração Maven ou Gradle. Algumas dependências também incluirão um código inicial para ajudá-lo em seus primeiros passos.
Para o nosso projeto, vamos precisar de:
  • Cliente MongoDB [quárkus-mongodb-cliente].
  • SmallRYE OpenAPI [quakus-smallrye-openapi].
  • REST [quarkus-rest].
  • REST dentro de jackson.
Sinta-se livre para usar o group e oartifact de sua escolha. Certifique-se de que a versão do Java corresponda à versão da sua versão do GraalVM e estamos prontos para Go.
Baixe o arquivo zip e descompacte-o na pasta de projeto de sua preferência. Quando terminar, dedique algum tempo para ler o arquivo README.md fornecido.
Por fim, precisamos de um cluster MongoDB. Duas soluções:
  • Criar um novo cluster no MongoDB Atlas e recuperar a connection string, ou
  • Crie um conjunto de réplicas de nó único efêmero com o Docker.
1docker run --rm -d -p 27017:27017 -h $(hostname) --name mongo mongo:latest --replSet=RS && sleep 5 && docker exec mongo mongosh --quiet --eval "rs.initiate();"
De qualquer forma, a próxima etapa é configurar sua connection string no arquivoapplication.properties.
1quarkus.mongodb.connection-string=mongodb://localhost:27017

Operações CRUD no Quarkus com MongoDB

Agora que nosso projeto Quakus está pronto, podemos começar a desenvolver.
Primeiro, podemos iniciar o modo de desenvolvedor, que inclui codificação ao vivo (atualização automática) sem a necessidade de reiniciar o programa.
1./mvnw compile quarkus:dev
O modo de desenvolvedor vem com dois recursos úteis:
Sinta-se à vontade para explorar essas duas UIs e ver os recursos que elas oferecem.
Além disso, como seu serviço agora está em execução, você deverá receber sua primeira comunicação HTTP. Abra um novo terminal e execute a seguinte consulta:
1curl http://localhost:8080/hello
Nota: se você clonou o repositório, então é /api/hello. Estamos mudando isso abaixo em um minuto.
Resultado:
1Hello from Quarkus REST
Isso funciona porque seu projeto atualmente contém uma única classe GreetingResource.java com o código a seguir.
1package com.mongodb;
2
3import jakarta.ws.rs.GET;
4import jakarta.ws.rs.Path;
5import jakarta.ws.rs.Produces;
6import jakarta.ws.rs.core.MediaType;
7
8@Path("/hello")
9public class GreetingResource {
10
11 @GET
12 @Produces(MediaType.TEXT_PLAIN)
13 public String hello() {
14 return "Hello from Quarkus REST";
15 }
16}

PersonEntity

"Olá do Quartokus REST" é bom, mas não é o nosso objetivo! Queremos manipular dados de uma coleçãopersons no MongoDB.
Vamos criar um PersonEntity.javaclássico classePOJO. Criei-o no pacote com.mongodbpadrão, que é o meugroup anterior. Sinta-se livre para alterá-lo.
1package com.mongodb;
2
3import com.fasterxml.jackson.databind.annotation.JsonSerialize;
4import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
5import org.bson.types.ObjectId;
6
7import java.util.Objects;
8
9public class PersonEntity {
10
11 @JsonSerialize(using = ToStringSerializer.class)
12 public ObjectId id;
13 public String name;
14 public Integer age;
15
16 public PersonEntity() {
17 }
18
19 public PersonEntity(ObjectId id, String name, Integer age) {
20 this.id = id;
21 this.name = name;
22 this.age = age;
23 }
24
25 @Override
26 public int hashCode() {
27 int result = id != null ? id.hashCode() : 0;
28 result = 31 * result + (name != null ? name.hashCode() : 0);
29 result = 31 * result + (age != null ? age.hashCode() : 0);
30 return result;
31 }
32
33 @Override
34 public boolean equals(Object o) {
35 if (this == o) return true;
36 if (o == null || getClass() != o.getClass()) return false;
37
38 PersonEntity that = (PersonEntity) o;
39
40 if (!Objects.equals(id, that.id)) return false;
41 if (!Objects.equals(name, that.name)) return false;
42 return Objects.equals(age, that.age);
43 }
44
45 public ObjectId getId() {
46 return id;
47 }
48
49 public void setId(ObjectId id) {
50 this.id = id;
51 }
52
53 public String getName() {
54 return name;
55 }
56
57 public void setName(String name) {
58 this.name = name;
59 }
60
61 public Integer getAge() {
62 return age;
63 }
64
65 public void setAge(Integer age) {
66 this.age = age;
67 }
68}
Agora temos uma classe para mapear nossos documentos MongoDB usando jackson.

PersonRepository

Agora que temos um PersonEntity, podemos criar um modeloPersonRepository, pronto para receber nossas queries CRUD.
Crie uma classe PersonRepository.javaao lado daPersonEntity.java.
1package com.mongodb;
2
3import com.mongodb.client.MongoClient;
4import com.mongodb.client.MongoCollection;
5import jakarta.enterprise.context.ApplicationScoped;
6
7@ApplicationScoped
8public class PersonRepository {
9
10 private final MongoClient mongoClient;
11 private final MongoCollection<PersonEntity> coll;
12
13 public PersonRepository(MongoClient mongoClient) {
14 this.mongoClient = mongoClient;
15 this.coll = mongoClient.getDatabase("test").getCollection("persons", PersonEntity.class);
16 }
17
18 // CRUD methods will go here
19
20}

PersonResource

Agora estamos quase prontos para criar nosso primeiro método CRUD. Vamos atualizar a classeGreetingResource.javapadrão para corresponder ao nosso objetivo.
  1. Renomeie o arquivo GreetingResource.java para PersonResource.java.
  2. Na pastatest, renomeie também os arquivos de teste padrão para PersonResourceIT.java e PersonResourceTest.java.
  3. Atualize PersonResource.java assim:
1package com.mongodb;
2
3import jakarta.inject.Inject;
4import jakarta.ws.rs.*;
5import jakarta.ws.rs.core.MediaType;
6
7@Path("/api")
8@Consumes(MediaType.APPLICATION_JSON)
9@Produces(MediaType.APPLICATION_JSON)
10public class PersonResource {
11
12 @Inject
13 PersonRepository personRepository;
14
15 @GET
16 @Path("/hello")
17 public String hello() {
18 return "Hello from Quarkus REST";
19 }
20
21 // CRUD routes will go here
22
23}
Observe que, com a anotação@Path("/api"), a URL do nosso serviço/hello agora é /api/hello.
Como consequência, atualize PersonResourceTest.java para que nosso teste continue funcionando.
1package com.mongodb;
2
3import io.quarkus.test.junit.QuarkusTest;
4import org.junit.jupiter.api.Test;
5
6import static io.restassured.RestAssured.given;
7import static org.hamcrest.CoreMatchers.is;
8
9@QuarkusTest
10class PersonResourceTest {
11 @Test
12 void testHelloEndpoint() {
13 given().when().get("/api/hello").then().statusCode(200).body(is("Hello from Quarkus REST"));
14 }
15}

Criar uma pessoa

Todos os blocos de código estão agora em vigor. Podemos criar nossa primeira rota para poder criar uma nova pessoa.
No repositório, adicione o seguinte método que insere um PersonEntity e retorna o ObjectIddo documento inserido no formatoString.
1public String add(PersonEntity person) {
2 return coll.insertOne(person).getInsertedId().asObjectId().getValue().toHexString();
3}
No arquivo de recursos , podemos criar a rota correspondente:
1@POST
2@Path("/person")
3public String createPerson(PersonEntity person) {
4 return personRepository.add(person);
5}
Sem reiniciar o projeto (lembre-se do modo dev?), Você deve ser capaz de testar esta rota.
1curl -X POST http://localhost:8080/api/person \
2 -H 'Content-Type: application/json' \
3 -d '{"name": "John Doe", "age": 30}'
Isso deve retornar a ObjectId do novo documentoperson.
1661dccf785cd323349ca42f7
Se você se conectar à instância do MongoDB com mongosh, poderá confirmar que o documento chegou:
1RS [direct: primary] test> db.persons.find()
2[
3 {
4 _id: ObjectId('661dccf785cd323349ca42f7'),
5 age: 30,
6 name: 'John Doe'
7 }
8]

Leia pessoas

Agora, podemos ler todas as pessoas no banco de dados, por exemplo.
No repositório, adicione:
1public List<PersonEntity> getPersons() {
2 return coll.find().into(new ArrayList<>());
3}
No recurso, adicione:
1@GET
2@Path("/persons")
3public List<PersonEntity> getPersons() {
4 return personRepository.getPersons();
5}
Agora podemos recuperar todas as pessoas em nosso banco de dados:
1curl http://localhost:8080/api/persons
Isso retorna uma lista de pessoas:
1[
2 {
3 "id": "661dccf785cd323349ca42f7",
4 "name": "John Doe",
5 "age": 30
6 }
7]

Atualizar pessoa

É o aniversário de John Doe! Vamos aumentar a idade dele em um.
No repositório, adicione:
1public long anniversaryPerson(String id) {
2 Bson filter = eq("_id", new ObjectId(id));
3 Bson update = inc("age", 1);
4 return coll.updateOne(filter, update).getModifiedCount();
5}
No recurso, adicione:
1@PUT
2@Path("/person/{id}")
3public long anniversaryPerson(@PathParam("id") String id) {
4 return personRepository.anniversaryPerson(id);
5}
É hora de testar essa festa:
1curl -X PUT http://localhost:8080/api/person/661dccf785cd323349ca42f7
Isso retorna 1, que é o número de documentos modificados. Se o ObjectIdfornecido não corresponder ao ID de uma pessoa, ele retornará 0 e o MongoDB não executará nenhuma atualização.

Exclui pessoa

Finalmente, é hora de excluir o John Doe...
No repositório, adicione:
1public long deletePerson(String id) {
2 Bson filter = eq("_id", new ObjectId(id));
3 return coll.deleteOne(filter).getDeletedCount();
4}
No recurso, adicione:
1@DELETE
2@Path("/person/{id}")
3public long deletePerson(@PathParam("id") String id) {
4 return personRepository.deletePerson(id);
5}
Vamos testar:
1curl -X DELETE http://localhost:8080/api/person/661dccf785cd323349ca42f7
Novamente, ele retorna 1 que é o número de documentos excluídos.
Agora que temos um aplicativo Quartokus em funcionamento com um serviço CRUD do MongoDB, é hora de experimentar todo o poder do Quakus.

Compilação nativa do Quarkus

Saia do modo de desenvolvedor simplesmente pressionando a teclaqno terminal relevante.
É hora de construir o executável nativo que podemos usar na produção com GraalVM e experimentar o tempo de inicializaçãoinsanamente rápido.
Use esta linha de comando para construir diretamente com seu GraalVM local e outras dependências.
1./mvnw package -Dnative
Ou use a imagem do Docker que contém tudo o que você precisa:
1./mvnw package -Dnative -Dquarkus.native.container-build=true
O resultado final é um aplicativo nativo, pronto para ser iniciado, em sua pastatarget .
1./target/quarkus-mongodb-crud-1.0.0-SNAPSHOT-runner
No meu laptop, ele começa em apenas 0.019s! Lembre-se de quanto tempo o Spring Boot precisa para iniciar um aplicativo e responder às queries pela primeira vez ?!
Você pode ler mais sobre como o Quarkus torna esse milagre uma Realidade na documentação do container first.

Conclusão

Neste tutorial, exploramos como o Quekus e o MongoDB podem se unir para criar uma API RESTful ultra rápida com recursos de CRUD.
Agora fornecido com esses insights, você está pronto para criar API ultrarrápidas com o Quarkus, GraalVM e MongoDB. Mergulhe no Githubfornecido para obter mais detalhes.
Em caso de dúvidas, acesse nosso website da comunidade de desenvolvedores, no qual os engenheiros do MongoDB e a MongoDB Community ajudarão você a colocar em prática sua próxima grande ideia com o MongoDB.
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 Início rápido
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Artigo

Usar o Atlas Search do Java


Jul 14, 2023 | 13 min read
exemplo de código

Como implementar a criptografia no nível do campo do lado do cliente (CSFLE) em Java com o Spring Data MongoDB


Jan 27, 2024 | 11 min read
Tutorial

Geração aumentada de recuperação com MongoDB e Spring AI: Trazendo AI para seus aplicativos Java


Sep 23, 2024 | 6 min read
Tutorial

Dados da primavera desbloqueados: queries avançadas com MongoDB


Nov 08, 2024 | 7 min read
Sumário