Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Basics for Setting Up a Microservices Architecture in a Project for Spring Boot and Gradle

DZone's Guide to

Basics for Setting Up a Microservices Architecture in a Project for Spring Boot and Gradle

Learn about the components needed to build microservices architecture in a project for Spring Boot and Gradle to enable continuous delivery/deployment.

· Microservices Zone ·
Free Resource

Containerized Microservices require new monitoring. See why a new APM approach is needed to even see containerized applications.

Microservices, also known as the microservices architecture, is an architectural style that structures an application as a collection of loosely-coupled services, which implement business capabilities. Microservice architecture enables the continuous delivery/deployment of large, complex applications, and allows organizations to evolve their technology stack. Its main advantage is scaling along with deployments. Below you'll find the essentials for a simple web application built using microservices architecture.

Image title

1. Spring Boot

Spring Boot makes it easy to create stand-alone applications with tomcat installed, which you can run by starting the jar file. A Spring Boot app does not require any kind of XML configurations; everything is done using just annotations. It is very simple to create a web app using Spring Boot. Below, you can see an example of a Spring Boot controller, which makes it so simple to create a web app with a REST service:

@Controller
@EnableAutoConfiguration
public class SampleController {

    @RequestMapping("/")
    @ResponseBody
    String home() {
        return "Hello World!";
    }

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

2. Gradle

Gradle is a Java building tool similar to Maven and Ant. Gradle is more powerful than both, as it is a combination of Maven and Ant. Gradle does not require any XML file, as it has its own DSL based in Groovy. Gradle is much simple and cleaner than Maven or Ant. We have the build.gradle file in it, which includes all the dependencies required for a web app. It also includes the jar name to be generated along with Java, Hibernate, and Database versions. Below is a code snippet from the build.gradle file:

apply plugin: 'java'
apply plugin: 'checkstyle'
apply plugin: 'findbugs'
apply plugin: 'pmd'

version = '1.0'

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
    testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: '1.3'
}

3. Discovery Server

Discovery Server is mainly used to have all the microservices' clients connected at a central place so that they can easily communicate. Eureka Discovery receives heartbeat messages from each instance belonging to a service. If the heartbeat fails over a configurable timetable, the instance is normally removed from the registry. By having @EnableDiscoveryClient, you can easily create a discovery client in a Spring Boot app.

@SpringBootApplication
@EnableEurekaServer
@EnableDiscoveryClient
public class EurekaApplication {

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

}

For all the discovery clients, you need to add the configuration below into the application.yml of each client module to locate its discovery server:

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

4. Central Config Server

The main functionality of having central-config-server is for storing all kind of configuration properties at a central place so that we do not need to go to each core module explicitly to change properties. It is actually connected to the discovery server, which makes it easy for each core's microservices to get its properties files. Whenever a change is made to a property file, we can just restart this server and the core module whose property file is changed; you will not even require any kind of build for the core module to get the updated properties. You place properties files at any specific location (Git, etc) and just specify the path of properties in the application.yml file. The code snippet below will give you an overview of the Central Config server:

