spring-cloud / spring-cloud-gateway

An API Gateway built on Spring Framework and Spring Boot providing routing and more.
http://cloud.spring.io
Apache License 2.0
4.52k stars 3.32k forks source link

Springcloud gateway + BFF #1584

Closed ramonli closed 4 years ago

ramonli commented 4 years ago

I'm looking for a way to introduce BFF(backend for frontend) into gateway. Basically my idea is implementing some web controllers in springcloud gateway, and making all requests go through global/customized filters, and then enter my own web controllers(a uri like 'forward:/api/hello/gulu'). For example my routes is defined as below:

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    return builder.routes().route("hello", r -> {
            logger.debug("Hello, there...{}", r);
            return r.path("/**").filters(f -> {
                logger.debug("add request header...");
                return f.addRequestHeader("header1", "header-value-1");
            }).uri("https://httpbin.org/get");
        }).build();
}

and a global filter:

public class CustomGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        logger.info("custom global filter:{}", exchange.getRequest().getURI());
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -1;
    }
}

and a customized web controller:

@RestController
@RequestMapping("/api")
public class HelloController {

    private Logger logger = LoggerFactory.getLogger(HelloController.class);

    @GetMapping("/hello/{name}")
    public String hello(@PathVariable String name) {
        logger.debug("hello, {}", name);
        return "hello," + name;
    }
}

My expectation is that when client requests url 'http://localhost:18006/api/hello/ramon', it shoud intercepted by route 'hello', and then at least filtered by my CustomGlobalFilter, and finally hit HelloController. But the actual result is the request handled by RequestMappingHandlerMapping, just like a simple pure web controller, no any routes or filters triggered.

I am wondering whether it is right to introduce BFF into springcloud gateway, or there is some elegant way to implement this?

spencergibb commented 4 years ago

Your controller matches /api first, it never hits the gateway

ramonli commented 4 years ago

@spencergibb that is exactly what i want, make the request hit gateway first. Is there any means to implement it?

spencergibb commented 4 years ago

Change the controller mapping to something else and move /api to a gateway route

ramonli commented 4 years ago

yes, but if client access the web controller's URL directly, it will bypass gateway. That is some kind of risk, all my filters, something like rate limiter, will be ignored.

spencergibb commented 4 years ago

Move the controllers out of gateway I guess.

spring-projects-issues commented 4 years ago

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

spring-projects-issues commented 4 years ago

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.