Writing Microservices Using MSF4J

Zoe Lavena
SW|D
Published in
10 min readMar 30, 2019

This blog post will be a step-by-step demonstration of writing microservices using MSF4J (MicroService Framework for Java). We are going to work on the ABC Diners Application which will be discuss briefly later in this post. This will also cover the steps that are involved when creating or migrating or transitioning to microservices.

ABC Diners

ABC Diners is a restaurant application. Aside from taking orders from their customers and viewing orders, they post recipes that customers will rate while waiting for their food.

We are going to pretend that ABC Diners has already a monolithic-based application, and they wanted to migrate to using microservice-based application for reasons that their business is growing and they have too much requests and data to handle.

Three-Step Process

Based on the book Microservice Patterns with Examples in Java by C. Richardson, there is a three-step process to migrating to microservices [1]:

  1. Define Business Capabilities
  2. Define Services
  3. Define APIs and Collaborations

Define Business Capabilities. In this step, we have to identify the functional requirements of the system. Given the brief description of the ABC Diners business, we can tell that in these are the possible functional requirements that the application requires, see Figure 1 below.

Define Services. When defining the services, we have to group the functionalities that works in the same database.

In my previous post Microservices: Understanding the Background of Microservice Architecture, we define that a service is independent and has its own database structure. We have to lessen the joins for each databases as much as possible to enforce the major characteristics of microservices (modularity and loose coupling). Of course, there will be times that some services has to communicate or needs data from another service. If that is the case, we have to use the SAGA pattern to maintain data consistency.

For this demonstration, we are going to keep things simple. Given the list of functionalities on Figure 1, we can tell that add/delete/edit/rate recipe can be grouped into one service (and call it Recipe Service). View/Create orders can be grouped into another service (and call it Order Service), see Figure 2 below. Each of the ABC Diners application’s services has its own database named recipeDB and orderDB respectively.

Define APIs and Collaborations. This step is easy and straightforward, we just have to change our functional requirements into methods (and/or add more methods if we are required to). For example, Add Recipe will be called addRecipe() method in our code, see the rest on Figure 3 below.

Requirements and Tools

This demonstration requires at least a basic knowledge in the following areas:

  • Java (more specifically working with Maven projects)
  • REST API (basic annotations such as @GET, @POST, @PUT, @DELETE)
  • JPA (used for mapping objects)
  • MySQL (used for writing the database script)

Listed down are the tools that will be used in the demonstration:

  • Eclipse, NetBeans (used for development)
  • MySQL Workbench (used for viewing the data)
  • Postman (used for constructing requests and reading responses)

Common Errors

Before we move on, this post would like to introduce you to the common errors that might be encountered during the demonstration. We should be able to know how to migrate from and take actions to it.

  • POM File Not Found
  • Persistence Exception
  • Project Unloadable
  • Cannot Connect to the Database
  • Cannot Import javax

POM File Not Found. A POM file is a file that contains information about the Maven project and its configurations. This happens when you try to create a Maven project in NetBeans — NetBeans assumes that you already have a POM file in the directory where the project will be built. In Eclipse, it creates one if a POM file does not exist in the directory. This is also the reason why Eclipse will be used in the first part of the demo, and later on will switch to NetBeans (we will have to use database).

Persistence Exception. A persistence file is a configuration file in JPA. If this error occurs, the following steps has to be performed:

  • Delete the existing persistence.xml file
  • Delete the existing models
  • Generate new models
  • Rename persistence name, if necessary

Project Unloadable. If this error occurs, right click on the project and select clean and build.

Cannot Connect to the Database. If this error occurs, add the dependency jar file com.mysql.jdbc.

Cannot Import javax. If this error occurs, add the dependency jar file javax:javaee-web-api.

Demo 1: Hello World

Step 1: Open Eclipse IDE, click on the new icon, expand Maven, select Maven Project. Click on Next.

Step 2: Select Use default Workspace location. Click on Next.

Step 3: Choose the org.wso2.msf4j archetype. If it is not listed, click on Add Archetype and fill out the fields, see Figure: Adding MS4FJ Archetype. Click on Next.

Adding MSF4J Archetype

Step 4: Provide the following inputs. At this part, Order service will be created (will later on work on the Recipe service). Click Finish.

Step 5: Click on the Order project’s Application class and click the play button.

Order Microservice is running on port 8080

Hooray! We have created our first MicroService!

With just 5 steps, we have created our first microservice called Order. Let us dive into the code and analyze the components.

This microservice has Application and OrderResource classes. The Application class takes care of deploying the Order microservice — It creates a new OrderResource object, starts it, and deploys it at the default port 8080.

After all of those, our first microservice is up and running. OrderResource microservice is available at the path /service. Once we opened our favorite browser and typed in http://localhost:8080/service, it goes to the port 8080 and finds the service path. Since this is a get method, within the service path, it goes to the get method with the GET annotation and path “/” and performs whatever is inside the method. In this case, it will print out Hello from WSO2 MSF4J.

Demo 2: Order Service

In this part of the demo, we will slowly build our Order Service with all the functionalities listed in our Business Rules in NetBeans.

Step 1: Open the Order Microservice that was created using Eclipse before by clicking on the Open Project icon.

Step 2: Go to the directory where you saved the project, select it, and click on Open Project.

