In this tutorial, we will be discussing about how to route in cloud native apps to different services using spring netflix zuul proxy.We will have multiple micro services running and an API gateway that does intelligent routing through proxy based on the requested resource. We will be also discussing about setting up Zuul Filter to intercept all the request and perform some operations to all the requests that pass through the API gateway.
API Gateway means a single entry point for all clients.So, we have a single interface exposed on behalf of all the microservices running. This gateway at the run-time will identify the correct service to be invoked. To achieve this routing we have Netflix zuul proxy. Zuul is an edge service that provides dynamic routing, monitoring, resiliency, security, and more.
In this example, we will be creating two different services as first-service and second-service first and enable discovery server to auto discover these services. Till this point we have already discussed in my last article - Spring cloud netflix eureka.On top of this, we will be creating an API gateway using netflix zuul for intelligent routing.
Netflix Discovery Server
We will be using our existing discovery server implementation on github. Following is the application.properties
file and DiscoveryServerApplication.java
that we used while implementing discovery server in our last example.
spring.application.name=discovery-server eureka.client.register-with-eureka=false eureka.client.fetch-registry=false server.port=8761DiscoveryServerApplication.java
@EnableEurekaServer @SpringBootApplication public class DiscoveryServerApplication { public static void main(String[] args) { SpringApplication.run(DiscoveryServerApplication.class, args); } }
API Gateway Service
By default, zuul routes request by service name which is resolved by discovery server.For example, if the request url is like /first-service/first then zuul discovers service with name first-service and routes the request to it for url mapping first. So, basically zuul strips the prefix and route it to the corresponding service.
Spring Cloud Netflix includes an embedded Zuul proxy, which we can enable with the @EnableZuulProxy
annotation in our main application class. Since, we want our service to be auto discoverable, we also have annotated it with @EnableDiscoveryClient
package com.devglan.gatewayservice; 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; @SpringBootApplication @EnableZuulProxy @EnableDiscoveryClient public class GatewayServiceApplication { public static void main(String[] args) { SpringApplication.run(GatewayServiceApplication.class, args); } }
For auto discovery, we also require to tell the spring about our eureka discovery server url. Following are the requird entries in application.properties for this.
application.propertiesspring.application.name=gateway-service eureka.client.service-url.default-zone=http://localhost:8761/eureka
This is it for configuring a simple API gateway service. Now, this app will be running on port 8080 and it will intercept all the request and based on the service id, it will discover the dervice from discovery server and route the request to the corresponding service.
Implementing Cloud Service
In this section, we will implementing our micro services. We will have 2 different services with application name as first-service running on 9090 and second-service running on 9095 respectively.Following is the implementation of the respective controller class.
FirstController.java@RestController public class FirstController { @RequestMapping("/") public String demo(){ return "First service "; } }SecondController.java
@RestController public class SecondController { @RequestMapping("/") public String demo(){ return "Second service"; } }
Testing Zuul Proxy
Now, we will test the application. For that first start discovery server then the gateway service and then the two micro service and hit the url http://localhost:8080/first-service. Here, our gateway service is running on port 8080 and first-service is the service name. You can see that the request is proxied to first service by zuul.
Zuul Filter Implementation
Sometimes, it is required to intercept the request and response that is passed through the gateway.Doing so, we can add some validations or modify headers of requet and response. For this, zuul provides filter implementation and this filter implementation provides full control about how how to proceed with the request and response. There are 4 types of filter provided by zuul. We have pre filter that is executed before the request is routed.Similarly, we have route filter to direct the request and post filter that is executed after the the request is routed.We also have error filter that is executed when any error is occurred during routing.
Fllowing is a sample pre filter implementation that modifies the request header and adds X-source
in the header.And the same header can be extracted in the service implementation. This is a very useful feature in a real time app.
package com.devglan.gatewayservice.config; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; public class AddRequestHeaderFilter extends ZuulFilter { @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; } @Override public Object run() throws ZuulException { RequestContext context = RequestContext.getCurrentContext(); context.addZuulRequestHeader("X-source", "Zuul"); return null; } }
Before this filter can be used we need to define it as a bean.
@Bean public AddRequestHeaderFilter addRequestHeaderFilter(){ return new AddRequestHeaderFilter(); }
Now, we can have access to this header in our controller as below:
@RequestMapping("/") public String demo(@RequestHeader("X-source") String source){ return "First service with " + source; }
Conclusion
In this article, we discussed about implementing API gateway using spring cloud netflix zuul proxy for intelligent routing.In next article, we will be discussing about spring cloud netflix hystrix.The source can be downloaded from here.If you have anything that you want to add or share then please share it below in the comment section