Spring-cloud-gateway: Dynamic Request Routing via Spring Cloud Gateway

Created on 18 Oct 2018  路  11Comments  路  Source: spring-cloud/spring-cloud-gateway

I have recently started working on Spring Cloud Gateway. I added the following maven dependency in my project:

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

But I couldn't find what I was expecting to be included in a basic API gateway. I am trying to achieve the followings:

  1. Simple Request Routing
    I want my gateway to to receive a request and execute another url defined in Uri. But, I couldn't find a way to receive GET request in gateway and execute POST request and vice versa. For example, in the example below, how may I execute Uri as POST?
    .route(r ->
                    r.path("/controller/action/{uhbgy}").and().method(HttpMethod.GET)
                      .uri("https://ip:port/group/2/${id}")
               )
  1. Reading request/query parameters from header/body from source request (path) and pass it to the destination request (Uri)?
  2. Changing routing rules at run time without any need to restart the application. Like I could define Uri to run against particular path in some file and may change it at run time.

I think 1st and 2nd point is very basic and should be supported. Can anyone please confirm that either SCG supports these things or not? Or either I missed in the documentation.

@spencergibb Can you please have a look into these points. Thanks

question

Most helpful comment

Just one late comment about dynamically update the routes, you can do it during runtime by using the event publisher ApplicationEventPublisher. After changing your routes all you need is calling the method refreshRoutes() on the following component.

`
@Component
public class GatewayRoutesRefresher implements ApplicationEventPublisherAware {

private ApplicationEventPublisher publisher;

@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
    publisher = applicationEventPublisher;
}

public void refreshRoutes() {
    publisher.publishEvent(new RefreshRoutesEvent(this));
}

}
`

For a more complete reference on dynamically setup and modification of routes take a look on following open source project: https://github.com/botorabi/HomieCenter
In particular this folder should be of your interest: https://github.com/botorabi/HomieCenter/tree/master/src/main/java/net/vrfun/homiecenter/reverseproxy

All 11 comments

  1. I dont believe there is a way to change the method of the proxied request at the moment.
  2. all headers, query params, and the body will be proxies to the source (might be misunderstanding this use case)
  3. If you use the spring cloud config server to serve your route config you can change the routes there and refresh the configuration used by the gateway

Thanks @ryanjbaxter for your replies.

Regarding 2nd point:
You mean all the request parameters / headers etc. are passed automatically to the destination request being mapped. For example in the example below: I want to pass the id got from predicate path to the destination path in _uri_.

uri: https://server:port/group/2/{id}
predicates:
    - Path=/controller/action/{id}

Regarding 3rd point:
How can we refresh configurations? with @RefreshScope? And will it refresh the spring cloud java based configurations as well? For example, in the above code snippet, I want to change the predicate path to the following at run time (which means I will place some configurational property here which will be updated at run time):

predicates:
    - Path=/controller2/action2/{id}

Thanks for your time in making things clear as Its document isn't that good. Stay blessed!

I want to pass the id got from predicate path to the destination path in uri.

Yes that id should be passed

How can we refresh configurations?

If the configuration is in your application configuration it is a just a matter of updating the configuration in the environment repository of the config server. You then tell the application that its application needs to be refreshed and it will fetch the new configuration.
http://cloud.spring.io/spring-cloud-static/Finchley.SR1/single/spring-cloud.html#refresh-scope

will it refresh the spring cloud java based configurations as well

Not unless that configuration is being pulled from application properties. Changing the Java configuration would require rebuilding and redeploying.

The path in the uri does not know about {id}. Please use the SetPath filter.

Hi @spencergibb
I tried setting path but still the parameters from header not being passed:

- id: test
  uri: https://someotherservice/group/2
  predicates:
  - Path=/entity/{id}
  filters:
  - SetPath=/{id}

So, Ideally id sent with path (/entity/5) should be set with the uri (/group/2/5)

@ryanjbaxter
So, after changing yaml file (spring cloud config) one will have to invoke /refresh to reload configurations? If I add a new route will spring cloud gateway pick and execute it with given predicates and filters?

Secondly, regarding JAVA based configurations, what If I use the variables which reads data from config server and use it in spring cloud gateway configurations. Will these configurations get updated when changed in the config server?

@Value("from_conf_file")
String pathUrl;

@Value("from_conf_file")
String serviceUrl;

@Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        return builder.routes()
              .route(r ->
                        r.path(pathUrl).and().method(HttpMethod.GET)
                                .uri(serviceUrl)
                )
                .build();
  }

Thanks,

So, after changing yaml file (spring cloud config) one will have to invoke /refresh to reload configurations?

Yes

If I add a new route will spring cloud gateway pick and execute it with given predicates and filters?

I believe so

Secondly, regarding JAVA based configurations, what If I use the variables which reads data from config server and use it in spring cloud gateway configurations. Will these configurations get updated when changed in the config server?

It should, yes

So, after changing yaml file (spring cloud config) one will have to invoke /refresh to reload configurations?

Yes

i change the yml file ,and request /actuator/gateway/refresh,and then it did not work

If you would like us to help you provide a sample that reproduces the problem.

Closing due to age of the question. If you would like us to look at this issue, please comment and we will look at re-opening the issue.

Just one late comment about dynamically update the routes, you can do it during runtime by using the event publisher ApplicationEventPublisher. After changing your routes all you need is calling the method refreshRoutes() on the following component.

`
@Component
public class GatewayRoutesRefresher implements ApplicationEventPublisherAware {

private ApplicationEventPublisher publisher;

@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
    publisher = applicationEventPublisher;
}

public void refreshRoutes() {
    publisher.publishEvent(new RefreshRoutesEvent(this));
}

}
`

For a more complete reference on dynamically setup and modification of routes take a look on following open source project: https://github.com/botorabi/HomieCenter
In particular this folder should be of your interest: https://github.com/botorabi/HomieCenter/tree/master/src/main/java/net/vrfun/homiecenter/reverseproxy

Was this page helpful?
0 / 5 - 0 ratings

Related issues

esacaceres picture esacaceres  路  7Comments

aresa7796 picture aresa7796  路  6Comments

ShahzebAnsari picture ShahzebAnsari  路  3Comments

xiaozhiliaoo picture xiaozhiliaoo  路  4Comments

zjengjie picture zjengjie  路  6Comments