For this part of the demo, we will build our Order Microservice using a 4-tier architecture — remember that each Microservice can have its own architecture, but has to be careful. This means that we will be having 4 packages: application, database, models, service.

Step 3: Create new packages. Right-click on Source Packages > New > Java Package.

We should end up with the following package structure:

The application package will contain the microservice classes, which are the Application class and OrderResource class. The database package will contain all the files that relates to accessing our database (which includes the script, utilities, and brokers). The models package will contain the entity classes from the database, and the service package will contain the classes used to access the brokers in the database package.

Step 4: Copy the following SQL script, DBUtil code, and OrderBroker code under the database package.

orderDB.sql script
DBUtil.java
OrderBroker.java

Step 5: Generate new entity models from database. Make sure you ran the orderDB.sql script first. Right click on the models package > New > Entity Classes from Database…

Select Entity Classes from Database…
Select order > Add > Next
Rename to Order_ > Next
Set Association Fetch to eager > Set Collection Type to List > Finish

Step 6: Copy the OrderService code under the services package.

OrderService.java

After all of those, our project structure should look like this:

Now all we have left is the functionalities of our Order. Based on the business rules, Order should have the following methods:

From the model above, Order Service has two functionalities to perform: viewOrders. and createOrders(). The viewOrders() method is used to view all of the orders in the database — This means that we are getting from the database, and so this method will use the GET annotation. The createOrders() method is used to create an order and eventually add it into the database — This means that we are adding or putting an object into the database, and so this method will use the PUT annotation.

When we are creating methods for our Microservice, we have to make sure to use the appropriate REST annotations. The annotations are as follows:

  • GET (used to tell that this method does the get/retrieve functionality)
  • PUT (used to tell that this method does the add functionality)
  • DELETE (used to tell that this method does the delete functionality)
  • POST (used to tell that this method does the edit functionality)
  • PATH (identifies the path to the method to run)
  • PATHPARAM (used to map the PATH parameters to method parameters)
  • PRODUCES (used to indicate that this method returns an object)
  • CONSUMES (used to indicate that this method takes an object)

Step 7: viewOrders()

a.) First, create a regular java method that returns a list of Order_ objects from the database.

public List<Order_> viewOrders() {
// create new OrderService
OrderService os = new OrderService();
// call the method to get all the orders and return it
return os.getAllOrders();
}

b.) Add the annotations at the top of the method.

  • Identify that this method is GET
  • Identify the PATH to this method
  • Identify that this method returns an object
@GET
@PATH("/vieworders")
@PRODUCES(MediaType.APPLICATION_JSON)
public List<Order_> viewOrders() {
OrderService os = new OrderService();
return os.getAllOrders();
}

This states that the viewOrders method is available at /service/vieworders and returns a JSON object back to the browser.

We can test this out using Postman. Postman is a software used to create requests and build responses without using an actual browser. To test our viewOrders method, we have to run our Microservice first. Click on the project and hit the run button.

Launch Postman. Choose GET from the dropdown and type in the path to the method. Click Send.

Step 8: addOrder()

a.) First, create a regular java method that takes in parameters to create an Order object that eventually will get added into the database.

public Order_ addOrder(String tableNumber, String orderName) {
// create new OrderService
OrderService os = new OrderService();
// create an Order object from the parameters
Order_ order = new Order_
(0, Integer.parseInt(tableNumber), orderName);
// add the Order object into the database
os.addOrder(order);
//return the Order object
return order;
}

b.) Add annotations at the top of the method.

  • Identify that this method is POST
  • Identify that PATH to this method.
  • Identify the parameters needed for the PATH.
  • Identify that this method PRODUCES an object
  • Identify that this method CONSUMES an object
  • Map the PATH parameters to method parameters
@POST
@PATH("/addorder/{tableNumber}/{orderName}
@PRODUCES(MediaType.APPLICATION_JSON)
@CONSUMES(MediaType.APPLICATION_JSON)
public Order_ addOrder
(@PathParam("tableNumber") String tableNumber,
@PathParam("orderName") String orderName) {
OrderService os = new OrderService();
Order_ order = new Order_
(0, Integer.parseInt(tableNumber), orderName);
os.addOrder(order);
return order;
}

This states that addOrder method is available at /service/addOrder and it takes in parameters tableNumber and orderName. This method consumes and produces a JSON object. The PATHPARAM annotation tells that the “tableNumber” in the PATH parameter will be identified as the “tableNumber” parameter in the method (same thing will follow to orderName).

Again, we can test this using Postman. Re-run the project. Launch Postman. Choose POST from the dropdown and type in the path and required parameter in the text field. Click Submit.

Below is the entirety of the Order Service code:

Now we are done with the Order Service! All we have left to do is the Recipe Service and I will leave that as an exercise :) If you ever feel stuck at any point of this demonstration, feel free to check out my Github repositories for this demo: Order Service and Recipe Service.

Conclusion

When building Microservice using the MSF4J Framework, we have to make sure we have an understanding of the business rules to better design and build a service. When building a service, we have to take note of the port and path that this services will be available — As well as the path for its method/functionalities.

Microservice-based projects are easy to maintain as you can build services and define it at different ports. It provides flexibility on the choice of the languages and tools used to build each services.

References

[1] C. Richardson, Microservices Patterns with Examples in Java. New York: Manning Publications Co., 2019, pp. 44.

--

--