tags: [spring cloud, zuul] projects: [spring-cloud, spring-cloud-netflix] --- :spring_version: current :spring_boot_version: 2.3.2.RELEASE :DataSource: :toc: :icons: font :source-highlighter: prettify :project_id: gs-routing-and-filtering
This guide walks you through the process of routing and filtering requests to a microservice application by using the Netflix Zuul edge service library.
You will write a simple microservice application and then build a reverse proxy application that uses Netflix Zuul to forward requests to the service application. You will also see how to use Zuul to filter requests that are made through the proxy service.
For all Spring applications, you should start with the Spring Initializr. The Initializr offers a fast way to pull in all the dependencies you need for an application and does a lot of the set up for you.
This guide needs two applications. The first application (the book application) needs only the Spring Web dependency.
The second application (the routing and filtering application) needs the Spring Web and Zuul dependencies.
Note
|
For convenience, we have provided build files (a pom.xml file and a build.gradle
file) at the top of the project (one directory above the book and gateway directories)
that you can use to build both projects at once. We also added the Maven and Gradle
wrappers there.
|
To initialize the project, create two applications:
-
Navigate to https://start.spring.io. This service pulls in all the dependencies you need for an application and does most of the setup for you.
-
Choose either Gradle or Maven and the language you want to use. This guide assumes that you chose Java.
-
Click Dependencies and select Spring Web for the book application and Spring Web and Zuul for the routing and filtering application.
-
Click Generate.
-
Download the resulting ZIP file, which is an archive of a web application that is configured with your choices.
Note
|
If your IDE has the Spring Initializr integration, you can complete this process from your IDE. |
Note
|
You can also fork the project from Github and open it in your IDE or other editor. |
The Book service will be as simple as a Spring application can be. Edit
RoutingAndFilteringBookApplicationBookApplication.java
so that it matches the following
listing (from
book/src/main/java/com/example/routingandfilteringbook/RoutingAndFilteringBookApplication.java
):
link:complete/book/src/main/java/com/example/routingandfilteringbook/RoutingAndFilteringBookApplication.java[role=include]
The RoutingAndFilteringBookApplicationBookApplication
class is now a REST controller.
The @RestController
annotation marks the class as a controller class and ensures that
return values from @RequestMapping
methods in this class are automatically and
appropriately converted and written directly to the HTTP response.
Speaking of @RequestMapping
methods, we have added two: available()
and
checkedOut()
. They handle requests to the /available
and /checked-out
paths, each of
which returns the String
name of a book.
Set the application name (book
) in src/main/resources/application.properties
, as the
following listing shows:
link:complete/book/src/main/resources/application.properties[role=include]
Set server.port
here, too, so that it does not conflict with your edge service when you
get both services up and running locally.
Spring Cloud Netflix includes an embedded Zuul proxy, which you can enable with the
@EnableZuulProxy
annotation. This will turn the Gateway application into a reverse proxy
that forwards relevant calls to other services — such as our book application.
Open the Gateway application’s RoutingAndFilteringGatewayApplicationGatewayApplication
class and add the @EnableZuulProxy
annotation, as the following listing (from
gateway/src/main/java/com/example/routingandfilteringgateway/RoutingAndFilteringGatewayApplication.java
)
shows:
link:complete/gateway/src/main/java/com/example/routingandfilteringgateway/RoutingAndFilteringGatewayApplication.java[role=include]
To forward requests from the Gateway application, you need to tell Zuul the routes that it
should watch and the services to which to forward requests that are made to those routes.
We specify routes by setting properties under zuul.routes
. Each of our microservices can
have an entry under zuul.routes.NAME
, where NAME
is the application name (as stored in
the spring.application.name
property).
Add the application.properties
file to a new directory (src/main/resources
) in the
Gateway application. It should match the following listing (from
gateway/src/main/resources/application.properties
):
link:complete/gateway/src/main/resources/application.properties[role=include]
Spring Cloud Zuul automatically sets the path to the application name. In this sample, set
zuul.routes.books.url
so that Zuul will proxy requests to /books
to this URL.
Notice the second property in the application.properties
file, Spring Cloud Netflix Zuul
uses Netflix’s Ribbon to perform client-side load balancing. By default, Ribbon would use
Netflix Eureka for service discovery. For this simple example, you can skip service
discovery, so set ribbon.eureka.enabled
to false
. Since Ribbon now cannot use Eureka
to look up services, we must specify a url
for the book service.
Now you can see how to filter requests through your proxy service. Zuul has four standard filter types:
-
pre
filters run before the request is routed. -
route
filters can handle the actual routing of the request. -
post
filters run after the request has been routed. -
error
filters run if an error occurs in the course of handling the request.
You are going to write a pre
filter. Spring Cloud Netflix picks up, as a filter, any
@Bean
that extends com.netflix.zuul.ZuulFilter
and is available in the application
context. The following listing (from
gateway/src/main/java/com/example/routingandfilteringgateway/filters/pre/SimpleFilter.java
)
shows the filter you need:
link:complete/gateway/src/main/java/com/example/routingandfilteringgateway/filters/pre/SimpleFilter.java[role=include]
Filter classes implement four methods:
-
filterType()
: Returns aString
that stands for the type of the filter — in this case,pre
. (It would beroute
for a routing filter.) -
filterOrder()
: Gives the order in which this filter is to be run, relative to other filters. -
shouldFilter()
: Contains the logic that determines when to run this filter (this particular filter is always run). -
run()
: Contains the functionality of the filter.
Zuul filters store request and state information in (and share it by means of) the
RequestContext
. You can use that to get at the HttpServletRequest
and then log the
HTTP method and URL of the request before it is sent on its way.
The GatewayApplication
class is annotated with @SpringBootApplication
, which includes
(among others) the @Configuration
annotation that tells Spring to look in a given class
for @Bean
definitions. Put the filter in the application class, as shown in the
following listing (from
gateway/src/main/java/com/example/routingandfilteringgateway/RoutingAndFilteringGatewayApplication.java
):
link:complete/gateway/src/main/java/com/example/routingandfilteringgateway/RoutingAndFilteringGatewayApplication.java[role=include]
Make sure that both applications are running. In a browser, visit one of the book
application’s endpoints through the Gateway application. If you have used the
configuration shown in this guide, you can access the book application directly at
localhost:8090/available
and through the Gateway service at
localhost:8080/books/available
.
Visit one of the Book service endpoints (localhost:8080/books/available
or
localhost:8080/books/checked-out
) and you should see your request’s method logged by the
Gateway application before it is handed on to the Book application, as the following
sample logging output shows:
2019-10-02 10:58:34.694 INFO 11608 --- [nio-8080-exec-4] c.e.r.filters.pre.SimpleFilter : GET request to http://localhost:8080/books/available
Congratulations! You have used Spring to develop an edge service application that can proxy and filter requests for your microservices.
The following guides may also be helpful: