Build Rest CRUD API with Quarkus and MongoDB client

Hello everyone. Today we will learn how to develop REST-style CRUD APIs with MongoDB, Quarkus,  and Mongodb Client.You can download the source code from our Github repository.

After completing this tutorial what we will build? 

We will build REST API  CRUD features: 
  1. GET - Fetch all User       :     /api/v1/users
  2. GET - Get User by ID     :     /api/v1/users/{id} 
  3. POST - Create User         :     /api/v1/users 
  4. PUT - Edit User Details   :     /api/v1/users/
  5. DELETE - Delete User    :     /api/v1/users/{id}

Technologies used:

  • Quarkus 2.2.3.Final
  • Mongodb
  • Mongodb client
  • Maven
  • Java 11

More Quarkus Related topics,


Project Directory:


Maven[pom.xml]

A Project Object Model or POM is the fundamental unit of work in Maven. It is an XML file that contains information about the project and configuration details utilized by Maven to build the project. It contains default values for most projects. Some of the configurations that can be designated in the POM is the project dependencies, the plugins or goals that can be executed, the build profiles, and so on. Other information such as the project version, description, developers, mailing lists and such can withal be designated.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.knf.dev</groupId>
<artifactId>quarkus-mongo-crud</artifactId>
<version>1.0</version>

<properties>
<compiler-plugin.version>3.8.1</compiler-plugin.version>
<maven.compiler.parameters>true</maven.compiler.parameters>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus-plugin.version>2.2.3.Final</quarkus-plugin.version>
<quarkus.platform.artifact-id>quarkus-universe-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
<quarkus.platform.version>2.2.3.Final</quarkus.platform.version>
<surefire-plugin.version>2.22.1</surefire-plugin.version>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jsonb</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-mongodb-client</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemProperties>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
</systemProperties>
</configuration>
</plugin>
</plugins>
</build>

<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemProperties>
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
</systemProperties>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
</project>

application.properties

quarkus.mongodb.connection-string = mongodb://localhost:27017

Create Document - User.java

package com.knf.dev.model;

public class User {

private String id;
private String firstName;
private String lastName;
private String emailId;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getEmailId() {
return emailId;
}

public void setEmailId(String emailId) {
this.emailId = emailId;
}

public User(String id, String firstName,
String lastName, String emailId) {
super();
this.id=id;
this.firstName = firstName;
this.lastName = lastName;
this.emailId = emailId;
}

public User() {
super();
}

}

Create UserRepository.java

package com.knf.dev.repository;

import com.knf.dev.model.User;
import org.bson.Document;
import java.util.List;
import java.util.Optional;

public interface UserRepository {
User saveUser(User user);

User updateUser(String id, User user);

List<User> findAll();

Optional<User> findUserById(String id);

void deleteUserById(String id);
}

Create UserRepositoryImpl.java

package com.knf.dev.repository.impl;

import com.knf.dev.model.User;
import com.knf.dev.repository.UserRepository;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import org.bson.Document;
import org.bson.types.ObjectId;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import static com.mongodb.client.model.Filters.eq;

@ApplicationScoped
public class UserRepositoryImpl implements UserRepository {
private final MongoClient mongoClient;

@Inject
public UserRepositoryImpl(MongoClient mongoClient) {
this.mongoClient = mongoClient;
}

private MongoCollection getCollection() {
return mongoClient.getDatabase("user-test").getCollection("user-test");
}

@Override
public User saveUser(User user) {
Document document = new Document()
.append("firstName", user.getFirstName()).
append("lastName", user.getLastName()).
append("emailId", user.getEmailId());
getCollection().insertOne(document);
user.setId(document.getObjectId("_id").toString());
return user;
}

@Override
public User updateUser(String id, User user) {
Optional<Document> optionalDocument = findDocumentById(id);
if (optionalDocument.isPresent()) {
Document document = optionalDocument.get();
document.put("firstName", user.getFirstName());
document.put("lastName", user.getLastName());
document.put("emailId", user.getEmailId());
getCollection().replaceOne(eq(new ObjectId(id)), document);
}
return user;
}

@Override
public List<User> findAll() {
List<User> users = new ArrayList<>();
MongoCursor<Document> cursor = getCollection().find().iterator();

try {
while (cursor.hasNext()) {
Document document = cursor.next();
User user = new User();
user.setLastName(document.getString("lastName"));
user.setFirstName(document.getString("firstName"));
user.setEmailId(document.getString("emailId"));
user.setId(String.valueOf(document.getObjectId("_id")));
users.add(user);
}
} finally {
cursor.close();
}
return users;
}

@Override
public Optional<User> findUserById(String id) {
return findDocumentById(id).map(this::mapUser);
}

@Override
public void deleteUserById(String id) {
getCollection().deleteOne(eq(new ObjectId(id)));
}

private Optional<Document> findDocumentById(String id) {
MongoCursor<Document> iterator =
getCollection().find(eq(new ObjectId(id))).iterator();
return iterator.hasNext() ?
Optional.of(iterator.next()) : Optional.empty();
}

private User mapUser(Document document) {
User user = new User();
user.setId(document.getObjectId("_id").
toString());
user.setEmailId(document.getString("emailId"));
user.setLastName(document.getString("lastName"));
user.setFirstName(document.getString("firstName"));
return user;
}
}

Create UserController.java

package com.knf.dev.controller;

import com.knf.dev.model.User;
import com.knf.dev.repository.UserRepository;

import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
import java.util.Optional;

@Path("/api/users")
public class UserController {

@Inject
UserRepository userRepository;

@GET
@Produces(MediaType.APPLICATION_JSON)
public List<User> getUsers() {
return userRepository.findAll();
}

@GET
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getUser
(@PathParam("id") String id) {
Optional<User> user = userRepository.findUserById(id);
return user.isPresent() ?
Response.ok(user.get()).build() :
Response.status(Response.Status.NOT_FOUND).build();
}

@PUT
@Path("/{id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response updateUser
(@PathParam("id") String id, User user) {
Optional<User> optionalUser = userRepository.findUserById(id);
if (!optionalUser.isPresent()) {
return Response.status(Response.Status.NOT_FOUND).build();
}
return Response.ok(userRepository.updateUser(id, user)).build();
}

@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response addUser(User user) {
userRepository.saveUser(user);
return Response.status(Response.Status.CREATED).build();
}

@DELETE
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response deleteUser(@PathParam("id") String id) {
Optional<User> user = userRepository.findUserById(id);
user.ifPresent(usr -> userRepository.deleteUserById(usr.getId()));
return user.isPresent() ?
Response.noContent().build() :
Response.status(Response.Status.NOT_FOUND).build();
}
}

Verify REST APIs

Build application  jar file: mvn clean package

Start application: java -jar quarkus-run.jar

1. Add User

2. Find User

3. Fetch All Users

4. Update User

5. Delete User


More Quarkus Related topics,

Kotlin + Quarkus

Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete