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

  • Keep Your Application Secrets Secret
  • Build a Java Backend That Connects With Salesforce
  • How To Validate Names Using Java
  • How To Check for JSON Insecure Deserialization (JID) Attacks With Java

Trending

  • Why High-Performance AI/ML Is Essential in Modern Cybersecurity
  • Understanding and Mitigating IP Spoofing Attacks
  • Enhancing Security With ZTNA in Hybrid and Multi-Cloud Deployments
  • The Role of Functional Programming in Modern Software Development
  1. DZone
  2. Data Engineering
  3. Databases
  4. Create an API Gateway with Load Balancer Using Java

Create an API Gateway with Load Balancer Using Java

Nowadays every application is moving to microservice architecture. In this architecture, API Gateway has an important role. Let's build a simple API gateway using Java.

By 
Vishnu Viswambharan user avatar
Vishnu Viswambharan
·
Updated Sep. 10, 20 · Tutorial
Likes (10)
Comment
Save
Tweet
Share
28.9K Views

Join the DZone community and get the full member experience.

Join For Free

Used Libraries

  1.   Netflix Eureka naming server 
  2.   Netflix Zuul
  3.   Ribbon
  4.   Feign

Network Architecture of the system

This Architecture Contains Four Applications

  1. Load balancing application [netflix-eureka-naming-server]
  2. API gateway application [api-gateway-server]
  3. Server application [micro-service-server]
  4. Client application [micro-service-client]

Steps To Run The Applications

  1. Install JDK 11 or latest. 
  2. Clone git repository of the project into local.
  3. Github: https://github.com/VishnuViswam/LOAD-BALANCER-WITH-API-GATEWAY.git
  4. Run Load balancing application first. 
  5. Run The API gateway application.
  6. Then run Server application in two ports. 
  7. At last run Client application.

1) Load Balancing Application

All client server communication will be done through this load balancing server application. 

pom.xml

We are using netflix-eureka-server library to enable the communication between client and server. 

XML
 




xxxxxxxxxx
1
29


 
1
<properties>
2
    <java.version>11</java.version>
3
    <spring-cloud.version>Hoxton.SR4</spring-cloud.version>
4
</properties>
5

          
6
<dependencies>
7
  <dependency>
8
    <groupId>org.springframework.cloud</groupId>
9
    <artifactId>spring-cloud-starter-config</artifactId>
10
  </dependency>
11
  <dependency>
12
    <groupId>org.springframework.cloud</groupId>
13
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
14
  </dependency>
15
</dependencies>



application.properties

Properties files
 




xxxxxxxxxx
1


 
1
spring.application.name=netflix-eureka-naming-server // application unique name
2
server.port=8761 // It will be the default port which eureka naming server
3
eureka.client.register-with-eureka=false
4
eureka.client.fetch-registry=false



NetflixEurekaNamingServerApplication.java

@EnableEurekaServer  named annotation will allow the eureka server to control this application.

Java
 




xxxxxxxxxx
1
11
9


 
1
@SpringBootApplication
2
@EnableEurekaServer // to enable the communication with Eureka server
3
public class NetflixEurekaNamingServerApplication {
4

          
5
    public static void main(String[] args) {
6
        SpringApplication.run(NetflixEurekaNamingServerApplication.class, args);
7
    }
8
}


After running this application we can access the eureka server dashboard under following URL.

Link: http://localhost:8761

Eureka Server Dashboard

Eureka dashboard


2) API Gateway Application

This application will act as a middleware in between Server Application and Client Application. 

All requests going to the Server application will be filtered here.

We are using spring-cloud-starter-netflix-zuul library to enable this filtering process.

netflix-eureka-client is the library which used to register the application with Eureka naming server.

Zuul Dependency

XML
 




xxxxxxxxxx
1


 
1
<dependency>
2
    <groupId>org.springframework.cloud</groupId>
3
    <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
4
</dependency>


pom.xml

XML
 




xxxxxxxxxx
1
18


 
1
<properties>
2
    <java.version>11</java.version>
3
    <spring-cloud.version>Hoxton.SR6</spring-cloud.version>
4
</properties>
5
<dependencies>
6
    <dependency>
7
        <groupId>org.springframework.boot</groupId>
8
        <artifactId>spring-boot-starter-web</artifactId>
9
    </dependency>
10
    <dependency>
11
        <groupId>org.springframework.cloud</groupId>
12
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
13
    </dependency>
14
    <dependency>
15
        <groupId>org.springframework.cloud</groupId>
16
        <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
17
    </dependency>
18
</dependencies>


application.properties

Properties files
 




xxxxxxxxxx
1


 
1
spring.application.name=api-gateway-server // application unique name
2
server.port=8765 // application will be running under this port
3
eureka.client.service-url.default-zone=http://localhost:8761/eureka // end point of load balancing server


ApiGatewayApplication.java

@EnableDiscoveryClient named annotation used to register the application with Eureka server in the main class. 

