Day: May 4, 2017

Microservices with Spring Boot

Introduction

Currently enterprise application development is more interested towards building them as microservices. This trend started about 2 years back and some organizations take this as an opportunity to do a complete re-write of their products. To help developing microservices, several organizations have done framework implementations. In here I am talking about using Spring Boot to create a very basic microservice.

Use-case

This system is about handling patient records. So it is more like an CRUD application. To persist data, I am using a Mongo DB (embedded version). First, let’s see what would be structure of this project.

proj-structure

Fist you need to create a project with the above structure. You may find maven arc-types which helps to do that. Next the pom file should be created properly. Here, I’m showing the important sections of the pom file.

 <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
</parent>
...
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>

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

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

</dependencies>

 

Application.java file contains the main method to start the microservice. So it should looks like as follow:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

 public static void main(String[] args) {
     SpringApplication.run(Application.class, args);
 }
}

ApplicationConfig.java file is used to provide configurations to Spring framework. Here we provide the location of the service and REST-Template. So it should look like follows:

 

import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

import javax.inject.Named;

@Configuration
public class ApplicationConfig {
    @Named
    static class JerseyConfig extends ResourceConfig {
        public JerseyConfig() {
            this.packages("com.project.capsule.rest");
        }
    }

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate;
    }
}

Next we can extend MongoRepository and create PatientReportRepository. This is very interesting capability of Spring framework as it can convert method names in to SQL queries directly.

import com.project.capsule.bean.PatientReport;
import org.springframework.data.mongodb.repository.MongoRepository;
import java.util.List;

public interface PatientReportRepository extends MongoRepository&lt;PatientReport, String&gt; {

 public List<PatientReport> findByName(String name);

 public List<PatientReport> findByNameLike(String name);

 public List<PatientReport> findByTimeBetween(long from, long to);

}

Now let’s create the bean class, PatientReport

 

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.springframework.data.annotation.Id;
import java.util.Map;

@JsonIgnoreProperties(ignoreUnknown = true)
public class PatientReport {

@Id
public String id;

public String name;
public int age;
public String sex;
public String doctorName;
public long time;
public String reportType;
public Map<String, Object> reportData;
}

Finally the service class, PatientReportService. You can define any number of methods and implement a custom logic.

import com.project.capsule.PatientReportRepository;
import com.project.capsule.bean.PatientReport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import javax.inject.Named;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.*;

@Named
@Path("/report")
public class PatientReportService {

@Autowired
private PatientReportRepository repository;

@POST
@Path("")
@Consumes(MediaType.APPLICATION_JSON)
public Response storePatientReport(@RequestBody PatientReport patientReport) {
repository.save(patientReport);
return Response.status(201).build();
}

@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public PatientReport retrievePatientReport(@PathParam("id") int id) {
PatientReport patientReport = repository.findOne(String.valueOf(id));
return patientReport;
}

@POST
@Path("find")
public List<PatientReport> findReports(@RequestParam Map<String, Object> map) {
List<PatientReport> patientReports = new ArrayList<PatientReport>();
Map<String, PatientReport> resultantMap = new HashMap<String, PatientReport>();
List<PatientReport> resultantReports;

if (map.containsKey("name") && map.get("name") != null) {
String patientName = (String) map.get("name");
if (!patientName.trim().equalsIgnoreCase("")) {
resultantReports = repository.findByNameLike(patientName);

for (PatientReport report : resultantReports)
resultantMap.put(report.id, report);

}
}
return patientReports;
}

}

Once you run the Application.java file, microservice will start from port 8080. You can change the post by giving argument “-Dserver.port=8090” etc. Thereafter you can use a REST client to send HTTP requests and see how it works!

References

[1] https://spring.io/blog/2015/07/14/microservices-with-spring

[2] http://blog.scottlogic.com/2016/11/22/spring-boot-and-mongodb.html

[3] https://dzone.com/articles/spring-boot-creating

Advertisements