RESTful web service – JAX-RS and CDI

Now, it's time to build our RESTful web service implementation, as follows:

  1. Delete the default implementation class, HelloWorldEndpoint.java, created by the Thorntail generator.
  2. Define a new package, named service (the fully qualified name will be com.packtpub.thorntail.footballplayermicroservice.rest.service), where we will put the RESTful web service implementation.
  3. Finally, let's build the API implementations by using the CDI specifications (in order to inject the entity manager used to manage database connections) and the JAX-RS (in order to implement the RESTful operations). We will create an AbstractFacade class that defines the standard CRUD of our microservice:
package   com.packtpub.thorntail.footballplayermicroservice.rest.service;

import java.util.List;
import javax.persistence.EntityManager;

/**
* Abstract facade used to define the CRUD APIs of our micro service.
*
* @author Mauro Vocale
* @param <T> The type class of our entity domain.
* @version 1.0.0 17/08/2018
*/
public abstract class AbstractFacade<T> {

private final Class<T> entityClass;

public AbstractFacade(Class<T> entityClass) {
this.entityClass = entityClass;
}

protected abstract EntityManager getEntityManager();

public void create(T entity) {
getEntityManager().persist(entity);
}

public void edit(T entity) {
getEntityManager().merge(entity);
}

public void remove(T entity) {
getEntityManager().remove(getEntityManager().merge(entity));
}

public T find(Object id) {
return getEntityManager().find(entityClass, id);
}

public List<T> findAll() {
javax.persistence.criteria.CriteriaQuery<T> cq =
getEntityManager().getCriteriaBuilder().createQuery(entityClass);
cq.select(cq.from(entityClass));
return getEntityManager().createQuery(cq).getResultList();
}
}
  1. Finally, the real implementation is as follows:
package   com.packtpub.thorntail.footballplayermicroservice.rest.service;

import com.packtpub.thorntail.footballplayermicroservice.model.FootballPlayer;
import java.util.List;
import javax.enterprise.context.ApplicationScoped;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

/**
* Class that exposes the APIs implementations of our CRUD micro service.
*
* @author Mauro Vocale
* @version 1.0.0 17/08/2018
*/
@ApplicationScoped
@Path("/footballplayer")
public class FootballPlayerFacadeREST extends AbstractFacade<FootballPlayer> {

@PersistenceContext(unitName = "FootballPlayerPU")
private EntityManager em;

public FootballPlayerFacadeREST() {
super(FootballPlayer.class);
}

@POST
@Override
@Consumes({MediaType.APPLICATION_JSON})
@Transactional(Transactional.TxType.REQUIRES_NEW)
public void create(FootballPlayer entity) {
super.create(entity);
}

@PUT
@Path("{id}")
@Consumes({MediaType.APPLICATION_JSON})
@Transactional(Transactional.TxType.REQUIRES_NEW)
public void edit(@PathParam("id") Integer id, FootballPlayer entity) {
super.edit(entity);
}

@DELETE
@Path("{id}")
@Transactional(Transactional.TxType.REQUIRES_NEW)
public void remove(@PathParam("id") Integer id) {
super.remove(super.find(id));
}

@GET
@Path("{id}")
@Produces({MediaType.APPLICATION_JSON})
public FootballPlayer find(@PathParam("id") Integer id) {
return super.find(id);
}

@GET
@Override
@Produces({MediaType.APPLICATION_JSON})
public List<FootballPlayer> findAll() {
return super.findAll();
}

@Override
protected EntityManager getEntityManager() {
return em;
}

}
  1. Now, we will be able to create our Uber JAR, with the following command:
$ mvn clean package 
  1. Launch our microservice application by using the following command:
$ java -jar target/football-player-microservice-thorntail.jar 

Let's check that the application is deployed and that Thorntail is up and running, as follows:

