Creating a TomEE / React Application using MicroProfile - Part 1
Tags: tomee, microprofile, react, rest
Published: 2019-09-26 08:54:34

---
title: Creating a TomEE / React Application using MicroProfile - Part 1
published: true
description: 
tags: TomEE, MicroProfile, React, REST, MicroProfile
canonical_url: https://davidsalter.uk/2019/09/26/creating-tomee-react-app-part-1.html

---

In this and the following articles, I'm going to build a TomEE application that provides a REST interface. The interface will then be queried by a React JavaScript frontend. Specifically, the back end will expose a REST interface via JAX-RS providing information about Constellations. The React front end will allow users to select a Constellation to get more details about it. The final product will look something like:

![Constellations - TomEE and React Demonstration](https://davidsalter.uk/assets/images/tomeereact.png)

## Creating The Back End

The quickest way to create the Constellations API is to use the [MicroProfile Starter](https://start.microprofile.io). This enbles all the scaffolding to be created for a MicroProfile Maven application. For this application the followng options were chosen:

- `groupId` - com.davidsalter
- `artifactId` - constellationapi
- `MicroProfile Version` - 2.1
- `MicroProfile Server` - TomEE

At the time of writing, the latest available version of TomEE on the MicroProfile Starter is 8.0.0.M3, however version 8.0.0 has been released since the starter was last updated. The first task therefore, is to update to the correct (and latest) version of TomEE in the project's pom.xml file.

```xml
<properties>
  <tomee.version>8.0.0</tomee.version>
...

<plugin>
  <groupId>org.apache.tomee.maven</groupId>
  <artifactId>tomee-maven-plugin</artifactId>
  <version>${tomee.version}</version>
```

To easily access the constellations within the API, I want to store them in a database and query them using JPA. To do this, I need to add some of Java EE 8 into the application. This is achieved by adding the `javaee-api` dependency into the `pom.xml`

```xml
<dependency>
  <groupId>org.apache.tomee</groupId>
  <artifactId>javaee-api</artifactId>
  <version>8.0-2</version>
  <scope>provided</scope>
</dependency>
```

The full `pom.xml` looks like:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
  xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.davidsalter</groupId>
  <artifactId>constellationapi</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>
  <properties>
    <final.name>constellationapi</final.name>
    <tomee.version>8.0.0</tomee.version>
    <failOnMissingWebXml>false</failOnMissingWebXml>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.eclipse.microprofile</groupId>
      <artifactId>microprofile</artifactId>
      <version>2.1</version>
      <type>pom</type>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.tomee</groupId>
      <artifactId>javaee-api</artifactId>
      <version>8.0-2</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>
  <build>
    <finalName>constellationapi</finalName>
  </build>
  <profiles>
    <profile>
      <id>tomee</id>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.tomee.maven</groupId>
            <artifactId>tomee-maven-plugin</artifactId>
            <version>${tomee.version}</version>
            <executions>
              <execution>
                <id>executable-jar</id>
                <phase>package</phase>
                <goals>
                  <goal>exec</goal>
                </goals>
              </execution>
            </executions>
            <configuration>
              <context>ROOT</context>
              <tomeeClassifier>microprofile</tomeeClassifier>
              <tomeeHttpPort>8080</tomeeHttpPort>
              <tomeeShutdownPort>8005</tomeeShutdownPort>
              <tomeeAjpPort>8009</tomeeAjpPort>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
</project>
```

Now that we've created the basic scaffolding for the project, using the MicroProfile Starter and manually editing the `pom.xml`, there are 3 things we need to do to complete the API.

1. Create a persistence layer to hold details of all the Constellations
2. Populate the persistence layer
3. Create a JAX-RS endpoint to query the persistence layer

## Create A Persistence Layer

Since we're using JPA, we need to create a `@Entity` class to represent a Constellation and a DAO class to use to retrieve data from the backend database table. Since I'm using TomEE, I can use the embedded HSQLDB and don't need to install any new drivers. All the required dependencies are provided out of the box.

First off, we need to create an `@Entity` class

```java
package com.davidsalter.constellationapi.entity;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

@Entity
@Table(name = "Constellation")
@NamedQuery(name = "Constellation.findAll", query = "SELECT c FROM Constellation c")
public class Constellation {
  private static final long serialVersionUID = 1L;

  public Constellation() {
  }

  private String name;

  @Id
  private String abbreviation;

  private String description;

  // Getters / Setters omitted
```

From this code, we can see that an `@Entity` class has been defined that is backed off by a database table called `Constellation` This table has 3 fields

---

| Field        | Description                                            |
| ------------ | ------------------------------------------------------ |
| name         | The name of a constellation.                           |
| abbreviation | The abbreviation for the constellation. This is the PK |
| description  | The description for the constellation,                 |

---

The class also defines a single `@NamedQuery` to get a list of all of the Constellations form the database.

So, the `Constellation` class represents a single entity, so we need to write a DAO class to be able to retrieve all the entities from the database.

The `ConstellationDao` class looks like the following:

```java
package com.davidsalter.constellationapi.controller;

import java.util.List;

import javax.enterprise.context.RequestScoped;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import com.davidsalter.constellationapi.entity.Constellation;

@RequestScoped
public class ConstellationDao {

  @PersistenceContext(name = "constellation-pu")
  private EntityManager em;

  public List<Constellation> findAllConstellations() {
    return em.createNamedQuery("Constellation.findAll", Constellation.class).getResultList();
  }
}
```

This class simply provides one method (`findAllConstellations`) that executes the `@NamedQuery` we created within the `Constellation` class.

The class makes use of an `EntityManager` to query the database. This in turn uses a persistence unit called `constellation-pu` to define the database and how it is created.

Within the `META-INF/persistence.xml` file, we define the persistence unit as follows:

```xml
<persistence version="2.2"
  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_1.xsd">
  <persistence-unit name="constellation-pu">
    <provider>org.apache.openjpa.persistence.PersistenceProviderImpl
    </provider>

    <jta-data-source>constellationDatasource</jta-data-source>
    <properties>
      <property name="openjpa.jdbc.DBDictionary" value="hsql" />

      <property
        name="javax.persistence.schema-generation.database.action"
        value="drop-and-create" />
      <property
        name="javax.persistence.schema-generation.create-source"
        value="metadata" />
      <property
        name="javax.persistence.schema-generation.drop-source"
        value="metadata" />
      <property name="javax.persistence.sql-load-script-source"
        value="META-INF/import.sql" />
    </properties>
  </persistence-unit>
</persistence>
```

This persistence unit specifies that it uses a JTA data source called `constellationDatasource`. We'll see how this is defined in a minute. For now though, lets look at the properties that we define for the data source.

First of all, we tell OpenJPA that we are using a HSQL database. We then define that the schema must be dropped and created (`drop-and-create`) everytime the application is run. In this example application, we are seeding the database everytime we run the app as we're going to use an in-memory database. This technique of dropping and creating a database is most likely, not suitable for production use !

The next two properties tell JPA how to create and drop the database table(s). In this case, to use the metadata defined for the `Consteallation` class, rather than via user defined scripts.

Finally, the `sql-load-script-source` tells JPA to run the script `META-INF/import.sql` to seed the database. We'll look at this a bit later.

So, the persistence unit specifies that we are to use a JTA datasource called `constellationDatasource`, but where is that defined ? In TomEE, datasources can be defined within a file called `META-INF/resources.xml` In this instance, as below:

```xml
<Resource id="constellationDatasource" type="javax.sql.DataSource">
    defaultAutoCommit = true
    jdbcDriver = org.hsqldb.jdbcDriver
    jdbcUrl = jdbc:hsqldb:mem:hsqldb
    jtaManaged = true
    maxActive = 20
    password =
    passwordCipher = PlainText
    userName = sa
</Resource>
```

This code simply defines an in-memory hsql database that is accessed via a datasource called `constellationDatasource`.

## Populate Persistence Layer

We looked at this briefly before. Within the persistence unit, JPA allows us to specify a script that is run whenever the application starts up to seed the database with pre-defined data.

```xml
<property name="javax.persistence.sql-load-script-source"
  value="META-INF/import.sql" />
```

To load the constellations data into the database, this file contains an INSERT statement for each Constellation, e.g.

```sql
insert into constellation(name, abbreviation, description) values ('Andromeda', 'And', 'The Chained Maiden');
insert into constellation(name, abbreviation, description) values ('Antila', 'Ant', 'The Air Pump');
etc.
```

Remember we don't have to create the database table as that is done by JPA, and we don't need to worry about duplicate entries in the database as JPA drops and creates the schema everytime the application (and the script) is executed.

## Create JAX-RS Endpoint

We're nearly there !

In the previous sections, we've created a skeleton application, created a persistence layer and seeded the database with data. All that's left to do now is to develop a REST endpoint to query the data.

To use JPA, we need to define an `Application` that specifies the base URI of the endpoint. The MicroProfile Starter did this for us automatically within the `ConstellationapiRestApplication` class

```java
package com.davidsalter.constellationapi;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/api")
public class ConstellationapiRestApplication extends Application {
}
```

This class simply defines that the base URI of our endpoint will be `/api`

To implement an endpoint, we need to write a Resource that uses the DAO we created earlier to query the database. This is shown below:

```java
package com.davidsalter.constellationapi.boundary;

import java.util.List;

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import com.davidsalter.constellationapi.controller.ConstellationDao;
import com.davidsalter.constellationapi.entity.Constellation;

@Path("constellations")
@RequestScoped
public class ConstellationResource {

  @Inject
  private ConstellationDao constellationDao;

  @GET
  @Produces(MediaType.APPLICATION_JSON)
  public List<Constellation> getConstellations() {
    return constellationDao.findAllConstellations();
  }
}
```

This class simply injects an instance of our `ConstellationDao`, calls the method `findAllConstellations` on it, and then returns the result as JSON to the caller.

OK. So we're there?

We've build an endpoint that will return the required data. We can build and execute the endpoint with:

```bash
$ mvn clean package tomee:run
```

and then test it with:

```bash
$ curl http://localhost/api/constellations
[{"abbreviation":"And","description":"The Chained Maiden","name":"Andromeda"},
etc...
```

All looks good so far. However, since our React website is running separately from TomEE, we'll need to configure [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) within TomEE to enable the React application to call the TomEE web services. We'll see how this can be done in Part 2.