I want to filter-out Json objects from a REST end-point into a new - reduced stream of objects. I have a REST handler component that uses a WebClient to retrieve a Flux of JsonNode objects by providing a URI. For testing purposes I use dummy REST end-point.
The dummy JSON for mobiles product look like this:
{
"products": [
{
"id": 1,
"title": "iPhone 9",
"description": "An apple mobile which is nothing like apple",
"price": 549,
"discountPercentage": 12.96,
"rating": 4.69,
"stock": 94,
"brand": "Apple",
"category": "smartphones",
"thumbnail": "https://i.dummyjson.com/data/products/1/thumbnail.jpg",
"images": [
"https://i.dummyjson.com/data/products/1/1.jpg",
"https://i.dummyjson.com/data/products/1/2.jpg",
"https://i.dummyjson.com/data/products/1/3.jpg",
"https://i.dummyjson.com/data/products/1/4.jpg",
"https://i.dummyjson.com/data/products/1/thumbnail.jpg"
]
},
{
"id": 2,
"title": "iPhone X",
"description": "SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...",
"price": 899,
"discountPercentage": 17.94,
"rating": 4.0,
"stock": 34,
"brand": "Apple",
"category": "smartphones",
"thumbnail": "https://i.dummyjson.com/data/products/2/thumbnail.jpg",
"images": [
"https://i.dummyjson.com/data/products/2/1.jpg",
"https://i.dummyjson.com/data/products/2/2.jpg",
"https://i.dummyjson.com/data/products/2/3.jpg",
"https://i.dummyjson.com/data/products/2/thumbnail.jpg"
]
},
…
In the test use-case I provide a criteria to filter out all JsonNode objects (smartphones) that received a rating score higher than 4.1. I want to be able to dynamically filter the response by providing a JSON path and criteria, but for testing purpose I hard code the path and criteria as following;
@Test
public void invokeGetJsonFluxResponseTest() {
UriComponents uriComp = UriComponentsBuilder
.newInstance().
scheme(URI_SCHEME)
.host(URI_HOST)
.path(URI_PATH_PRODUCT_CATEGORY).build().encode();
assertThat(uriComp.toUriString()).isNotEmpty();
log.debug("URI: {}", uriComp.toUriString());
Flux<JsonNode> result = restInokationHandler.invokeGetJsonFluxRespose(uriComp.toUri());
result.doOnNext(node -> {
if(node.path("/products/rating").asDouble() >= 4.1)
log.debug(node.toPrettyString());
}
).blockLast();
}
I presume that my test function is consuming the stream since nothing is logged in the debug output. Who do I filter-out JSON objects from a Flux of JsonNode and collect them into a new stream?
I am using Spring Boot 3.
P.S. A similar question provides an answer by using Jackson2JsonDecoder
and ObjectMapper
to create a new stream.