2018-07-17   16:41:31,640 INFO  [org.wildfly.extension.undertow] (ServerService Thread   Pool -- 12) WFLYUT0021: Registered web context: '/' for server 'default-server'
2018-07-17 16:41:31,674 INFO [org.jboss.as.server] (main) WFLYSRV0010: Deployed "football-player-microservice.war" (runtime-name : "football-player-microservice.war")
2018-07-17 16:41:31,680 INFO [org.wildfly.swarm] (main) WFSWARM99999: Thorntail is Ready
  1. Now, invoke the API that retrieves the list of football players, as follows:
$ curl   http://localhost:8080/footballplayer | json_pp   

The output should be similar to the following (for convenience, there is only a portion of it here):

[
{
"id":1,
"name":"Gianluigi",
"surname":"Buffon",
"age":40,
"team":"Paris Saint Germain",
"position":"goalkeeper",
"price":2
},
{
"id":2,
"name":"Manuel",
"surname":"Neuer",
"age":32,
"team":"Bayern Munchen",
"position":"goalkeeper",
"price":35
},
{
"id":3,
"name":"Keylor",
"surname":"Navas",
"age":31,
"team":"Real Madrid",
"position":"goalkeeper",
"price":18
},
...
]
  1. Finally, we will create the JUnit test, in order to ensure that our APIs are working properly. Let's add the Maven dependencies, as follows:
<properties>
...
<version.resteasy>3.0.19.Final</version.resteasy>
</properties>

<dependency>
<groupId>io.thorntail</groupId>
<artifactId>arquillian</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>${version.resteasy}</version>
<scope>test</scope>
</dependency>
  1. Then, we will create the test class, named FootballPlayerFacadeRESTTest, in the package com.packtpub.thorntail.footballplayermicroservice.rest.service, under the src/main/test directory:
package com.packtpub.thorntail.footballplayermicroservice.rest.service;

import com.packtpub.thorntail.footballplayermicroservice.model.FootballPlayer;
import com.packtpub.thorntail.footballplayermicroservice.rest.RestApplication;
...

/**
* Unit Test class needed to test the APIs.
*
* @author Mauro Vocale
* @version 1.0.0 18/07/2018
*/
@RunWith(Arquillian.class)
public class FootballPlayerFacadeRESTTest {
private static final String API_URL = "http://localhost:8080/footballplayer";

/**
*
* @return @throws Exception
*/
@Deployment
public static Archive createDeployment() throws Exception {
JAXRSArchive deployment = ShrinkWrap.create(JAXRSArchive.class);
deployment.addPackage(FootballPlayer.class.getPackage());
deployment.addPackage(AbstractFacade.class.getPackage());
deployment.addPackage(RestApplication.class.getPackage());

deployment.addAsWebInfResource(new ClassLoaderAsset(
"META-INF/create.sql", FootballPlayerFacadeREST.class.
getClassLoader()),"classes/META-INF/create.sql");

deployment.addAsWebInfResource(new ClassLoaderAsset(
"META-INF/load.sql", FootballPlayerFacadeREST.class.getClassLoader()),
"classes/META-INF/load.sql");

deployment.addAsWebInfResource(new ClassLoaderAsset(
"META-INF/persistence.xml", FootballPlayerFacadeREST.class.
getClassLoader()), "classes/META-INF/persistence.xml");

deployment.addAsWebInfResource(new ClassLoaderAsset(
"project-defaults.yml", FootballPlayerFacadeREST.class.
getClassLoader()), "classes/project-defaults.yml");

deployment.addAllDependencies();
System.out.println(deployment.toString(true));
return deployment;
}

private final Client client = ClientBuilder.newBuilder().build();
private WebTarget target;

...
@Before
public void setUp() {
target = client.target(API_URL);
}

/**
* Test of create method, of class FootballPlayerFacadeREST.
*/
@Test
@InSequence(2)
public void testCreate() {
System.out.println("create");
FootballPlayer player = new FootballPlayer("Mauro", "Vocale", 38,
"Juventus", "central midfielder", new BigInteger("100"));
Response response = target.request().post(Entity.entity(player,
MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus(), is(Response.Status.NO_CONTENT.
getStatusCode()));
}

...
}

Are some famous players missing? At the end of the chapter, we will build a graphic user interface that will help you to insert your favorite ones.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset