diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc index 867d3c5b..6d5866b8 100644 --- a/docs/modules/ROOT/nav.adoc +++ b/docs/modules/ROOT/nav.adoc @@ -1,4 +1,7 @@ * xref:index.adoc[Introduction] + +// begin Gateway Reactive Server + * xref:spring-cloud-gateway.adoc[] ** xref:spring-cloud-gateway/starter.adoc[] ** xref:spring-cloud-gateway/glossary.adoc[] @@ -58,7 +61,16 @@ ** xref:spring-cloud-gateway/developer-guide.adoc[] ** xref:spring-cloud-gateway/aot-and-native-image-support.adoc[] ** xref:spring-cloud-gateway/configuration-properties.adoc[] + +// begin Gateway Server MVC + * xref:spring-cloud-gateway-server-mvc.adoc[] ** xref:spring-cloud-gateway-server-mvc/starter.adoc[] +** xref:spring-cloud-gateway-server-mvc/glossary.adoc[] +** xref:spring-cloud-gateway-server-mvc/how-it-works.adoc[] +** xref:spring-cloud-gateway-server-mvc/java-routes-api.adoc[] + +// begin Gateway Proxy Exchange + * xref:spring-cloud-gateway-proxy-exchange.adoc[] * xref:appendix.adoc[] diff --git a/docs/modules/ROOT/pages/spring-cloud-gateway-server-mvc/glossary.adoc b/docs/modules/ROOT/pages/spring-cloud-gateway-server-mvc/glossary.adoc new file mode 100644 index 00000000..e8b5fc6d --- /dev/null +++ b/docs/modules/ROOT/pages/spring-cloud-gateway-server-mvc/glossary.adoc @@ -0,0 +1,11 @@ +[[glossary]] += Glossary +:page-section-summary-toc: 1 + +* *Route*: The basic building block of the gateway. +It is defined by an ID, a destination URI, a collection of predicates, and a collection of filters. A route is matched if the aggregate predicate is true. +* *Predicate*: This is a https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/function/RequestPredicate.html[Spring WebMvc.fn `RequestPredicate`]. The input type is a https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/function/ServerRequest.html[Spring WebMvc.fn `ServerRequest`]. +This lets you match on anything from the HTTP request, such as headers or parameters. +* *Filter*: These are instances of https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/function/HandlerFilterFunction.html[`HandlerFilterFunction`]. +Here, you can modify requests and responses before or after sending the downstream request. Filters may also implement `Function` and adapted to a `HandlerFilterFunction` by https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/function/HandlerFilterFunction.html#ofRequestProcessor(java.util.function.Function)[`HandlerFilterFunction.ofRequestProcessor()`] for 'before' filters. For 'after' filters, `BiFunction` may be implemented and adapted by https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/function/HandlerFilterFunction.html#ofResponseProcessor(java.util.function.BiFunction)[`HandlerFilterFunction.ofResponseProcessor()`]. + diff --git a/docs/modules/ROOT/pages/spring-cloud-gateway-server-mvc/how-it-works.adoc b/docs/modules/ROOT/pages/spring-cloud-gateway-server-mvc/how-it-works.adoc new file mode 100644 index 00000000..874e6807 --- /dev/null +++ b/docs/modules/ROOT/pages/spring-cloud-gateway-server-mvc/how-it-works.adoc @@ -0,0 +1,17 @@ +[[gateway-how-it-works]] += How It Works +:page-section-summary-toc: 1 + +The following diagram provides a high-level overview of how Spring Cloud Gateway works: + +// TODO: gateway mvc diagram +//image::spring_cloud_gateway_diagram.png[Spring Cloud Gateway Diagram] + +In Spring Cloud Gateway Server MVC routes are normal WebMvc.fn `RouterFunction` instances with a special https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/function/HandlerFunction.html[HandlerFunction] to forward the requests over HTTP defined in https://github.com/spring-cloud/spring-cloud-gateway/blob/main/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/handler/HandlerFunctions.java[org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions]. Please see the https://docs.spring.io/spring-framework/reference/web/webmvc-functional.html[WebMvc.fn] documentation for regular use of the functional API. + +In addition to custom `HandlerFunctions` for HTTP forwarding, Spring Cloud Gateway Server MVC provides additional `RequestPredicate` implementations in https://github.com/spring-cloud/spring-cloud-gateway/blob/main/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/predicate/GatewayRequestPredicates.java[org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates] and `HandlerFilterFunctions` implementations in https://github.com/spring-cloud/spring-cloud-gateway/blob/main/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/FilterFunctions.java[org.springframework.cloud.gateway.server.mvc.filter.FilterFunctions]. All the custom filters that can be pure 'before' filters are implemented in https://github.com/spring-cloud/spring-cloud-gateway/blob/main/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/BeforeFilterFunctions.java[org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions] and adapted in `FilterFunctions` as request processors. The custom 'after' filters in https://github.com/spring-cloud/spring-cloud-gateway/blob/main/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/AfterFilterFunctions.java[org.springframework.cloud.gateway.server.mvc.filter.AfterFilterFunctions] are also adapted in `FilterFunctions` as response processors. + +There are additional `*FilterFunctions` classes for optional filters that will are documented along with each filter. + + + diff --git a/docs/modules/ROOT/pages/spring-cloud-gateway-server-mvc/java-routes-api.adoc b/docs/modules/ROOT/pages/spring-cloud-gateway-server-mvc/java-routes-api.adoc new file mode 100644 index 00000000..ba9ee6ec --- /dev/null +++ b/docs/modules/ROOT/pages/spring-cloud-gateway-server-mvc/java-routes-api.adoc @@ -0,0 +1,41 @@ +[[java-routes-api]] += Java Routes API + +Spring Cloud Gateway Server MVC uses the Spring WebMvc.fn https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/function/RouterFunctions.Builder.html[RouterFunctions.Builder] as the default way to create Routes, which are WebMvc.fn https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/function/RouterFunction.html[RouterFunction] instances. + +A https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/function/RouterFunctions.Builder.html[`RouterFunctions.Builder`] instance is obtained by calling https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/function/RouterFunctions.html#route()[RouterFunctions.route()] + +.GatewaySampleApplication.java +[source,java] +---- +import org.springframework.web.servlet.function.RouterFunctions.route; +import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http; + +class SimpleGateway { + @Bean + public RouterFunction getRoute() { + return route().GET("/get", http("https://httpbin.org")); + } +} +---- + +There are methods in `RouterFunctions.Builder` for each HTTP methods (GET, POST, etc...) combined with a path predicate, such as `/get` as above. The final parameter is the `HandlerFilterFunction`, in this case `HandlerFunctions.http()`. There are overloaded methods for each HTTP method for additional `RequestPredicate` parameters as well as a generic `route(RequestPredicate, HandlerFunction`) method for general use. + +[[gateway-routerfunctions-builder]] +== Gateway MVC implementation of RouterFunctions.Builder + +Some advanced filters require some metadata to be added to request attributes. To accommodate this, there is a `org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions` class. `GatewayRouterFunctions.route(String routeId) creates a `RouterFunctions.Builder` instance then adds a 'before' filter to add the `routeId` as request metadata. + +.GatewaySampleApplication.java +[source,java] +---- +import org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions; +import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http; + +class SimpleGateway { + @Bean + public RouterFunction getRoute() { + return route("simple_route").GET("/get", http("https://httpbin.org")); + } +} +---- \ No newline at end of file diff --git a/docs/modules/ROOT/pages/spring-cloud-gateway-server-mvc/starter.adoc b/docs/modules/ROOT/pages/spring-cloud-gateway-server-mvc/starter.adoc index 7924560e..3c081e91 100644 --- a/docs/modules/ROOT/pages/spring-cloud-gateway-server-mvc/starter.adoc +++ b/docs/modules/ROOT/pages/spring-cloud-gateway-server-mvc/starter.adoc @@ -5,9 +5,9 @@ To include Spring Cloud Gateway Server MVC in your project, use the starter with a group ID of `org.springframework.cloud` and an artifact ID of `spring-cloud-starter-gateway-mvc`. See the https://projects.spring.io/spring-cloud/[Spring Cloud Project page] for details on setting up your build system with the current Spring Cloud Release Train. -If you include the starter, but you do not want the gateway to be enabled, set `spring.cloud.gateway.enabled=false`. +If you include the starter, but you do not want the gateway to be enabled, set `spring.cloud.gateway.mvc.enabled=false`. -IMPORTANT: Spring Cloud Gateway Server MVC is built on https://spring.io/projects/spring-boot#learn[Spring Boot] and https://docs.spring.io/spring-framework/reference/web.html[Spring Web MVC]. +IMPORTANT: Spring Cloud Gateway Server MVC is built on https://spring.io/projects/spring-boot#learn[Spring Boot] and https://docs.spring.io/spring-framework/reference/web/webmvc-functional.html[Spring WebMvc.fn]. As a consequence, many of the asynchronous or reactive libraries may not apply when you use Spring Cloud Gateway Server MVC. IMPORTANT: Spring Cloud Gateway Server MVC works with traditional Servlet runtimes such as Tomcat and Jetty. diff --git a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/GatewayServerMvcAutoConfiguration.java b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/GatewayServerMvcAutoConfiguration.java index 883b078b..5effacfd 100644 --- a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/GatewayServerMvcAutoConfiguration.java +++ b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/GatewayServerMvcAutoConfiguration.java @@ -19,6 +19,7 @@ package org.springframework.cloud.gateway.server.mvc; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration; import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; import org.springframework.boot.ssl.SslBundle; @@ -51,6 +52,7 @@ import org.springframework.util.StringUtils; import org.springframework.web.client.RestClient; @AutoConfiguration(after = { RestTemplateAutoConfiguration.class, RestClientAutoConfiguration.class }) +@ConditionalOnProperty(name = "spring.cloud.gateway.mvc.enabled", matchIfMissing = true) @Import(GatewayMvcPropertiesBeanDefinitionRegistrar.class) public class GatewayServerMvcAutoConfiguration {