RESTful Web Services using Java and Spring

Posted on - Last Modified on

Spring is a modular application framework which was adopted by the Java community to replace the Java EE modules. It gained a lot of traction, since it has everything what a developer nowadays needs, like IoC, Transactional execution, MVC web framework, and a framework for Android mobile development. It also supports Aspect Oriented Programming (AOP) and convention is preferred over configuration. Along with the Spring Data module, it supports MongoDB out of the box.

For this article I used the Spring Data MongoDB module, as you will see this is very easy to use and you can become productive in no time.

Data Model

As with any RESTful Web service there has to be a data layer defined. I used the Contact Card database and I created the Contact class in the contact_cards.models Java package. The class has the @Document annotation -- this specifies which collection should be used from the database. The @Field annotations map the fields in the Mongo collection to the class attributes. 

package contact_cards.models;

import java.util.Date;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

@Document(collection="contacts")
public class Contact {
	@Id
	private String id;
	
	@Field(value="first_name")
	private String firstName;
	
	@Field(value="last_name")
	private String lastName;
	
	@Field(value="website")
	private String website;
	
	@Field(value="email")
	private String email;
	
	@Field(value="work_phone")
	private String workPhone;
	
	@Field(value="home_phone")
	private String homePhone;
	
	@Field(value="mobile_phone")
	private String mobilePhone;
	
	@Field(value="birthday_phone")
	private Date birthday;
}

Repository

From implementation point of view, the repository is the simplest. When running the application, many things happen in the background. I only defined the interface of the repository, which extends the MongoRepository<> interface from Spring Data MongoDB module. The actual implementation of the interface will be generated runtime by Spring, using the given type parameters.  The implementation for the public methods listed in the interface is generated by Spring (here comes into play the convention over configuration).

Spring does the following before code generation (high level):

  1. Splits the name of the method in 2-3 parts 
  2. The first part is findBy, based on this Spring knows it needs to generate search MongoOperations 
  3. The second part is considered as a member/property of the class which the MongoRepository was declared for (in this case Contact). The class member has to have getter and setter methods defined, if it does not have compile errors appear 
  4. Checks the third part; it has to be one of the keywords (basically comparison operators): Like, Between, GreatherThan, LessThan, LessThanOrEqualTo, NotIn, Null, NotNull and so on. If there is no third part, it applies the equality comparator.
package contact_cards.repositories;

import java.util.List;
import org.springframework.data.mongodb.repository.MongoRepository;
import contact_cards.models.Contact;

public interface ContactRepository extends MongoRepository<Contact, String> {
	public List<Contact> findByFirstName(String firstName);
	public List<Contact> findByLastName(String lastName);
	public List<Contact> findByWebsite(String website);
	public List<Contact> findByEmail(String email);
	public List<Contact> findByMobilePhone(String mobilePhone);
	public List<Contact> findByMobilePhoneNull();
}

Controller

Implementing REST controllers in Spring is easy. The class has to have the @RestController annotation, webmethods need the @RequestMapping annotation, which helps the Spring routing engine to map request URLs to webmethods in the controller.  

The controller has an Autowired private member, an instance of the ContactRepository class. In the getAllContacts() method I used the findAll() method of the repository, although this was not defined in the interface. I could use it, because the MongoRepository interface extends the PagingAndSortingRepository (which extends CrudRepository) and this one has the findAll() method defined.

//Import statements removed
@RestController
public class ContactController {

	@Autowired
	private ContactRepository repository;

	@RequestMapping("/contacts")
	public List<Contact> getAllContacts() {
		List<Contact> result = new LinkedList<Contact>();
		result = repository.findAll();
		return result;
	}

        // Code removed

	@RequestMapping("/contacts/mobile_phone")
	public List<Contact> getContactsByMobilePhone(
		@RequestParam(value="value", required=false) String mobilePhone) {
		List<Contact> result = new LinkedList<Contact>();

		if (!StringUtils.isEmpty(mobilePhone)) {
			result = repository.findByMobilePhone(mobilePhone);
		}
		else {
			result = repository.findByMobilePhoneNull();
		}
		return result;
	}
}

In the getContactsByMobilePhone() method, depending on the @RequestParam I use the findByMobilePhone() or findByMobilePhoneNull() method for looking up the contacts in the database.

Java has always been the WORA (write once, run anywhere) programming language. Even today, if people want software running on any platform (Mac, Windows and Linux) they will stick with Java (especially in the Enterprise sector).

Comparing the implementation of RESTful services between ASP.NET Web API and Spring MVC is interesting, because creating the implementation of the RESTful service is more or less the same effort, but in this case Spring has much better support for MongoDB as .NET hast, so if I’d need to implement a RESTful service API using MongoDB as a data store, I’d use Java and Spring. In case the data store is MSSQL server then Entity Framework and ASP.NET Web API would be the way to go. 

The project is on GitHub, you can use Eclipse or STS (Spring Tool Suite) to import and try it out. For additional settings check the MongoConfiguration.java file.

Posted 29 January, 2015

Greg Bogdan

Software Engineer, Blogger, Tech Enthusiast

I am a Software Engineer with over 7 years of experience in different domains(ERP, Financial Products and Alerting Systems). My main expertise is .NET, Java, Python and JavaScript. I like technical writing and have good experience in creating tutorials and how to technical articles. I am passionate about technology and I love what I do and I always intend to 100% fulfill the project which I am ...

Next Article

Corey Rabazinski Up Next on Feb 5th’s WAMA