@SpringBootApplication
@EnableConfigServer
@EnableDiscoveryClient
public class CentralConfigServerApplication {

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

application.yml

spring:
    profiles:
        active: native
    cloud:
        config:
            server:
                native:
                    searchLocations: file:./properties,classpath:config/

5. Gateway Server

Gateway/Zuul is an edge service that provides dynamic routing, monitoring, resiliency, security, and more. The main purpose of this is to provide security and routing for the core microservices. We can have different types of filters in the Gateway server so that we can manage security for any type of API call to the core microservices. It acts as a proxy between core microservices and the outside applications. 

package com.example.EmployeeZuulService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@EnableZuulProxy
@EnableDiscoveryClient
@SpringBootApplication
public class EmployeeZuulServiceApplication {
   public static void main(String[] args) {
      SpringApplication.run(EmployeeZuulServiceApplication.class, args);
   }
}

application.yml

zuul:
prefix: /application_name
    ignoredServices: "*"
    routes:
    coreservice_name: /coreservice_name/**

6. Orchestra Microservices Layer

The use of this layer in microservice architecture is to combine different kinds of responses from multiple core services and do more processing on the data, then publish them in the response. The main need for this layer is less as compared to all other layers. It is just a Spring Boot app which is communicating to discovery, gateway, and microservices but does not have any kind of interactions with the database part.

@RestController
@RequestMapping("orchestra")
public class OrchestraController {

  @Autowired
  @LoadBalanced
  protected RestTemplate restTemplate;


  protected Logger LOGGER = LoggerFactory.getLogger(getClass());

  @ApiOperation(value = "Retrieve combined list from two microservices")
  @RequestMapping(value="/combinedlists", method=RequestMethod.GET, produces= MediaType.APPLICATION_JSON_VALUE)
  public ResponseEntity<List<Object>> getCombinedList(HttpServletRequest request) {
    LOGGER.info("Inside getCombinedList method");
    List<Object> combinedList = new ArrayList<>();
    try {
      String url1 = "http://"+"<core_microservice_name1>"+"rest_api_url1";
      String url2 = "http://"+"<core_microservice_name2>"+"rest_api_url2";
      ResponseEntity<List<Object>> result1 = restTemplate.exchange(url1, HttpMethod.GET, null,new ParameterizedTypeReference<List<Object>>() {});
      ResponseEntity<List<Object>> result2 = restTemplate.exchange(url2, HttpMethod.GET, null,new ParameterizedTypeReference<List<Object>>() {});
      List<Object> list1 = result1.getBody();
      List<Object> list2 = result2.getBody();
      combinedList.addAll(list1);
      combinedList.addAll(list2);
    }
    catch(Exception e) {
      LOGGER.error("Exception in getCombinedList method:",e.getMessage());
      return new ResponseEntity<List<Object>>(combinedList,HttpStatus.INTERNAL_SERVER_ERROR);
    }
    LOGGER.info("Exit from getCombinedList method");
    return new ResponseEntity<List<Object>>(combinedList,HttpStatus.OK);
  }
}


7. Core Microservices Layer

This is the lowest layer in the microservices architecture, which actually performs a lot of operations on the database and process the data as per the need. The actual REST services are written in the core layer. This part does each operation of different transactions.

It has connections with the discovery through the @EnableDiscoveryClient annotations. As we already added environment level configurations in the central config server, we can still have application-level configuration settings/messages in the application.properties in the core module itself.

SampleServiceApplication.java

@SpringBootApplication
@EnableDiscoveryClient
public class SampleServiceApplication {

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

SampleServiceController.java

@RestController
public class RecommendationService {

    private static final Logger LOG = LoggerFactory.getLogger(RecommendationService.class);

    @Autowired
    private SetProcTimeBean setProcTimeBean;

    @Autowired
    private LoadBalancerClient loadBalancer;
private RestTemplate restTemplate = new RestTemplate();

    @RequestMapping("/recommendation")
    public List<Recommendation> getRecommendations(@RequestParam(value = "productId",  required = true) int productId) {
        List<Recommendation> list = new ArrayList<>();
        list.add(new Recommendation(productId, 1, "Author 1", 1, "Content 1"));
        list.add(new Recommendation(productId, 2, "Author 2", 2, "Content 2"));
        list.add(new Recommendation(productId, 3, "Author 3", 3, "Content 3"));
        return list;
    }
}

application.yml

server:
  port: 7878

eureka:
  instance:
    leaseRenewalIntervalInSeconds: 10
    metadataMap:
      instanceId: ${vcap.application.instance_id:${spring.application.name}:${spring.application.instance_id:${random.value}}}
  client:
    registryFetchIntervalSeconds: 5

bootstrap.yml

spring:
  application:
    name: sample
  cloud:
    config:
      enabled: true
      discovery:
        enabled: true
        serviceId: central-config-server


References 

https://spring.io/guides/gs/centralized-configuration/ x

https://spring.io/guides/gs/service-registration-and-discovery/ x

Automatically manage containers and microservices with better control and performance using Instana APM. Try it for yourself today.

Topics:
microservices ,software architecture ,ci/cd ,tutorial ,spring boot ,gradle

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}