DEV Community

Ed Legaspi
Ed Legaspi

Posted on • Originally published at czetsuyatech.com

Microservice Architecture with Spring Cloud in Code

1. Overview

Microservice is a service-oriented architecture where an application is deployed as a collection of loosely-couple services. The goal is to make each service independent, fine-grained, scalable and flexible which allows faster testing and release.

Image description

2. Microservices

2.1 Business Services

2.1.1 applicant-services

Dummy service that returns a list of applicant names.

@GetMapping("/applicants-by-job")
public List<String> getApplicantsByJob() {

    log.debug("port={} get applicants by job", port);
    return Arrays.asList("Steve", "Bill", "Linus");
}
Enter fullscreen mode Exit fullscreen mode

2.1.2 job-services

Dummy service that returns a job title with a list of applicant names.

@GetMapping("/job-with-applicant-profiles")
public ResponseEntity listJobsWithApplicantProfiles() {

    log.debug("get job details with applicants");

    JobWithApplicantsDto result = new JobWithApplicantsDto();
    result.setJob("Java Developer");

    result.setApplicants(applicantProxy.getApplicantsByJob());

    return ResponseEntity.ok().body(result);
}
Enter fullscreen mode Exit fullscreen mode

2.2 Spring Cloud Services

2.2.1 naming-server / discovery-server

This server holds all the information about our microservices such as name, IP, and port. This information is used for exchanging a service name to IP address and port.

A simple naming-server typically has:

// pom.xml
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

// in application.yml
eureka:
  client:
    register-with-eureka: false
    fetch-registry: false

// in SpringBootApplication annotated class
@EnableEurekaServer
Enter fullscreen mode Exit fullscreen mode

2.2.2 api-gateway

It's a server that provides criteria-driven request routing. It also offers other features such as security, load balancing, logging, monitoring, etc.

API Gateway is not at all different from the naming-server. Thanks to Spring for doing the heavy lifting:

// pom.xml
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

// @Configuration annotated class
@Bean
public RouteLocator gatewayRouter(RouteLocatorBuilder builder) {

    return builder.routes()
        .route(p -> p
            .path("/get")
            .uri("http://httpbin.org"))
        .route(p -> p.path("/applicants/**")
            .uri("lb://applicant-services"))
        .route(p -> p.path("/jobs/**")
            .uri("lb://job-services"))
        .build();
}
Enter fullscreen mode Exit fullscreen mode

3. Spring Cloud Libraries

3.1 spring-cloud-starter-openfeign - this library is used for referencing service in the naming server

To enable this feature, @EnableFeignClients must be annotated to a configuration class.

To call an endpoint from another service, an interface must be created with the same method signature as the method from the other service. In this example, we are importing 2 endpoints from the applicant-service.

@FeignClient(name = "applicant-services")
public interface ApplicantProxy {

    @GetMapping("/applicants/applicants-by-job")
    List<String> getApplicantsByJob();

    @GetMapping("/applicants/top-applicants-by-job")
    public List<String> getTopApplicantsByJob();
}
Enter fullscreen mode Exit fullscreen mode

3.2 spring-cloud-starter-netflix-eureka-client - this library provides the necessary classes for our services to register to the discovery server.

To register to a naming-server, we need to add this configuration in each of the services:

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka // make sure that this address is correct
Enter fullscreen mode Exit fullscreen mode

3.3 spring-cloud-starter-sleuth - this library helps us trace our requests across different microservices by automatically adding a unique id to the logs.

As we can see in the logs, it started from api-gateway, pass thru job-services, and then application-services. In the 3 logs, notice the unique common id: 3b4039e47fb602a9. We can use this when tracing a request.

Image description

4. URLs

4.1 Eureka Server

http://localhost:8761

4.2 Applicant Services

http://localhost:8081/applicants/applicants-by-job
http://localhost:8081/applicants/top-applicants-by-job

4.3 Job Services

http://localhost:8080/jobs/job-with-applicant-profiles
http://localhost:8080/jobs/job-with-top-applicants

4.4 API Gateway

http://localhost:8000/applicants/applicants-by-job
http://localhost:8000/applicants/top-applicants-by-job
http://localhost:8000/jobs/job-with-applicant-profiles
http://localhost:8000/jobs/job-with-top-applicants

5. Git Repository

https://github.com/czetsuya/lab-microservice-spring

6. Summary

This blog teaches the basics of microservice composition and the tools we can leverage to set up such infrastructure. A more in-depth explanation and demonstration are in the video.

Top comments (0)