@EnableZuulProxy named annotation used to connect the Zuul library.

Java
 




xxxxxxxxxx
1


 
1
@SpringBootApplication
2
@EnableZuulProxy
3
@EnableDiscoveryClient
4
public class ApiGatewayApplication {
5
    public static void main(String[] args) {
6
        SpringApplication.run(ApiGatewayApplication.class, args);
7
    }
8
}


ZuulLoginFilter.java

  • It is the class where all the APIs getting flittered.
  • We extended one class named by "ZuulFilter".
  • Four methods will be override from this class.

filterType(): 

  •   The interruption time of a request will be decided in this method.
  •   pre key is used to filter before reaching the Server application .
  •   post key is used to filter when response came back from the Server application.
  •   error key is used to filter any error happened.

filterOrder():

  •   To set the priority of the filter process.

shouldFilter(): 

  • To decide whether the request is filter or not.

run():

  • This method will trigger after filtering process. So that we can write the business logic what ever we required.
Java
 




xxxxxxxxxx
1
31


 
1
@RestController
2
@RequestMapping("/client")
3
public class ZuulLoginFilter extends ZuulFilter  {
4

          
5
  @Override
6
    public String filterType() {
7
        return "pre"; // filter before request is executed
8
        // return "post"; filter after request is executed
9
        //return "error"; upon request error
10
    }
11

          
12
    @Override
13
    public int filterOrder() {
14
        return 1;
15
    }
16

          
17
    @Override
18
    public boolean shouldFilter() {
19
        return true;
20
    }
21

          
22
    @Override
23
    public Object run() throws ZuulException {
24
      logger.info("Request is filtered");
25
        HttpServletRequest httpServletRequest =                    RequestContext.getCurrentContext().getRequest();
26

          
27
        logger.info("request -> {} request uri -> {} ",
28
                httpServletRequest, httpServletRequest.getRequestURI());
29
        return null;
30
    }
31
}


After running this application, the instance of this application will be appear in the Eureka server dashboard. 

3) Server Application

In order to perform load distribution this application need to run in two instances. 

spring-cloud-starter-netflix-eureka-client  library used to enable communication with Eureka naming server

XML
 




xxxxxxxxxx
1


 
1
<dependency>
2
  <groupId>org.springframework.cloud</groupId>
3
  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
4
</dependency>


pom.xml

XML
 




xxxxxxxxxx
1
16


 
1
<properties>
2
  <java.version>11</java.version>
3
  <spring-cloud.version>Hoxton.SR4</spring-cloud.version>
4
</properties>
5

          
6
<dependencies>
7
    <dependency>
8
        <groupId>org.springframework.cloud</groupId>
9
        <artifactId>spring-cloud-starter-config</artifactId>
10
    </dependency>
11
    <dependency>
12
        <groupId>org.springframework.cloud</groupId>
13
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
14
    </dependency>
15
</dependencies>


application.properties

Properties files
 




xxxxxxxxxx
1


 
1
spring.application.name=micro-service-server // application unique name
2
server.port=4000 // application will be running under this port
3

          
4
eureka.client.service-url.default-zone=http://localhost:8761/eureka // end point of load balancing server


MicroServiceServerApplication.java

@EnableDiscoveryClient named annotation to register the application with eureka server. 

Java
 




xxxxxxxxxx
1


 
1
@SpringBootApplication
2
@EnableDiscoveryClient
3
public class MicroServiceServerApplication {
4

          
5
    public static void main(String[] args) {
6
        SpringApplication.run(MicroServiceServerApplication.class, args);
7
    }
8
}


  • Run Server application instance in two ports
  • First simply run the application as java application using main method. 

To run one more instance in another port we need to edit the <b>Run/Debug Configurations</b> In the IDE. 

In IntelliJ:

Click on the Edit Configuration option, it will be available on the right top side of the menu bar.

Edit configuration


It will open a window as follows. Then enable Allow parallel run and press apply.


Enable parallel run

  Now change the port in the property file as 4001. Then run once again. 

In Eclipse:

Right-click on the main class -> click properties -> select main class -> click new button and add -Dserver. port=4001 in the Vm Arguments as shown in the following images.

Run/debug settings

VM arguments

  

Then select the new configuration and run. Now these two instances of server will be appear in the eureka server dashboard. 

4) Client Application

  • This application will perform as consumer of APIs which is written in the main server. 
  • It consumes the APIs from the both main server instance based on availability through load balancer. 
  • We also use netflix-eureka-client library to communicate with load balancer application. 

OpenFeign

  •  We are using OpenFeign to consume APIs rather than using traditional HTTP libraries. 
  •  OpenFeign will act as a proxy in between server and client.
XML
 




xxxxxxxxxx
1


 
1
<dependency>
2
  <groupId>org.springframework.cloud</groupId>
3
  <artifactId>spring-cloud-starter-openfeign</artifactId>
4
</dependency>


