Develop a Microservices-based RESTful Java Application

Developing a microservice for the cloud today requires modern tools. This microservices example explores using the Helidon server along with Docker to make a cloud-ready application.

Helidon Server

The Helidon server is a collection of Java libraries for writing Microservices applications in a cloud environment. Key features of Helidon include:

  • Helidon is simple to use with tooling and examples to get you going quickly. The collection of libraries are fast and lightweight running on a Netty core.

  • Helidon provides familiar APIs like JAX-RS, CDI and JSON-P/B.

  • Helidon is lightweight, flexible, and reactive and provides a modern functional programming model.

  • Helidon provides support for health checks, metrics, tracing and fault tolerance. In addition, Helidon integrates with Prometheus, Zipkin and Kubernetes.

  • Helidon supports the MicroProfile standard.

Docker

Docker is enterprise container management software. Think of a container as a very lightweight virtual machine. A container allows you to run applications in their own isolated memory space while still maintaining access to common resources like filesystems. Containers stay lightweight by not requiring processor intensive systems like GUI support, device drivers, and other more advanced operating system components. Containers are built from images which are combined with local resources from the hosting operating system.

With Docker, a Helidon application can be packaged into an image. That image can then be passed to an orchestration system like Kubernetes. From there, the orchestration system deploys, runs, manages, sizes, and monitors the application as it runs. This provides a great degree of portability as the packaged application could be deployed to any Kubernetes cluster.

Before You Begin

It is strongly recommend that you read the preceding solution before beginning this solution. See Learn about architecting microservices-based applications on Oracle Cloud

Architecture

The following architecture diagram shows the completed RESTful Java microservices application. This microservices architecture focuses on building the actual RESTful Java application code that is deployed in Docker containers.

Figure - Completed Microservices Application Architecture

Description of Figure - follows
Description of "Figure - Completed Microservices Application Architecture"
  1. The RESTful web service client application, written in HTML/CSS/JavaScript, is used to access the application. The Bootstrap and jQuery frameworks are included in the client.
  2. The client connects to the application through a network. This could be a local network on a machine or the Internet.
  3. The backend application is a set of Docker containers running Helidon servers in a Kubernetes cluster. Typically, more than one copy of the application is deployed and a load balancer is used to select which instance the client communicates with. The containers are managed by the Kubernetes cluster which automatically scales the number of instances.
  4. The application uses an Oracle database for persistence. Any stored data is pushed to the database. No state is saved in the Kubernetes cluster.

About the Application

The RESTful application you create is a simple Employee Directory application.

The application has two main parts.

  • A microservice back end (written in Java)
  • A web service client (written in HTML, CSS and JavaScript)

The two parts demonstrate how a front end interacts with a microservices back end.

About the Microservices-Based Back End

The back end of the application is a microservice that's coded in Java and uses libraries from the Helidon project

The core of the application is the Main class and the EmployeeService class. The Main class loads the microservice and starts a Netty web server. The EmployeeService class defines the end points for the application and handles requests and responses. The application has only one microservice. But, a typical production application is likely to contain more services.

Note that the application is designed to be stateless. All data should be pushed to the database for persistence. This approach allows you to scale the application easily.

employee-app

The application implements the data access object (DAO) pattern and can be configured for two persistence stores. By default, the application uses a mock database written with in-memory ArrayList classes so you can test the application locally or in a Kubernetes cluster without a database connection. This configuration is selected in the src\main\resources\application.yaml file by setting the drivertype to Array. This guide only covers the ArrayList version of the application without a formal database.

To connect the application to an Oracle database, edit the src\main\resources\application.yaml file, fill the user, password, and hosturl properties and set the drivertype property to Oracle. This application configuration allows you to use an Oracle database as a persistence store. The code for using an Oracle database for persistence is not covered in this guide.

Note:

If more than one instance of the application is present in an application cluster, then new data is not replicated across nodes. Keep this in mind when testing.

About the Client

The client you use to access the microservice is coded using HTML, CSS, and JavaScript.

The application is written using a combination of BootStrap and jQuery. The application client is included with the source of the Java back end. When the application is built, the application directory is copied to the /public directory and is available to load from your browser at http://hostname:8080/public/index.html.

By default, the client looks for the microservice on the current host using port 8080.

About the REST Service

The REST back end is implemented in Java using the Helidon server. The server implements a few search operations along with standard create, read, update, and delete (CRUD) operations. The list of endpoints includes:

Endpoint Method Description
/ GET Get all employees
/lastname/{name} GET Search all lastname fields for the value provided in "name"
/department/{name} GET Search all department fields for the value passed in "name".
/title/{name} GET Search all title fields for the value provided in "name".
/ POST Add a new employee.
/{id} GET Get an employee by ID.
/{id} UPDATE Update an employee by ID.
/{id} DELETE Delete an Employee based on ID.