- There is a known issue when composing a URI with WebClient as shown below:
webClient.get()
.uri(
uriBuilder -> uriBuilder.path("/v1/api/user/{id}").build(idNo)
)
// ...
- In this case, the
uri() method parameter passes the fully constructed URI through the uriBuilder.
- This can lead to excessive metric collection and potentially high memory usage.
- Example:
/v1/api/user/1234, /v1/api/user/2345 ...
- To collect metrics correctly, the URI should be collected in the template form
/v1/api/user/{id}.
- To achieve this, pass the URI template and its arguments directly to the
uri() method as shown below:
webClient.get()
.uri("/v1/api/user/{id}", idNo)
// ...
- By enabling Spring Boot Actuator, you can observe the difference through the
http.client.requests metric.
- From Boot 3.x onwards, this issue has been acknowledged. If the URI is determined to be dynamically generated, metrics collection does not occur.
- When calling WebClient with the code that was problematic in 2.x, you will see that the
uri tag value of the http.client.requests metric remains "none".
- To avoid potential side effects in future metric or log collection, avoid generating URL strings through
uriBuilder and passing them to uri() as you would in 2.x. Instead, pass the URI template and parameters directly.
- Simply avoid using
UriBuilder.path to maintain peace of mind.
webClient.get().uri("/v1/api/simple")...
webClient.get().uri("/v1/api/{id}", id)...
webClient.get()
.uri(uriBuilder -> uriBuilder
.path("/v1/api/{id}")
.queryParam("queryParam1", queryParam1)
.build(id)
)
...