opencodez

Building Restful Web Services using Java

When we think of web services the one obvious question comes to our mind is Soap or Restful? And what are the differences and advantages over one another. In this article we are not going to discuss about the pros an cons of them. When we are developing Restful Web Services we need make sure that we support what is expected out of REST Architectural style. That is x

We will see how we can develop simple restful web services using Java and Spring Boot. We will implement CRUD operations using restful web services.

Software used

As mentioned earlier we are using Spring Boot here so all the necessary code plumbing will be done by it and we will directly concentrate on our code sample. We will go through a sample where we will create, update,  get and delete a user from our application system. The pom.xml for reference is as below

x?xml version="1.0" encoding="UTF-8"?x
xproject 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"x
	xmodelVersionx4.0.0x/modelVersionx

	xgroupIdxcom.opencodezx/groupIdx
	xartifactIdxrestful-demox/artifactIdx
	xversionx0.0.1-SNAPSHOTx/versionx
	xpackagingxjarx/packagingx

	xnamexrestful-demox/namex
	xdescriptionxDemo project for Spring Bootx/descriptionx

	xparentx
		xgroupIdxorg.springframework.bootx/groupIdx
		xartifactIdxspring-boot-starter-parentx/artifactIdx
		xversionx1.4.7.RELEASEx/versionx
		xrelativePath/x x!-- lookup parent from repository --x
	x/parentx

	xpropertiesx
		xproject.build.sourceEncodingxUTF-8x/project.build.sourceEncodingx
		xproject.reporting.outputEncodingxUTF-8x/project.reporting.outputEncodingx
		xjava.versionx1.8x/java.versionx
	x/propertiesx

	xdependenciesx
		xdependencyx
			xgroupIdxorg.springframework.bootx/groupIdx
			xartifactIdxspring-boot-starter-webx/artifactIdx
		x/dependencyx

		xdependencyx
			xgroupIdxorg.springframework.bootx/groupIdx
			xartifactIdxspring-boot-starter-testx/artifactIdx
			xscopextestx/scopex
		x/dependencyx
	x/dependenciesx

	xbuildx
		xpluginsx
			xpluginx
				xgroupIdxorg.springframework.bootx/groupIdx
				xartifactIdxspring-boot-maven-pluginx/artifactIdx
			x/pluginx
		x/pluginsx
	x/buildx


x/projectx

In this example we are not using any database but will use a static map which serves like our database during our application run. We have written very simple class to help and interact with this map data. This class will be our repository.

/**
 * 
 */
package com.opencodez.rest.dao;

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

import org.springframework.stereotype.Repository;

import com.opencodez.rest.model.User;

/**
 * @author pavan.solapure
 *
 */
@Repository
public class UserServiceImpl implements UserService {

	private MapxString, Userx mapOfUser = new HashMapxString, Userx();

	public void addUser(User u) {
		mapOfUser.put(u.getId(), u);
	}

	public void deleteUser(String id) {
		mapOfUser.remove(id);
	}

	public void updateUser(User u) {
		mapOfUser.replace(u.getId(), u);
	}

	public User getUser(String id) {
		return mapOfUser.get(id);
	}

	public MapxString, Userx getMapOfUser() {
		return mapOfUser;
	}

}

As you can see we have very simple methods  in this class. We will autowire this as our repository and use it in our controllers.

As mentioned earlier we are using Spring Boot for all the underlying configuration. Our main controller is annotated with @RestController that means where every method returns a domain object instead of a view.
Its combined annotation for @Controller and @ResponseBody .

@RestController
public class MainController {

	@Autowired
	private UserService userService;
      
        //code here
}

Now we will see one by one each method from our CRUD operation.

Using HTTP GET

In this method we will send complete list of the users available in the system.

@RequestMapping(value = "/users/list", method = RequestMethod.GET)
public ResponseEntityxListxUserxx list() {
	ListxUserx users = new ArrayListxUserx(userService.getMapOfUser().values());
	return new ResponseEntityxListxUserxx(users, HttpStatus.OK);
}

You can see we have restricted the listing to only GET method. The method returns list of users as part of ResponseEntity. When we tested the get call in Postman you can see how we get the list of users as part of our response.

Using HTTP POST

@RequestMapping(value = "/users/add", method = RequestMethod.POST, consumes={MediaType.APPLICATION_JSON_VALUE})
public void addUser(@RequestBody User user) {
	userService.addUser(user);
}

As we are testing from Postman, I have restricted the input to JSON only. Here we are using Springs RequestBody annotation that helps us to map/convert the incoming HTTP request to our User Model. Check below the call we did for adding a resource.

If you use any other then POST method type, it will fail.

Using HTTP PUT 

Whenever we are updating any resource we need to use this method type.

@RequestMapping(value = "/users/update", method = RequestMethod.PUT, consumes={MediaType.APPLICATION_JSON_VALUE})
public void updateUser(@RequestBody User user) {
	userService.updateUser(user);
}

Request in Postman

After we updated a resource lets see if it got really changed or not

Using HTTP DELETE

As name suggest, we need to use this whenever we want to remove a resource.

@RequestMapping(value = "/users/delete/{userid}", method = RequestMethod.DELETE)
public ResponseEntityx?x deleteUser(@PathVariable(value = "userid") String userid) {
	User usr = userService.getUser(userid);
	if (usr == null) {
		return new ResponseEntity("User with id " + userid + " not found", HttpStatus.NOT_FOUND);
	}
	userService.deleteUser(usr.getId());
	return new ResponseEntityxUserx(HttpStatus.NO_CONTENT);
}

The postman request would be like

and the list after our api is executed successfully

Thats it. Its looks very easy when we combine Restful with Spring Boot.  You can download the code from our Github

Download Code

x