DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Distributed Tracing System (Spring Cloud Sleuth + OpenZipkin)
  • Full-Duplex Scalable Client-Server Communication with WebSockets and Spring Boot (Part I)
  • NGINX With Eureka Instead of Spring Cloud Gateway or Zuul
  • Implementation Best Practices: Microservice API With Spring Boot

Trending

  • Immutable Secrets Management: A Zero-Trust Approach to Sensitive Data in Containers
  • Using Python Libraries in Java
  • AI's Dilemma: When to Retrain and When to Unlearn?
  • Why Database Migrations Take Months and How to Speed Them Up
  1. DZone
  2. Software Design and Architecture
  3. Microservices
  4. Using Spring Cloud Gateway and Discovery Service for Seamless Request Routing

Using Spring Cloud Gateway and Discovery Service for Seamless Request Routing

In this tutorial, learn how to route requests between Java microservices with Spring Cloud Gateway and Discovery Service.

By 
Denis Magda user avatar
Denis Magda
DZone Core CORE ·
Aug. 04, 23 · Tutorial
Likes (7)
Comment
Save
Tweet
Share
17.0K Views

Join the DZone community and get the full member experience.

Join For Free

Spring Cloud is a versatile framework for building Java applications in various cloud environments. Today, we'll explore how to use two components of the framework - Spring Cloud Gateway and Discovery Service (aka Spring Cloud Netflix) - for easy routing of user requests between your Java microservices.

We'll build two microservices, register them with a Discovery Service instance, and use the Cloud Gateway for routing requests to a specific microservice instance. The cool thing is that the Cloud Gateway will also be registered with the Discovery Service and will use the latter to resolve a microservice name into an actual connection endpoint.

So, whether you prefer reading or watching, let’s walk through this practical example:

Creating Sample Microservices

Imagine we’re creating an online service for a pizza company. There are two basic capabilities the service needs to support - customers can order a pizza online and then track the order status. To achieve this, let's introduce two microservices - the Kitchen and the Tracker.

Kitchen Microservice

The Kitchen microservice allows customers to place pizza orders. Once an order is placed, it'll hit the kitchen, and the chef will start cooking.

Let's create a basic implementation for the purpose of testing Spring Cloud Gateway with the Discovery Service. This service is a Spring Boot web application with a REST controller that simply acknowledges an order.

Java
 
@RestController
@RequestMapping("/kitchen")
public class KitchenController {
  
    @PostMapping("/order")
    public ResponseEntity<String> addNewOrder(@RequestParam("id") int id) {
        return ResponseEntity.ok("The order has been placed!");
    }
}


The service will be listening on port 8081, which is set in the application.properties file:

Properties files
 
server.port=8081


Once the microservice is started you can use curl or HTTPie to test that the REST endpoint works. We’ll be using HTTPie throughout the article:

Shell
 
http POST localhost:8081/kitchen/order id==1

HTTP/1.1 200 
Connection: keep-alive
Content-Length: 26
Content-Type: text/plain;charset=UTF-8
Date: Thu, 03 Aug 2023 18:45:26 GMT
Keep-Alive: timeout=60

The order has been placed!


Tracker Microservice

Customers use the second microservice, the Tracker, to check their order status.

We'll go the extra mile with this service implementation by supporting several order statuses, including ordered, baking, and delivering. Our mock implementation will randomly select one of these statuses:

Java
 
@RestController
@RequestMapping("/tracker")
public class TrackerController {
    @GetMapping("/status")
    public ResponseEntity<String> getOrderStatus(@RequestParam("id") int orderId) {
        String[] status = { "Ordered", "Baking", "Delivering" };
        Random rand = new Random();

        return ResponseEntity.ok(status[rand.nextInt(status.length)]);
    }
}


The Tracker will be listening on port 8082, which is configured in the application.properties file:

Properties files
 
server.port=8082


Once the microservice is started, we can test it by sending the following GET request:

Shell
 
http GET localhost:8082/tracker/status id==1

HTTP/1.1 200 
Connection: keep-alive
Content-Length: 10
Content-Type: text/plain;charset=UTF-8
Date: Thu, 03 Aug 2023 18:52:45 GMT
Keep-Alive: timeout=60

Delivering


Registering Microservices With Spring Cloud Discovery Service

Our next step is to register these two microservices with the Spring Cloud Discovery Service. But what exactly is a Discovery Service?

Discovery Service

The Discovery Service lets your microservices connect to each other using only their names. For instance, if Tracker needs to connect to Kitchen, the Discovery Service gives Tracker the IP addresses of Kitchen's available instances. This list can change - you can add or remove Kitchen instances as needed, and the Discovery Service always keeps the updated list of active endpoints.

