Microservice Architecture - Hands-On SOA



In this chapter, we will develop a CRUD-based application with SOA architecture. Later on in the subsequent chapters, we will break this service into microservice and we will learn the basic difference between SOA and microservice architecture.

System Configuration and Setup

In this section, we will build a sample CRUD application, which will return a JSON object as a response whenever we call our service. We will use the Jersey framework to develop the same. Following are the steps to set up your local system environment.

Developing a CRUD Application

Step 1 − We will use NetBeans as development IDE. Please download and install the latest version available on NetBeans official website https://netbeans.org/downloads/.

Step 2 − Open your NetBeans IDE. Go to “File -> New Project”. The following screenshot pops up. Choose “Maven” as a category and select “Project from ArchType” as a project and hit Next.

Screenshot Pops Up

This will download all the required jar files to create your first ever Maven project and RESTful Web Service.

Step 3 − On hitting the Next button in the previous step, the following screenshot appears. Here, you will have to specify the Maven Archetype.

Maven Archetype

In the search box, search for “Jersey-archType-Webapp(2.16)” and check the “Show Older” checkbox.

Step 4 − Once you have selected the same, you will be redirected to the following screen. Select the preferred jar from the list and hit Next to continue.

Redirected Screen

Step 5 − In this step, you need to provide the name of your project and its Group Id as well as the package details. After providing all this information, hit Finish to continue.

Group Id

Step 6 − You are done with your workspace setup. The project directory will look like the following.

Workspace Setup

Check out your “Dependencies” folder and you will find that Maven has automatically downloaded all the required jar files for this project.

Dependencies

Step 7 − Your workspace is set up and you can start with coding. Go ahead and create four classes and packages as mentioned in the following screenshot. You can find MyResource.java is already created by Maven, as Maven is smart enough to detect that you are going to build your own web service.

Source Packages

Step 8 − Once done with the above step, we will construct our POJO class that is UserProfile.java as follows.

package com.tutorialspoint.userprofile.Model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class UserProfile {
   private long ProId;
   private String FName;
   private String LName;
   private String Add;
   public UserProfile(){}
   
   public UserProfile(long Proid, String Fname, String Lname,String Add) {
      this.ProId = Proid;
      this.FName = Fname;
      this.LName = Lname;
      this.Add = Add;
   }
   public long getProId() {
      return ProId;
   }
   public void setProId(long ProId) {
      this.ProId = ProId;
   }
   public String getFName() {
      return FName;
   }
   public void setFName(String FName) {
      this.FName = FName;
   }
   public String getLName() {
      return LName;
   }
   public void setLName(String LName) {
      this.LName = LName;
   }
   public String getAdd() {
      return Add;
   }
   public void setAdd(String Add) {
      this.Add = Add;
   }
}

Step 9 − Now we will create our Database class. As this is a part of learning material, we will not use any DB as our database. We will use an inbuilt Java memory to work as our temporary memory. As you can see in the following set of code, we will use MAP as our database. All the web service operation that we perform, we will work on this MAP defined in the class.

package com.tutorialspoint.userprofile.DAO;

import com.tutorialspoint.userprofile.Model.UserProfile;

import java.util.HashMap;
import java.util.Map;

public class DatabaseClass {
   private static Map<Long,UserProfile> messages = new HashMap<Long,UserProfile>();
   public static Map<Long,UserProfile> getUsers() {
      return messages; 
      // Each time this method will return entire map as an instance of database
   }
}

Step 10 − Now let us build our service class. Go ahead and copy paste the following set of code in the “ProfileService.java” class. This is the class where we will declare all our web service methods that is to be exposed for the outer world. We need to create one reference of our DatabaseClass such that our temporary database can be accessed in this class.

package com.tutorialspoint.userprofile.service;

