158 lines
4.8 KiB
Plaintext
158 lines
4.8 KiB
Plaintext
[[developer-guide]]
|
|
= Developer Guide
|
|
|
|
These are basic guides to writing some custom components of the gateway.
|
|
|
|
[[writing-custom-route-predicate-factories]]
|
|
== Writing Custom Route Predicate Factories
|
|
|
|
|
|
In order to write a Route Predicate you will need to implement `RoutePredicateFactory` as a bean. There is an abstract class called `AbstractRoutePredicateFactory` which you can extend.
|
|
|
|
.MyRoutePredicateFactory.java
|
|
[source,java]
|
|
----
|
|
@Component
|
|
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {
|
|
|
|
public MyRoutePredicateFactory() {
|
|
super(Config.class);
|
|
}
|
|
|
|
@Override
|
|
public Predicate<ServerWebExchange> apply(Config config) {
|
|
// grab configuration from Config object
|
|
return exchange -> {
|
|
//grab the request
|
|
ServerHttpRequest request = exchange.getRequest();
|
|
//take information from the request to see if it
|
|
//matches configuration.
|
|
return matches(config, request);
|
|
};
|
|
}
|
|
|
|
public static class Config {
|
|
//Put the configuration properties for your filter here
|
|
}
|
|
|
|
}
|
|
----
|
|
[[writing-custom-gatewayfilter-factories]]
|
|
== Writing Custom GatewayFilter Factories
|
|
|
|
To write a `GatewayFilter`, you must implement `GatewayFilterFactory` as a bean.
|
|
You can extend an abstract class called `AbstractGatewayFilterFactory`.
|
|
The following examples show how to do so:
|
|
|
|
.PreGatewayFilterFactory.java
|
|
====
|
|
[source,java]
|
|
----
|
|
@Component
|
|
public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {
|
|
|
|
public PreGatewayFilterFactory() {
|
|
super(Config.class);
|
|
}
|
|
|
|
@Override
|
|
public GatewayFilter apply(Config config) {
|
|
// grab configuration from Config object
|
|
return (exchange, chain) -> {
|
|
//If you want to build a "pre" filter you need to manipulate the
|
|
//request before calling chain.filter
|
|
ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
|
|
//use builder to manipulate the request
|
|
return chain.filter(exchange.mutate().request(builder.build()).build());
|
|
};
|
|
}
|
|
|
|
public static class Config {
|
|
//Put the configuration properties for your filter here
|
|
}
|
|
|
|
}
|
|
----
|
|
|
|
.PostGatewayFilterFactory.java
|
|
[source,java]
|
|
----
|
|
@Component
|
|
public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {
|
|
|
|
public PostGatewayFilterFactory() {
|
|
super(Config.class);
|
|
}
|
|
|
|
@Override
|
|
public GatewayFilter apply(Config config) {
|
|
// grab configuration from Config object
|
|
return (exchange, chain) -> {
|
|
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
|
|
ServerHttpResponse response = exchange.getResponse();
|
|
//Manipulate the response in some way
|
|
}));
|
|
};
|
|
}
|
|
|
|
public static class Config {
|
|
//Put the configuration properties for your filter here
|
|
}
|
|
|
|
}
|
|
----
|
|
====
|
|
|
|
[[naming-custom-filters-and-references-in-configuration]]
|
|
=== Naming Custom Filters And References In Configuration
|
|
|
|
Custom filters class names should end in `GatewayFilterFactory`.
|
|
|
|
For example, to reference a filter named `Something` in configuration files, the filter
|
|
must be in a class named `SomethingGatewayFilterFactory`.
|
|
|
|
WARNING: It is possible to create a gateway filter named without the
|
|
`GatewayFilterFactory` suffix, such as `class AnotherThing`. This filter could be
|
|
referenced as `AnotherThing` in configuration files. This is **not** a supported naming
|
|
convention and this syntax may be removed in future releases. Please update the filter
|
|
name to be compliant.
|
|
|
|
[[writing-custom-global-filters]]
|
|
== Writing Custom Global Filters
|
|
|
|
To write a custom global filter, you must implement `GlobalFilter` interface as a bean.
|
|
This applies the filter to all requests.
|
|
|
|
The following examples show how to set up global pre- and post-filters, respectively:
|
|
|
|
[source,java]
|
|
----
|
|
@Bean
|
|
public GlobalFilter customGlobalFilter() {
|
|
return (exchange, chain) -> exchange.getPrincipal()
|
|
.map(Principal::getName)
|
|
.defaultIfEmpty("Default User")
|
|
.map(userName -> {
|
|
//adds header to proxied request
|
|
ServerHttpRequest.Builder builder = exchange.getRequest().mutate().header("CUSTOM-REQUEST-HEADER", userName);
|
|
//use builder to manipulate the request
|
|
return exchange.mutate().request(builder.build()).build();
|
|
})
|
|
.flatMap(chain::filter);
|
|
}
|
|
|
|
@Bean
|
|
public GlobalFilter customGlobalPostFilter() {
|
|
return (exchange, chain) -> chain.filter(exchange)
|
|
.then(Mono.just(exchange))
|
|
.map(serverWebExchange -> {
|
|
//adds header to response
|
|
serverWebExchange.getResponse().getHeaders().set("CUSTOM-RESPONSE-HEADER",
|
|
HttpStatus.OK.equals(serverWebExchange.getResponse().getStatusCode()) ? "It worked": "It did not work");
|
|
return serverWebExchange;
|
|
})
|
|
.then();
|
|
}
|
|
----
|
|
|