There are several ways to start a Discovery Service server instance. One of the options is to use the Spring Initializr website to generate a Spring Boot project with the Eureka Server dependency.
Spring Initializr: Generate a project

If you choose that method, the generated project will come with the following class that initiates a server instance of the Discovery Service:

Java
 
@SpringBootApplication
@EnableEurekaServer
public class DiscoveryServerApplication {

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


By default, the server listens on port 8761. So, once we start the server, we can visit localhost:8761 to view the Discovery Service dashboard:

Spring Eureka: Service Discovery Dashboard

Currently, the Discovery Service is running, but no microservices are registered with it yet. Now, it's time to register our Kitchen and Tracker microservices.

Update the Kitchen Microservice

To register the Kitchen service with the Discovery Service, we need to make the following changes:

1. Add the Discovery Service’s client library to the Kitchen’s pom.xml file:

XML
 
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>


2. Annotate the Kitchen’s application class with @EnableDiscoveryClient: 

Java
 
@SpringBootApplication
@EnableDiscoveryClient
public class KitchenApplication {
    public static void main(String[] args) {
        SpringApplication.run(KitchenApplication.class, args);
    }
}


3. Update the application.properties file by adding these two parameters:

Properties files
 
# The microservice will be registered under this name 
# with the Discovery Service
spring.application.name=kitchen-service

# Discovery Service address
eureka.client.service-url.defaultZone=http://localhost:8761/eureka


Update the Tracker Microservice

We need to follow the same steps to update the Tracker microservice. 

There's only one difference for Tracker: its name, which is provided via the spring.application.name property in the application.properties file:

Properties files
 
# The microservice will be registered under this name with the Discovery Service
spring.application.name=tracker-service


Register Microservices

Finally, restart the microservices to confirm their registration with the Discovery Service.

Restart the microservices to confirm their registration with the Discovery Service

As expected, both the Kitchen and Tracker microservices successfully register with the Discovery Service! Now, it's time to focus on the Spring Cloud Gateway.

Spring Cloud Gateway

Spring Cloud Gateway is used to resolve user requests and forward them to the appropriate microservices or API endpoints for further processing.

You can generate a Spring Boot project with Cloud Gateway support using the same Spring Initializr website. Simply add the Gateway and Eureka Discovery Client libraries, then click the generate button:

Add the Gateway and Eureka Discovery Client libraries, then click the generate button

The Gateway will serve as a one-stop solution for directing requests to Kitchen and Tracker instances. Its implementation is simple yet powerful:

Java
 
@SpringBootApplication
@EnableDiscoveryClient
public class ApiGatewayApplication {

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

    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        return builder.routes()
        	.route("kitchen-route", r -> r.path("/kitchen/**").uri("lb://kitchen-service"))
         	.route("tracker-route", r -> r.path("/tracker/**").uri("lb://tracker-service"))
         	.build();
    }
}


The Gateway supports two routes:

  1. The kitchen-route is for all requests beginning with the /kitchen/** path.
  2. The tracker-route is for requests starting with the /tracker/** path.

The most interesting part of this route configuration is how we define the destination endpoint (the uri(...) part of the configuration). Each destination starts with lb:, followed by a microservice name. When the Gateway encounters such a destination URL, it will use the Discovery Service to resolve a microservice name into an IP address of a microservice instance and establish a connection to it. Furthermore, lb stands for load balancer, which means the Gateway will distribute requests evenly if the Discovery Service returns several instances of the same microservice.

Finally, once we initiate the Gateway, it begins to monitor port 8080 for incoming traffic. We can then use the following HTTP requests to confirm that the Gateway is successfully routing our requests to the Kitchen and Tracker microservices!

Shell
 
http POST localhost:8080/kitchen/order id==2

HTTP/1.1 200 OK
Content-Length: 26
Content-Type: text/plain;charset=UTF-8
Date: Thu, 03 Aug 2023 20:11:26 GMT

The order has been placed!


http GET localhost:8080/tracker/status id==2

HTTP/1.1 200 OK
Content-Length: 6
Content-Type: text/plain;charset=UTF-8
Date: Thu, 03 Aug 2023 20:11:41 GMT

Baking


Summary

With Spring Cloud, building robust, scalable Java applications for the cloud has never been easier. Say goodbye to the hassles of tracking IP addresses and instances, and say hello to intelligent, effortless request routing. Enjoy!

Spring Cloud Java (programming language) microservice Spring Boot Service discovery

Opinions expressed by DZone contributors are their own.

Related

  • Distributed Tracing System (Spring Cloud Sleuth + OpenZipkin)
  • Full-Duplex Scalable Client-Server Communication with WebSockets and Spring Boot (Part I)
  • NGINX With Eureka Instead of Spring Cloud Gateway or Zuul
  • Implementation Best Practices: Microservice API With Spring Boot

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!