Visão geral
O Panache é uma biblioteca específica do framework Quartokus que simplifica o desenvolvimento de camadas persistentes baseadas no Hibernato. Ele reduz os códigos padrão fornecendo operações CRUD integradas e queries seguras por tipo.
O Panache é compatível com o padrão Active Record, que incorpora operações de banco de dados diretamente em classes de entidade, e com o padrão Repository, que separa a lógica de acesso a dados em classes de repositório dedicadas. Integra-se ao Quartokus para fornecer tempos de inicialização rápidos e um baixo espaço ocupado pela memória. O Panache trabalha com o Hibernar Object-Relational Mapping (ORM) e o Java Persistence API (JPA) para simplificar o acesso a dados e, ao mesmo tempo, manter o código limpo.
Neste tutorial, você construirá um aplicação Quartokus com a Panache para executar operações CRUD e agregações em um banco de dados MongoDB . O aplicação permite adicionar, atualizar, encontrar e excluir livros, além de contar livros por gênero.
Tutorial
Neste tutorial, você executa as seguintes ações:
Verifique os pré-requisitos
Configurar o projeto
Criar o modelo de dados
Criar endpoints de API REST
Teste a API
Verifique os pré-requisitos
Antes de começar, verifique se você tem o seguinte:
Uma conta do MongoDB Atlas com um cluster configurado. Para saber como configurar um Atlas cluster, consulte o guia Iniciar do MongoDB .
Java versão 21 ou posterior. Para saber mais sobre como instalar o Java, consulte o site da Oracle.
Seu IDE preferido.
Maven para gerenciar dependências de projeto .
Configurar o projeto
Crie uma pasta para manter seu projeto Quarkus . Navegue até este diretório e crie um projeto Quartokus com Maven executando o seguinte comando:
mvn io.quarkus:quarkus-maven-plugin:create \ -DprojectGroupId=io.quarkus.platform \ -DprojectArtifactId=quarkus-bom \ -DclassName="com.example.BookResource" \ -Dpath="/books"
Adicione as seguintes dependências ao seu arquivo pom.xml:
<dependencies> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-arc</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-rest</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-rest-client-jackson</artifactId> <version>3.16.2</version> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy-reactive-jackson</artifactId> <version>3.15.1</version> </dependency> <dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-mongodb-panache</artifactId> </dependency> </dependencies>
Crie o aplicação e baixe as dependências executando o seguinte comando no diretório do projeto :
mvn clean install
Criar o modelo de dados
Primeiro, a partir do diretório raiz do seu projeto, navegue até src/main/java/com/<package>. Crie um arquivo Book.java neste diretório. Dentro deste arquivo, defina a classe Book como mostrado no seguinte código:
import io.quarkus.mongodb.panache.PanacheMongoEntity; import io.quarkus.mongodb.panache.common.MongoEntity; public class Book extends PanacheMongoEntity { public String title; public String author; public String genre; public int year; public Book() { } }
Essa classe representa um documento de livro na coleção MongoDB com campos para título, autor, gênero e ano.
Criar endpoints de API REST
Crie um arquivo BookRepository.java no diretório do pacote . Dentro deste arquivo, defina a classe BookRepository como mostrado no seguinte código:
import com.quarkusWithPanache.model.Book; import io.quarkus.mongodb.panache.PanacheMongoRepository; import jakarta.enterprise.context.ApplicationScoped; public class BookRepository implements PanacheMongoRepository<Book> { }
Em seguida, crie um arquivo BookResource.java no diretório do pacote . Dentro deste arquivo, defina uma classe de recurso que utiliza a interface BookRepository que você criou no exemplo anterior, como mostrado no código a seguir:
import com.mongodb.client.MongoClient; import com.mongodb.client.MongoCollection; import com.quarkusWithPanache.model.Book; import com.quarkusWithPanache.repository.BookRepository; import jakarta.inject.Inject; import jakarta.ws.rs.*; import jakarta.ws.rs.core.Response; import org.bson.Document; import org.bson.types.ObjectId; import java.util.ArrayList; import java.util.List; public class BookResource { BookRepository bookRepository; MongoClient mongoClient; private MongoCollection<Document> getCollection() { return mongoClient.getDatabase("test").getCollection("books"); } public BookResource(BookRepository bookRepository) { this.bookRepository = bookRepository; } // Define API endpoints here }
As seções a seguir mostram como implementar vários endpoints da API para operações e agregações CRUD. Você pode adicionar o código de cada endpoint abaixo da linha destacada no exemplo anterior.
Inserir um livro
Você pode inserir um único livro adicionando o seguinte código à sua classe de recurso :
BookRepository bookRepository; public Response addBook(Book book) { bookRepository.persist(book); return Response.status(Response.Status.CREATED).entity(book).build(); }
Bulk insert
Você pode inserir vários livros de uma só vez adicionando o seguinte código à sua classe de recurso :
public Response bulkAddBooks(List<Book> books) { // Prepare documents for bulk write List<Document> documents = new ArrayList<>(); for (Book book : books) { documents.add(new Document("title", book.title) .append("author", book.author) .append("genre", book.genre) .append("year", book.year)); } getCollection().insertMany(documents); return Response.status(Response.Status.CREATED).entity(books).build(); }
O método getCollection retorna o nome do banco de dados e da coleção do pacote com.mongodb.client.MongoCollection.
Encontrar todos os livros
Você pode recuperar todos os livros adicionando o seguinte código à sua classe de recurso :
public List<Book> getAllBooks() { return bookRepository.listAll(); }
Encontrar um livro por ID
Você pode recuperar um livro específico pelo seu valor _id adicionando o seguinte código à sua classe de recurso :
public Book getBookById( String id) { return bookRepository.findById(new ObjectId(id)); }
Excluir um livro por ID
Você pode excluir um livro pelo seu valor _id adicionando o seguinte código à sua classe de recurso :
public Response deleteBook( String id) { boolean deleted = bookRepository.deleteById(new ObjectId(id)); return deleted ? Response.noContent().build() : Response.status(Response.Status.NOT_FOUND).build(); }
Atualizar um livro
Você pode atualizar um livro por seu valor _id adicionando o seguinte código à sua classe de recurso :
public Response updateBook( String id, Book book) { Book entity = bookRepository.findById(new ObjectId(id)); if (entity == null) { return Response.status(Response.Status.NOT_FOUND).build(); } entity.title = book.title; entity.author = book.author; entity.genre = book.genre; entity.year = book.year; bookRepository.update(entity); return Response.ok(entity).build(); }
Agregar por gênero
Você pode contar livros por gênero adicionando o seguinte código de agregação à sua classe de recurso :
public Response countBooksByGenre() { List<Document> pipeline = new ArrayList<>(); pipeline.add(new Document("$group", new Document("_id", "$genre") .append("count", new Document("$sum", 1)))); List<Document> result = getCollection() .aggregate(pipeline) .into(new ArrayList<>()); return Response.ok(result).build(); }
Teste a API
Inicie seu aplicação no http://localhost:8080 executando o seguinte comando a partir do diretório raiz do seu projeto:
mvn spring-boot:run
Você pode testar os endpoints da API executando os seguintes comandos curl:
Inserir um livro
O seguinte comando curl mostra como inserir um único livro:
curl -X POST "http://localhost:8080/books" -H "Content-Type: application/json" -d '{ "title": "Quarkus in Action", "author": "John Doe", "genre": "Programming", "year": 2023 }'
Bulk insert
O seguinte comando curl mostra como inserir vários livros:
curl -X POST http://localhost:8080/books/bulk \ -H "Content-Type: application/json" \ -d '[ { "title": "The Midnight Library", "author": "Matt Haig", "genre": "Fiction", "year": 2020 }, { "title": "Sapiens: A Brief History of Humankind", "author": "Yuval Noah Harari", "genre": "Non-Fiction", "year": 2011 } ]'
Encontrar todos os livros
O seguinte comando curl mostra como recuperar todos os livros:
curl -X GET "http://localhost:8080/books" | jq
Encontrar um livro
O seguinte comando curl mostra como recuperar um livro específico:
curl -X GET "http://localhost:8080/books/672f873b421eaa0c3e4da49f" | jq
Excluir um livro
O seguinte comando curl mostra como excluir um livro:
curl -X DELETE "http://localhost:8080/books/673f81b65750de0757a4bbfb" | jq
Atualizar um livro
O seguinte comando curl mostra como atualizar um livro:
curl -X PUT "http://localhost:8080/books/672f856f421eaa0c3e4da49e" \ -H "Content-Type: application/json" \ -d '{ "title": "Quarkus in Action", "author": "John Doe", "genre": "Programming", "year": 2021 }'
Agregar por gênero
O seguinte comando curl mostra como contar livros por gênero:
curl -X GET "http://localhost:8080/books/aggregate/genre-count" | jq
Dica
Usando jq para formatar saída JSON
Utilize a jq ferramenta, como mostrado nos exemplos anteriores, para formatar a saída JSON da API para melhor legibilidade. Você pode instalar jq o seguindo as instruções no site da jq.
Recursos adicionais
Para visualizar a versão completa do exemplo neste tutorial, consulte o repositório quárkus-panache-with-mongodb do Github.
Para saber mais sobre o Panache, consulte a documentação do MongoDB com o Panache no site do Quarkus.