MicroProfile REST API with MongoDB, Hibernate OGM and Thorntail

by Hayri Cicek


Posted on 07-Aug-2018

In this tutorial we will learn how to create REST API using MicroProfile, MongoDB, Hibernate OGM and Thorntail (wildfly-swarm)

Tools You Will Need
Maven 3.3+
Your favorite IDE. I'm using NetBeans
JDK 1.8+

Install MongoDB
To download and install MongoDB visit http://docs.mongodb.org/manual/installation/

WildFly Swarm Project Generator
Go to http://wildfly-swarm.io/generator/ and follow the steps below to generate a new project.



Enter the Details as Follows

Group ID: com.kodnito
Artifact ID: microprofile-restapi-mongodb
Dependencies: JAX-RS, CDI
Click Generate Project to generate and download your project.
Next, Unzip the downloaded zip file and import it into your favorite IDE.
Open the pom.xml and add two more dependencies.


<dependency>
    <groupId>org.hibernate.ogm</groupId>
    <artifactId>hibernate-ogm-mongodb</artifactId>
    <version>5.0.0.Final</version>
</dependency>
<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongo-java-driver</artifactId>
    <version>3.8.0</version>
</dependency>

We added Hibernate OGM and MongoDB dependencies to our application.
In project directory run the following command to download the dependencies.

$ mvn install
Persistence XML
Inside src/main/resources/META-INF/ create persistence.xml and add the following


<?xml version="1.0" encoding="utf-8"?>
 
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">
    <persistence-unit name="restapi-unit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>
<class>com.kodnito.microprofilerestapimongodb.model.Todo</class>
        <properties>
            <property name="hibernate.ogm.datastore.provider" value="mongodb" />
            <property name="hibernate.ogm.datastore.database" value="todoDB" />
            <property name="hibernate.ogm.datastore.host" value="localhost" />
            <property name="hibernate.ogm.datastore.create_database" value="true" />
            <property name="hibernate.ogm.datastore.username" value="" /> 
            <property name="hibernate.ogm.datastore.password" value="" /> 
        </properties>
    </persistence-unit>
</persistence>

Entity
Create a new java class called Todo.java inside src/main/java/com/kodnito/microprofilerestapimongodb/model/ and add the following

Todo.java

package com.kodnito.microprofilerestapimongodb.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.NamedQuery;

@Entity
@NamedQuery(name = "Todo.findAll", query = "SELECT t FROM Todo t")
public class Todo {

    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    private String id;
    private String task;
    private String description;

    public String getId() {
        return id;
    }

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

    public String getTask() {
        return task;
    }

    public void setTask(String task) {
        this.task = task;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Override
    public String toString() {
        return "Todo{" + "id=" + id + ", task=" + task + ", description=" + description + '}';
    }

}

@Entity annotation indicates that it is a JPA entity
@Table annotation is used to name the table in the database
@NamedQuery annotation defines query with a name
@Id annotation is used to define the primary key and the Id property is also annotated with @GeneratedValue to indicate that the Id should be generated automatically.

EntityManagerProducer
Inside src/main/java/com/kodnito/microprofilerestapimongodb/rest/ package create EntityManagerProducer.java file and add the following

EntityManagerProducer.java

package com.kodnito.microprofilerestapimongodb.rest;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import javax.persistence.EntityManager;
import javax.persistence.Persistence;

@ApplicationScoped
public class EntityManagerProducer {

    @Produces
    public EntityManager createEntityManager() {
        return Persistence
                .createEntityManagerProducer("restapi-unit")
                .createEntityManager();
    }

    public void close(EntityManager entityManager) {
        entityManager.close();
    }

}

Here we are creating a non-managed entity manager object inside a Producer method that can be injected.
@javax.enterprise.inject.Produces can be used when an object is not a bean but we want to inject it.

Business Logic
Inside src/main/java/com/kodnito/microprofilerestapimongodb/dao/ package create TodoDAO.java file and add the following

TodoDAO.java

package com.kodnito.microprofilerestapimongodb.dao;

import com.kodnito.microprofilerestapimongodb.model.Todo;
import java.util.List;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;

@ApplicationScoped
public class TodoDAO {

    @Inject
    private EntityManager em;

    public List getAll() {
        return em.createNamedQuery("Todo.findAll", Todo.class).getResultList();
    }

    public Todo findById(String id) {
        return em.find(Todo.class, id);
    }

    public void update(Todo todo) {
        em.getTransaction().begin();
        em.merge(todo);
        em.getTransaction().commit();

    }

    public void create(Todo todo) {
        em.getTransaction().begin();
        em.persist(todo);
        em.getTransaction().commit();
    }

    public void delete(Todo todo) {
        em.getTransaction().begin();
        em.remove(todo);
        em.getTransaction().commit();
    }

}

getAll() method retrieves all the todos from the database and return the entire list.
findById() method finds one Todo Object from the database with ID and returns it.
update() method will update existing Todo Object in the database.
create() method will create Todo Object in the database.
delete() method will find the Todo Object in the database and delete it.
em.getTransaction() is used to control transactions on resource-local entity managers.

Open HelloWorldEndpoint.java and change it to look like this


package com.kodnito.microprofilerestapimongodb.rest;

import com.kodnito.microprofilerestapimongodb.dao.TodoDAO;
import com.kodnito.microprofilerestapimongodb.model.Todo;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@ApplicationScoped
@Path("todos")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class HelloWorldEndpoint {

    @Inject
    private TodoDAO todoDAO;

    @GET
    public Response getAll() {
        return Response.ok(todoDAO.getAll()).build();
    }

    @GET
    @Path("{id}")
    public Response getTodo(@PathParam("id") String id) {
        Todo todo = todoDAO.findById(id);

        return Response.ok(todo).build();
    }

    @PUT
    @Path("{id}")
    public Response update(@PathParam("id") String id, Todo todo) {
        Todo updateTodo = todoDAO.findById(id);

        updateTodo.setTask(todo.getTask());
        updateTodo.setDescription(todo.getDescription());
        todoDAO.update(updateTodo);

        return Response.ok().build();
    }

    @POST
    public Response create(Todo todo) {
        todoDAO.create(todo);
        return Response.ok().build();
    }

    @DELETE
    @Path("{id}")
    public Response delete(@PathParam("id") String id) {
        Todo getTodo = todoDAO.findById(id);

        todoDAO.delete(getTodo);

        return Response.ok().build();
    }
}

Your project structure should look like this

tree .
.
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── kodnito
    │   │           └── microprofilerestapimongodb
    │   │               ├── dao
    │   │               │   └── TodoDAO.java
    │   │               ├── model
    │   │               │   └── Todo.java
    │   │               └── rest
    │   │                   ├── EntityManagerProducer.java
    │   │                   ├── HelloWorldEndpoint.java
    │   │                   └── RestApplication.java
    │   └── resources
    │       └── META-INF
    │           └── persistence.xml
    └── test
        └── java

It's time to test our new rest api.
Download Postman if you don't already have it.
Inside your project directory run the following command to start the Thorntail server.

$ mvn thorntail:run
Create TODO


Get TODOS

Get TODO

Update TODO

Delete TODO


Share this: