architecture Best Practices How-tos prac_eng products Spring spring cloud

Getting Started with Spring Cloud Gateway

This post was written in collaboration with Brian McClain

Microservice architectures are great, but as your application programming interfaces (APIs) start to grow, so do the challenges related to their maintenance.

For example, as an existing API matures and adds new features it will need to take its clients along with it on the journey. When the details of an API change, clients need to adjust in order to work with these changes. This process takes time and can really slow your APIs evolution and interfere with your ability to iterate quickly. Offering multiple APIs can help but brings with it its own set of challenges. How do you route requests and responses to the correct API? How do you manage any message disparity? How do you support clients when your endpoints can move around?

And then there’s the question of integrating with legacy systems. Not everyone is so lucky that they get to build apps and services into an entirely new ecosystem, instead needing to play nicely with preexisting systems for things like authentication and other backing services.

An API Gateway helps you to solve these problems and more. It is a powerful architectural tool which you can use to manage message routing, filtering and proxying in your microservice architecture. Many API Gateways can be dated back to SOA and these tend to have been implemented as centralized servers. But as microservices became more popular, modern lightweight independent and decentralized micro-gateway applications have appeared – such as Spring Cloud Gateway.  

In this first article in our series on Spring Cloud Gateway, we’ll start by doing something very simple – reroute requests coming into one URL and forward them to another. We’ll also insert a simple HTTP Header to the request just to show one more example of what’s possible.

Tools

  • Httpie

  • Your favorite Java IDE (check out Spring Tools if you don’t have one)

  • Your favorite command line (e.g zsh, bash, DOS command or PowerShell)

  • Httpbin.org – a website and diagnosis tool which converts Http GET request data into a JSON response

Step 1: Create a Project

In a new folder, we’ll use start.spring.io (and httpie) to create, download and extract a new Spring Boot project containing Spring Cloud Gateway in one smooth motion…

http https://start.spring.io/starter.zip dependencies==cloud-gateway,actuator baseDir==spring-cloud-gateway-demo | tar -xzvf -

We can assert straight away that this project is working by building and running the code and checking the Spring Boot Actuator health endpoint like so…

./mvnw package spring-boot:run

Now that your Spring Boot application is running, point your browser to http://localhost:8080/actuator/health. You should receive a JSON-formatted message saying “{"status":"UP"}” which indicates that everything is working fine. Now stop your server and continue to Step 2.

Step 2: Add a Re-Route Instruction To The Gateway

In your IDE, open the class `src/main/java/com/example/demo/DemoApplication.java` and add the following method, correcting the import statements as you go. If you get stuck, check out the code sample here.

 

@Bean
   public RouteLocator myRoutes(RouteLocatorBuilder builder) {
       return builder.routes()
                // Add a simple re-route from: /get to: http://httpbin.org:80
                // A a simple "Hello:World" HTTP Header
                .route(p -> p
                  .path("/get") // intercept calls to the /get path
                  .filters(f -> f.addRequestHeader("Hello", "World")) // add header
                  .uri("http://httpbin.org:80")) // forward to httpbin
                .build();
   }

Here we build a new route for our gateway. Any request to `localhost:8080/get` will be matched to this route instruction and our two changes to the request will be made. The `filters` method handles things such as adding or changing headers, in our case setting the “Hello” header to the value of “World”. Additionally, the “uri” method forwards our request to the new host. It’s important to note that the `/get` path is being retained when forwarding the message.

Recompile your code and start the application server once more, like this…

./mvnw package spring-boot:run

Step 3: Test Your Gateway

To test what you built, you can once again use Httpie. Send a get request to http://localhost:8080/get and observe what comes back.

http localhost:8080/get --print=HhBb

You should get a response very much like the one shown below.

GET /get HTTP/1.1

Accept: */*

Accept-Encoding: gzip, deflate

Connection: keep-alive

Host: localhost:8080

User-Agent: HTTPie/1.0.2
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Content-Encoding: gzip
Content-Length: 256
Content-Type: application/json
Date: Mon, 10 Jun 2019 13:13:36 GMT
Referrer-Policy: no-referrer-when-downgrade
Server: nginx
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block

{
   "args": {},
   "headers": {
       "Accept": "*/*",
       "Accept-Encoding": "gzip, deflate",
       "Forwarded": "proto=http;host="localhost:8080";for="0:0:0:0:0:0:0:1:52144"",
       "Hello": "World",
       "Host": "httpbin.org",
       "User-Agent": "HTTPie/1.0.2",
       "X-Forwarded-Host": "localhost:8080"
   },
   "origin": "0:0:0:0:0:0:0:1, 2.102.147.153, ::1",
   "url": "https://localhost:8080/get"
}

There are a few things here of note:

  • The response originates from httpbin.org as evidenced by the `Host` header.

  • The `X-Forwarded-Host` is `localhost:8080` (our locally running Gateway application)

  • The Http header `Hello` has been inserted and given a value of `World`.

  • The full "url" of the original request is "https://localhost:8080/get".

Final Thoughts

That’s it. You now should have a Spring Cloud Gateway application up and running and have learned how to forward basic requests to another endpoint. You could use this technique to automatically forward requests from your Gateway application to another service.

The code to accompany this article can be found here. The full documentation for the current GA release of Spring Cloud Gateway (2.1.0 at the time of writing) can be found here.

Next Time

We’ve only dipped our toes into what Spring Cloud Gateway can do, but hopefully, this was a good first look. In our next post, we’ll take a look at how to create a dynamic gateway – one that can discover the location of services at runtime. If you’d like to learn more in the meantime, be sure to check out the Spring Cloud Gateway page on spring.io, the official Spring guide, or set up your own service and gateway on Pivotal Web Services!

Finally, be sure to check out SpringOne Platform, the premier conference for building scalable applications that people love. Join your peers to learn, share, and have fun in Austin, TX from October 7th to 10th for the biggest and best show yet. Even better, use code S1P_Save200 when registering to save on your ticket. We hope to see you there!