Eureka Client & Ribbon

  • Ribbon will do the automatic switching of servers in the client-side
  • Eureka will help us to dynamically add main server instances to the load balancer according to traffic.
XML
 




xxxxxxxxxx
1


 
1
<dependency>
2
  <groupId>org.springframework.cloud</groupId>
3
  <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
4
</dependency>
5
<dependency>
6
  <groupId>org.springframework.cloud</groupId>
7
  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
8
</dependency>


pom.xml

XML
 




xxxxxxxxxx
1
25


 
1
<properties>
2
  <java.version>11</java.version>
3
  <spring-cloud.version>Hoxton.SR4</spring-cloud.version>
4
</properties>
5

          
6
<dependencies>
7
    <dependency>
8
        <groupId>org.springframework.cloud</groupId>
9
        <artifactId>spring-cloud-starter-config</artifactId>
10
    </dependency>
11
    <dependency>
12
        <groupId>org.springframework.cloud</groupId>
13
        <artifactId>spring-cloud-starter-openfeign</artifactId>
14
    </dependency>
15
    <dependency>
16
        <groupId>org.springframework.cloud</groupId>
17
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
18
    </dependency>
19
    <dependency>
20
        <groupId>org.springframework.cloud</groupId>
21
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
22
    </dependency>
23
</dependencies>


application.properties

Properties files
 




xxxxxxxxxx
1


 
1
server.servlet.contextPath=/microservice
2
spring.application.name=micro-service-client // application unique name
3
server.port=5000 // application will be running under this port
4

          
5
eureka.client.service-url.default-zone=http://localhost:8761/eureka // end point of load balancing server


MicroServiceClientApplication.java

  • @EnableDiscoveryClient named annotation used to register the application with eureka server in the main class. 
  • @EnableFeignClients named annotation used to connect the feign library.
Java
 




xxxxxxxxxx
1
10


 
1
@SpringBootApplication
2
@EnableFeignClients("com.microservices.client")
3
@EnableDiscoveryClient
4
public class MicroServiceClientApplication {
5

          
6
    public static void main(String[] args) {
7
        SpringApplication.run(MicroServiceClientApplication.class, args);
8
    }
9

          
10
}


ClientController.java

  • It is an ordinary REST controller class
Java
 




xxxxxxxxxx
1
14


 
1
@RestController
2
@RequestMapping("/client")
3
public class ClientController {
4

          
5
    @Autowired
6
    private ApiProxy apiProxy;
7

          
8
    @GetMapping("/technologyInfo/{platform}")
9
    public ResponseModel getTechnologyInfo(@PathVariable("platform") String platform) {
10
            // API calling using proxy interface and mapping into ResponseModel named Object.
11
            ResponseModel responseModel = apiProxy.retrieveTechnologyInfo(platform);
12
            return responseModel;
13
        }
14
}


ApiProxy.java

  • Act as proxy class in between API and client. 
  • @FeignClient(name = "api-gateway-server") annotation will enable the communication from the Client application to API gateway application. 
  • @RibbonClient(name = "micro-service-server") annotation will tell the API gateway application to where the request has to go.
  •  micro-service-server should be the name of Server application.
Java
 




xxxxxxxxxx
1


 
1
@FeignClient(name = "api-gateway-server")
2
@RibbonClient(name = "micro-service-server")
3
public interface ApiProxy {
4

          
5
    @GetMapping("micro-service-server/server/technologyInfo/{platform}")
6
    ResponseModel retrieveTechnologyInfo(@PathVariable("platform") String platform);
7
}


ResponseModel.java

  • It is a traditional model class.
Java
 




xxxxxxxxxx
1
15


 
1
public class ResponseModel {
2

          
3
    private String tittle;
4

          
5
    private String platform;
6

          
7
    private String usedFor;
8

          
9
    private Short serverPort;
10

          
11
    --------
12

          
13
    ---
14

          
15
}



After running the client application, an instance of this application also appears in the Eureka server dashboard. 

Result

Now we can see four application instances are running in Eureka server dashboard.

Call client application API. 

URI: http://localhost:5000/microservice/client/technologyInfo/java

Response:

JSON
 




xxxxxxxxxx
1


 
1
{"tittle":"Technology Stack","platform":"Java","usedFor":"Secured Web Services","serverPort":4000}



Do Refresh:

JSON
 




xxxxxxxxxx
1


 
1
{"tittle":"Technology Stack","platform":"Java","usedFor":"Secured Web Services","serverPort":4001}



  • From the result we can understand that the API response is receiving from different servers by identifying port change. That means the requests are distributing in between two Server applications.
  • And in the console of API gateway application we can see the message Request is filtered. That means API request also has been filtered by our application.
API application Load balancing (computing) Java (programming language)

Opinions expressed by DZone contributors are their own.

Related

  • Keep Your Application Secrets Secret
  • Build a Java Backend That Connects With Salesforce
  • How To Validate Names Using Java
  • How To Check for JSON Insecure Deserialization (JID) Attacks With Java

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!