Question
My use-case : 2 microservices behind the api gateway.
I get a route that must be route to microservice B but before the request must be routed to microservice A for some pre-check (it's not an API-Composition)
So I implemented the call to microservice A in a GatewayFilter. Config :
.route(r -> r.method(HttpMethod.GET)
.and()
.path("/messages/*")
.filters((f) -> f.filter(precheckfilter))
.uri(destinations.getEndpointX))
problem : I don't found an easy way to extract the request body (Flux of DataBuffer to Json String) and call the service 2. I got some exceptions because I used blocking method like toStream()
Where can I find some samples about filter implementation ?
I try something like this :
exchange.getRequest().getBody().map(dataBuffer -> {
ByteSource byteSource = new ByteSource() {
@Override
public InputStream openStream() throws IOException {
return dataBuffer.asInputStream();
}
};
try {
String text = byteSource.asCharSource(Charsets.UTF_8).read();
return text;
} catch (IOException e) {
throw new RuntimeException(e);
}
}).collect(Collectors.joining()).subscribe(....call service B)
but wrong....
I simply tried this
return (exchange, chain) -> {
ServerRequest serverRequest = new DefaultServerRequest(exchange);
serverRequest.bodyToMono(String.class).subscribe(s -> {
System.out.println("Request : " + s);
});
return chain.filter(exchange);
};
but seems request body is empty... don't understand what happened...
Please learn how to properly format code and logs.
See https://github.com/spring-cloud/spring-cloud-gateway/blob/master/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyRequestBodyGatewayFilterFactory.java for how to read the request body.
It is non-trivial.
Indeed non-trivial.. ok thanks I will try this.
Client: Content_type is application/json and post request
Server: springboot 2.0.6 and spring cloud gateway Finchley.SR2
steps:
first: Server gets body from post request
second: Server uses the params to do somthing then get new params
problems: this first step sometimes cannot get full body,sometimes can work. why?
method:
private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) {
Flux
AtomicReference
body.subscribe(buffer -> {
CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
DataBufferUtils.release(buffer);
bodyRef.set(charBuffer.toString());
});
return bodyRef.get();
}
For reading or modifying request body, one can simply use a filter which extends ModifyRequestBodyGatewayFilterFactory class.
`public class MyFilter extends ModifyRequestBodyGatewayFilterFactory {
@Override
public GatewayFilter apply(Config config) {
config.setRewriteFunction(String.class, String.class,
(exchange, originContent) -> {
System.out.println(originContent);
return Mono.just(originContent);
});
return super.apply(config);
}
}
`
Is it possible to easily read only the first few hundred bytes of the body without reading the whole request body, without affecting how the request is routed through to the destination? I have very large requests, and I need to do some content based routing by running a regex against a small chunk at the beginning of the body. Reading the whole body causes performance problems with the JVM/heap.