import com.tutorialspoint.userprofile.DAO.DatabaseClass;
import com.tutorialspoint.userprofile.Model.UserProfile;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class ProfileService {
   private Map<Long,UserProfile> Userprofiles = DatabaseClass.getUsers();
   
   // Creating some predefine profile and populating the same in the map
   public ProfileService() {
      UserProfile m1 = new UserProfile(1L,"Tutorials1","Point1","TutorialsPoint.com");
      UserProfile m2 = new UserProfile(2L,"Tutorials2","Point2","TutorialsPoint.com2");
      UserProfile m3 = new UserProfile(3L,"Tutorials3","Point3","TutorialsPoint.com3");
      UserProfile m4 = new UserProfile(4L,"Tutorials4","Point4","TutorialsPoint.com4");
      
      Userprofiles.put(1L, m1);
      Userprofiles.put(2L, m2);
      Userprofiles.put(1L, m3);
      Userprofiles.put(2L, m4);
   }
   
   //Method to fetch all profile
   public List<UserProfile> getAllProfile() {
      List<UserProfile> list = new ArrayList<UserProfile>(Userprofiles.values());
      return list;
   }  // Method to fetch only one profile depending on the ID provided
   
   public UserProfile getProfile(long id) {
      return Userprofiles.get(id);
   }  //Method to add profile
   
   public UserProfile addProfile(UserProfile UserProfile) {
      UserProfile.setProId(Userprofiles.size()+1);
      Userprofiles.put(UserProfile.getProId(), UserProfile);
      return UserProfile;
   }  //method to update Profile

   public UserProfile UpdateProfile(UserProfile UserProfile) {
      if(UserProfile.getProId()<=0) { 
         return null;
      } else { 
         Userprofiles.put(UserProfile.getProId(), UserProfile);
         return UserProfile;
      }
   } //method to delete profile
   
   public void RemoveProfile(long Id) {
      Userprofiles.remove(Id);
   }
}

Step 11 − In this step, we will create our Resource class that will be linked with the URL and the corresponding service will be called.

package com.tutorialspoint.userprofile.Resource;

import com.tutorialspoint.userprofile.Model.UserProfile;
import com.tutorialspoint.userprofile.service.ProfileService;

import java.util.List;
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;

@Path("/Profile")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)

public class ProfileResource {
   ProfileService messageService = new ProfileService();
   
   @GET
   public List<UserProfile> getProfile() {
      return messageService.getAllProfile();
   }

   @GET
   @Path("/{ProID}")
   public UserProfile getProfile(@PathParam("ProID")long Id) {
      return messageService.getProfile(Id);
   }

   @POST
   public UserProfile addProfile(UserProfile profile) {
      return messageService.addProfile(profile);
   }

   @PUT
   @Path("/{proID}")
   public UserProfile UpdateProfile(@PathParam("proID")long Id,UserProfile UserProfile) {
      UserProfile.setProId(Id);
      return messageService.UpdateProfile(UserProfile);
   }
   
   @DELETE
   @Path("/{ProID}")
   public void deleteProfile(@PathParam("ProID")long Id) {
      messageService.RemoveProfile(Id);
   }
}

Step 12 − Clean build the project and run it. If everything goes well then you should get the following output in the browser, while accessing http://localhost:8080/UserProfile/webapi/Profile” URL.

You can see different entries are populated using XML representation.

User Profiles

Different method can be tested using Postman by applying proper method URL.

@GET method − The following screenshot demonstrates how we can get the desired result for get request, which returns all user details.

Screenshot Demonstrates

@POST − The following request can be used to test our Post method. Notice how the proId has been generated automatically.

Post method

@PUT − This method will update the entries. The following screenshot demonstrates how Jersey takes the proId from the request URL and updates the same user profile reply.

Same User Profile Reply

In the same way, you can check for other methods available in your web services.

In the previous section, we have developed one service which will expose CRUD functionality. Now whenever we try to implement this service in our application, we need to create a client of this application and attach it to our application. In this chapter, we will learn how to build this functionality using the concept of Microservice. Following is a diagrammatic representation of our application built using the above steps.

Actor

The actor should be the entry point of our service. In this case “ProfileResource.java” performs the responsibility of an actor. This class will call different methods to perform different operations such as add, update and delete.

Decomposition of CRUD Application

According to the main principle of microservice, we need to have only one business task for each of the modules, hence one actor should not be responsible for all four CRUD functionalities. Consider the following example where we have introduced some new roles such that it will be conceptually clear to you that Microservice is an architectural representation of SOA.

Architectural Representation

“Main user” is the user who communicates with the ”Application Controller” to serve one’s needs. “Application Controller” is the one who just calls different “Resource Managers” depending upon the request from the end user. “Resource Manager” does the job that is required to be done. Let’s take a quick look on the different roles of different units of the application.

  • End User/Main Users − Requests for some resources to Application Controller.

  • Application − Receives the request and forwards the same to specific Resource Manager.

  • Resource Manager − Does the actual job of updating, deleting, and adding users.

See how the total responsibility of one class is distributed among different other classes.

Advertisements