Rest Services

Exposing business logic as a REST API

Hello everyone, in my previous blog I have explained what is a REST api, what is its architecture and what is its utility in web application development. In this blog I would explain my fellow readers a simple way as to how can you expose a business logic as a REST api.

The pre-requisites that would be needed are 1) an IDE, it can be netbeans or eclipse. If you are using Eclipse please download the enterprise version of eclipse, or if you choose to work with the normal eclipse version then you have to separately set up eclipse for an enterprise project. 2) Maven, as I will be using Maven to build the project. 3) Apache Tomcat. I have used Apache tomcat 7. 4) The jars for jersey-core, jersey-server and jersey-build.

To my readers who will be using the normal eclipse version, I would try to explain first how you can set up your eclipse for a web application. I have used Eclipse Mars 4.5.1 version.

Step-1: First go to Help -> Install new software. It would look something like this

screenshot-1

Step-2: Click on “Check for updates”. As soon as you click here it would load the next screen where you have to specify your eclipse’s version release. Check the screenshot

screenshot-2

  1. Select your version of eclipse from the “Work with” drop down. Once the version is selected eclipse will list down the components within the release.
  2. Select what component of the version you want to install.
  3. Then click on Next. Once you do that it will probably take some amount of time to install the components. Once the installation finishes your eclipse is ready to create web applications.

Step-3: Click on File -> New -> Java Project. Please check the following screenshot.

screenshot-3

Step-4: Create a Dynamic Web Project from here

screenshot-4

  1. Under new project goto the Web section.
  2. Click on Dynamic Web Project.
  3. Click on Finish.

The following web directory structure would look something like this.

Screenshot-5.png

Step-5: Download your choice of application server. I have used Tomcat 7.0 for this application. You can download it from Apache Tomcat version 7.0 . Once downloaded just copy the entire content into the Library directory. Not a necessary step but I preferred to do it. The following command to do it is sudo cp -r Downloads/Tomcat/ Library for Linux and Unix systems. For windows you can copy it into any folder.

Step-6: Next click on ‘Preferences’

Screenshot-6

Once clicked on Preferences eclipse will open up the preferences dialog box from where you can go to the server section. Under server section you will get the option to set up the server when you click on the runtime environments.

screenshot-7

Click on add to configure a server. I already have tomcat configured in the eclipse system.

screenshot-8

Screenshot-9

  1. Select your specific apache tomcat version.
  2. Enter the correct path for apache tomcat.
  3. Click on Finish.
  4. After the installation of the tomcat server is done there will be a directory created in the eclipse system as Servers something like this.

Screen Shot 2016-04-19 at 3.49.32 pm

Click on Tomcat v7.0 Server at localhost.server. It will look something like this

Screen Shot 2016-04-19 at 3.51.05 pm

By default the option would be set to “Use workspace metadata (does not modify Tomcat installation)” to “Use Tomcat installation (takes control of Tomcat installation)”

So your tomcat is set up in your eclipse. So if you start tomcat on port 8080 you will have an option to login to the manager app to handle your applications from the server itself. It provides a portal for that by default. But you will not access to have. For that you have to specifically define roles, the username and the password which you need to allocate it to the specific manager role. You can define the roles and the username and password for that in the tomcat-users.xml file under the server section in eclipse. The following needs to be scripted down in the XML file

<tomcat-users>
 <role rolename="manager-gui"/>
 <role rolename="manager-script"/>
 <role rolename="manager-jmx"/>
 <role rolename="manager-status"/>
 <role rolename="admin-gui"/>
 <role rolename="admin-script"/>
 <user username="admin" password="admin" roles="manager-gui,manager-script,manager-jmx,manager-status,admin-gui,admin-script"/>
<tomcat-users/>

So the next time you open the manager-app UI, you just need to provide the username admin and password admin and you are in, the list of the applications will be listed infront of you.

Now you have the dynamic web project ready to be implemented.

Step-7: Now since I am using maven to build my project hence you need to upgrade your project to a maven project. For that you need to right click on project -> Maven -> Update Project 

Screenshot-10

Once it is updated now you can add the following dependencies in the pom.xml. You have to declare dependencies for

  1. Jersey-core.
  2. Jersey-server.
  3. Jersey-bundle.
  4. asm
  5. JSON

So, Jersey implementation provides a library to implement Restful web services in a Java servlet container and ASM is an all purpose Java byte code manipulation and analysis framework. It can be used to modify existing classes or dynamically generate classes, directly in binary form. Besides using these libraries you need to also have the JSON library to parse the desired output in JSON format.

