What is an API Gateway?
API Gateway is an application, that acts as a single point of entry for a collection of microservices.
Any external client (desktop or mobile applications) cannot access the microservices directly but can access them through the API Gateway application.
Here is a list of advantages of having an API Gateway.
- Limits microservices access to external clients, thereby improving security.
- Clients don't know the actual server IP addresses and internal architecture of the microservices, as they are hidden behind the API Gateway.
- Simplifies client interaction as they simply need to access the API Gateway endpoint to access all the microservices.
- Easy to implement cross-cutting concerns like authentication, monitoring/metrics, and resiliency on API Gateway, as all the microservices are accessed through the Gateway application.
Why do we need API Gateway?
Let's assume we have multiple microservices that are available on different servers/ports as mentioned below.
If we don't have API Gateway, we need to enable the applications and their ports for public access, so that they are exposed for external clients' access.
If we have an API Gateway, we can simply enable the Gateway application and its port for public access, keeping all the other applications and their ports private, which makes the applications more secure. Once the Gateway is configured to route the incoming traffic to the respective applications, all the requests have to pass through the API Gateway and the URL looks like the ones mentioned below.
Service | Access URL Without Gateway | Access URL With Gateway |
API Gateway | http://localhost:8080 | http://localhost:8080 |
Employee | http://localhost:8081/employee/** | http://localhost:8080/employee/** |
Customer | http://localhost:8082/customer/** | http://localhost:8080/customer/** |
Category | http://localhost:8083/category/** | http://localhost:8080/category/** |
Implementing Services
Define the controllers on Employee service with @RequestMapping("/employee")
as shown below.
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@GetMapping("/hello")
public String hello() {
return "Hello from Employee service";
}
}
Define the controller on Customer service with @RequestMapping("/customer")
as shown below.
@RestController
@RequestMapping("/customer")
public class CustomerController {
@GetMapping("/hello")
public String hello() {
return "Hello from Customer service";
}
}
Define the controller on Category service with @RequestMapping("/category")
as shown below.
@RestController
@RequestMapping("/category")
public class CategoryController {
@GetMapping("/hello")
public String hello() {
return "Hello from Category service";
}
}
Implementing Spring Boot API Gateway
For a Spring Boot Maven project, add the below dependencies in the pom.xml
file to make the application an API Gateway.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
We don't need any changes to the application code.
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
However, we need to add the application routing within the application.properties or application.yml file as mentioned below.
server:
port: 8080
spring:
application:
name: api-gateway
cloud:
gateway:
default-filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "*"
allowedMethods: "*"
allowedHeaders: "*"
routes:
- id: employee-app
uri: http://localhost:8081/
predicates:
- Path=/employee/**
- id: customer-app
uri: http://localhost:8082/
predicates:
- Path=/customer/**
- id: category-app
uri: http://localhost:8083/
predicates:
- Path=/category/**
In the above application.yml file, the below properties to address the CORS issue are also added.
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "*"
allowedMethods: "*"
allowedHeaders: "*"
Run & Test API Gateway Application
After making the above changes, run the application on your IDE (Eclipse or STS), which runs the application on an embedded Netty server by default.
Then, test the below endpoints should work as expected and should route to the appropriate service defined on API Gateway.
Service URL Using API Gateway | Response |
http://localhost:8080/employee/hello | Hello from Employee service |
http://localhost:8080/customer/hello | Hello from Customer service |
http://localhost:8080/category/hello | Hello from Category service |
Running API Gateway as a Standalone Application
By default, the Spring Boot API Gateway runs on an embedded Netty Web Server, and if we need to run this on an external Tomcat server, we need to follow the below instructions.
Add the below dependency in the pom.xml file.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
Then, extend the main application class with SpringBootServletInitializer
and override the method configure()
as shown below, which makes the application a simple servlet application deployable on an external tomcat server.
@CrossOrigin("*")
@SpringBootApplication
public class GatewayApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(GatewayApplication.class);
}
}
Then, run the application.
Then, test the below endpoints should work as expected and should route to the appropriate service defined on API Gateway.
Service URL Using API Gateway | Response |
http://localhost:8080/employee/hello | Hello from Employee service |
http://localhost:8080/customer/hello | Hello from Customer service |
http://localhost:8080/category/hello | Hello from Category service |
References
Conclusion
Now, we know how to build a Spring Boot API Gateway application.