Building Microservices with Spring Data REST

Rodrigo Soares Chaves
ITNEXT
Published in
6 min readJun 15, 2017

--

Microservices are currently getting a lot of attention from the IT market . Companies like Uber, Amazon, Microsoft, and Netflix are investing in the migration of their platforms from a Monolithic Architecture to a Microservice Architecture. To help other companies to do the same, the big market players are sharing a set of frameworks, documentations and new techniques to deal with the complexity of this new market. Some of these companies believe there are two options: innovate or die. At the same time, there are some skeptics in the software community who say that microservices is not something new, it is only a rebranding of SOA.

My goal with this article is to show how Microservice Architecture pattern enables you for more agile development.

Is this article we will use Spring Boot, Spring Data REST, Swagger 2, Mongo DB and Maven. If you don’t know any of theses technologies, no worries, I’ll do a short introduction before coding.

Spring Boot

Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”. Most Spring Boot applications need very little Spring configuration.

Features

  • Create stand-alone Spring applications
  • Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)
  • Provide opinionated ‘starter’ POMs to simplify your Maven configuration
  • Automatically configure Spring whenever possible
  • Provide production-ready features such as metrics, health checks and externalized configuration
  • Absolutely no code generation and no requirement for XML configuration

The reference guide includes detailed descriptions of all the features.

Spring Data REST

Spring Data REST builds on top of Spring Data repositories, analyzes your application’s domain model and exposes hypermedia-driven HTTP resources for aggregates contained in the model.

Features

Swagger 2

Swagger is the world’s largest framework of API developer tools for the OpenAPI Specification(OAS), enabling development across the entire API lifecycle, from design and documentation, to test and deployment.

Swagger UI interface.

Spring Data Mongo DB

The Spring Data MongoDB project applies core Spring concepts to the development of solutions using the MongoDB document style data store. It provides a “template” as a high-level abstraction for storing and querying documents. You will notice similarities to the JDBC support in the Spring Framework.

Maven

Apache Maven is a software project management and comprehension tool. Based on the concept of the Project Object Model (POM), Maven can manage a project’s build, reporting and documentation from a central piece of information.

Let’s do it

First, we need to create a Spring Boot Application using Spring Initializr. If you don’t have enough experience with Spring Boot please read this. The base code can be found at the end of article.

Adding Dependencies

Got to your pom.xml at the root folder and add the dependencies for Spring Data REST, MondoDB, Swagger 2 (Jars and UI) and Test.

<!--DATA REST-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>

<!--EMBED MONGO DB-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<version>1.50.5</version>
</dependency>


<!--DEPENDENCIES FOR SWAGGER DOCUMENTATION-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-data-rest</artifactId>
<version>2.7.0</version>
</dependency>

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
<scope>compile</scope>
</dependency>

<!--TEST-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

In this example we used embed MongoDB, therefore after restarting the server the data will be lost.

Setting up our Web-Service

@SpringBootApplication
@EnableAutoConfiguration
@EnableSwagger2
@Import({springfox.documentation.spring.data.rest.configuration.SpringDataRestConfiguration.class})
public class SpringRestApplication {

public static void main(String[] args) {
SpringApplication.run(SpringRestApplication.class, args);
}
}
  • SpringBootApplication: it’s a standard configuration for our REST Service. This annotation is equivalent to using @Configuration, @EnableAutoConfiguration and @ComponentScan
  • EnableAutoConfiguration: allow our Swagger2 and MongoDB dependencies to do their self-configuration.
  • EnableSwagger2: generates the API documentation based on Swagger 2.
  • @Import({springfox.documentation.spring.data.rest.configuration.SpringDataRestConfiguration.class}): imports the Spring Data REST configuration to the API documentation .

Model

Our targeted service manages Authors, Books and Categories.

@Document
public class Author {

@Id
private String id;

private String name;

@DBRef
private List<Book> books;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public List<Book> getBooks() {
return books;
}

public void setBooks(List<Book> books) {
this.books = books;
}
}
@Document
public class Book {

@Id
private String id;

private String name;

@DBRef
private Category category;

private Double price;

public Book() {
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Category getCategory() {
return category;
}

public void setCategory(Category category) {
this.category = category;
}

public Double getPrice() {
return price;
}

public void setPrice(Double price) {
this.price = price;
}
}
@Document
public class Category {

@Id
private String id;

private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}
}

RepositoryRestResource

Now the cool part about Spring Data REST, on annotating MongoRepositories with @RepositoryRestResource, the RepositoryRestHandler will map all the end-points based on our repository, simulating a RestController.

AuthorRepository

This repository will expose the CRUD operations. You can add your own methods following the Spring Data.

@RepositoryRestResource(collectionResourceRel = "authors", path = "authors")
public interface AuthorRepository extends MongoRepository<Author, String> {
Author findOneByBooks(Book book);
}

BookRepository

@RepositoryRestResource(collectionResourceRel = "books", path = "books")
public interface BookRepository extends MongoRepository<Book, String> {
List<Book> findByCategory(Category category);
}

CategoryRepository

@RepositoryRestResource(collectionResourceRel = "categories", path = "categories")
public interface CategoryRepository extends MongoRepository<Category, String> {
}

Setting Base Path

It is possible to setup a base path for Data REST services. Go to your application property file at “src/main/resources/application.properties”.

spring.data.rest.base-path=/api

Last Swagger Configuration

Following is an example of a Swagger API scan.

/**
* Created by rodrigo.chaves on 13/06/2017.
*/
@Configuration
public class SwaggerConfig {
@Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}

Let’s RUN IT!

We just need to go to the root folder and run “mvn spring-boot:run”.

RepositoryRestHandlerMapping is mapping and exposing our API.

Let’s TEST IT!

Open the Swagger API documentation from: http://localhost:8080/swagger-ui.html

Swagger lists all the end-points available in the web-service. You can test all the end-points created automatically for us. And we can see our additional method called “findOneByBooks”.

Let’s Try it out!

By using the swagger-ui we can test directly our API. Basically that is our result for “api/authors”.

The other interesting feature is that all the APIs have HATEOAS (Hypermedia as the Engine of Application State) pattern implemented out-of-the-box! A hypermedia-driven site provides information to navigate the site’s REST interfaces dynamically by including hypermedia links with the responses.

This example can be download on: https://github.com/LINKIT-Group/spring-data-rest or here

--

--