Here is how my pom.xml looks like

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0modelVersion>
  <groupId>RestAPIgroupId>
  <artifactId>RestAPIartifactId>
  <version>0.0.1-SNAPSHOTversion>
  <packaging>warpackaging>
  <build>
   <sourceDirectory>src<sourceDirectory>
   <plugins>
     <plugin>
       <artifactId>maven-compiler-pluginartifactId>
       <version>3.3version>
       <configuration>
         <source>1.7<source>
         <target>1.7<target>
       <configuration>
     <plugin>
     <plugin>
       <artifactId>maven-war-pluginartifactId>
       <version>2.6<version>
       <configuration>
         <warSourceDirectory>WebContent<warSourceDirectory>
         <failOnMissingWebXml>false<failOnMissingWebXml>
       <configuration>
     <plugin>
   <plugins>
 <build>
 <dependencies>
   <dependency>
      <groupId>asmgroupId>
      <artifactId>asmartifactId>
      <version>3.3.1version>
  <dependency>
  <dependency>
      <groupId>com.sun.jerseygroupId>
      <artifactId>jersey-bundleartifactId>
      <version>1.19.1version>
  <dependency>
  <dependency>
    <groupId>org.jsongroupId>
    <artifactId>jsonartifactId>
    <version>20140107version>
 <dependency>
 <dependency>
   <groupId>com.sun.jerseygroupId>
   <artifactId>jersey-coreartifactId>
   <version>1.19.1version>
 <dependency>
 <dependency>
   <groupId>com.sun.jerseygroupId>
   <artifactId>jersey-serverartifactId>
   <version>1.19.1version>
 <dependency>
<dependencies>
<project>

You can get the dependency xml structure for the following jars from here. You just need to type the following requirements in search. it looks like the following

Screenshot-11

I would prefer using dependency structures from here because you will understand the following versions of the jar that are compatible presently with maven and the packages assigned to the following libraries. So you just need to pick up the dependency structure from here and just paste it in the pom.xml

So till now you have

  1. Updated your eclipse to support “Dynamic web projects”.
  2. You have configured apache tomcat with eclipse.
  3. You have updated your project to a maven project.
  4. You have updated your pom.xml structure with all the dependencies so that you are ready to build your project.

So, once these are all done, I will start writing my servlets under the src directory under a package container.

Screenshot-12

So, as I mentioned in my last blog of REST api that you can access the following resources of an API over an URL. So lets get to understanding how can you implement REST services.

As I said, I have been using the Jersey implementation. So Jersey implementation makes it much easier to implement a REST api service. I have followed the Agnostic application deployment model. So JAX-RS provides a deployment agnostic abstract class Application for declaring the root resource and the provider classes. A web service may extend this class to declare a root resource and provider classes. So the Root Resource will be the point of contact or communication with the rest of the provider classes. The structure will look somewhat like this

Screenshot-13

I have used the class MyApplication as the root class.  The MyApplication class extends the Application class

So the @ApplicationPath annotation allows you to access the root class as an url. Now as you can see that the get class () method returns the set of provider classes to the calling function. You can add as many provider classes inside the get classes() method. The agnostic application jersey implementation helps deployment at class level i.e you can deploy the application without the servlets declared within the web.xml.

The implementation of the root class looks like the following

package com.expose.restapi;

import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/testapp")

public class MyApplication extends Application
{
   @Override
   public Set<Class<?>> getClasses()
   {
     Set<Class<?>> set = new HashSet<>();
     set.add(CtoFService.class);
     set.add(FtoCService.class);
     return set;
   }
}

So as you see there are two provider classes that I have declared the CtoFService class and the FtoCService class. So in the two classes I have implemented both ways how you can 1) produce the api service in XML format and as well as JSON format. 2) implement in such a way so that I can use a query as well as a query parameter to access the REST API service. Here is an example of how you can do it.

package com.expose.restapi;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import org.json.JSONException;
import org.json.JSONObject;

@Path("/ftocservice")
public class FtoCService
{
  @GET
  @Produces("application/json")
  public Response convertFtoC() throws JSONException
  {
     JSONObject jsonObject = new JSONObject();
     Double fahrenheit = 98.24;
     Double celsius;
     celsius = (fahrenheit - 32)*5/9;
     jsonObject.put("F Value", fahrenheit); 
     jsonObject.put("C Value", celsius);
     String result = "@Produces(\"application/json\") Output: \n\nF to C Converter Output: \n\n" + jsonObject;
     return Response.status(200).entity(result).build();
 }

 @Path("{F}")
 @GET
 @Produces("application/json")
 public Response convertFtoCfromParameter(@PathParam("F") float F) throws JSONException
 {
   JSONObject jsonObject = new JSONObject();
   float celsius;
   celsius =  (F - 32)*5/9;
   jsonObject.put("F Value", F);
   jsonObject.put("C Value", celsius);
   String result = "@Produces(\"application/json\") Output: \n\nF to C Converter Output: \n\n" + jsonObject;
   return Response.status(200).entity(result).build();
 }
}

For more details you can use my git hub REST-API link to get a better over view of how REST api is functioning.

 
Soumyajit Basu

Leave a Reply

Your email address will not be published. Required fields are marked *