-
Notifications
You must be signed in to change notification settings - Fork 40.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Auto-configuration for RestClient, WebClient and generated @HttpExchange proxies #42963
Comments
RestClient
, WebClient
and generated @HttpExchange
proxies
Thanks for moving this topic over here @ch4mpy, and thanks for being willing to provide detailed feedback.
I haven't used the spring-addons project so my thoughts about it are mostly at the conceptual level. Having said that, I think that providing very detailed auto-configuration based solely on properties is only one way of providing convenience features like this. Sometimes, it will solve a particular problem very well. Other times, it might struggle to meet the requirements of a particular use case. When it fails to meet a particular requirement, I imagine it could quickly break down and require quite a pivot to a different way of configuring the application that is night and day from where the "yaml only" configuration began. Because of that, I imagine that it might lead to a particular style of architecting, arranging, or configuring applications to suit preference. I wonder whether such an opinionated set of arrangements would fit well inside of Spring Boot, or if instead they are best suited to what I would call a meta-framework (like spring-addons)?
Any time verbose configuration of technical components is required there is some difficulty and complexity. However, YAML is not the only place where such developer productivity improvements are gained, nor is it always capable of expressing the entire application's configuration. So again, I think this becomes about preference.
This seems very similar actually (in my mind at least) to what we have/had with XML configuration using namespaces. I don't know that this is really an intended paradigm for auto-configuration features of Spring Boot. I'm open to hearing other perspectives on the matter. In any case, I think conversation on #31337 illustrates quite well how much balance is required in finding general solutions for reducing boilerplate configuration. In such cases, if we can make it easier to produce meta-frameworks that tailor to a particular configuration preference, I think it benefits the entire community. Large companies which tend to produce their own meta-frameworks have an easier time maintaining them, and small companies and separate open source projects can more easily experiment and iterate on ideas and even easily change directions when needed. Regarding this issue, I'd be in favor of seeing a request like this broken down into some more discrete building blocks that ease or simplify multiple types of configuration approaches (not just configuration properties-based). So my question would be, are there any building blocks (components, factory methods, etc.) that might improve the situation for producing auto-configuration for |
Shouldn't frameworks precisely aim at reducing verbosity, difficulty, and complexity? To me, configuring clients request authorization with a I have the same observation for HTTP proxy configuration: this should be a snap, especially when the Ideally, selecting the kind of authorization to use (Basic or Bearer) and providing its details (credentials or access token source) would be independent of the underlying client implementation and framework version. Same for HTTP proxy configuration and stuff like connection & read timeouts. The YAML above achieves such a de-coupling and so do most of the existing "official" Boot properties.
Given "my" starter offers the option to expose the builders instead of already built instances, one can take auto-configuration to the point he likes and add his custom needs the exact same way he would without auto-configuration: as it is already documented in Spring Security or Spring Web documentation.
As I understand this other ticket, it is about auto-detecting So far, I focused on Here are some of the building blocks I wrote to ease clients auto-configuration:
All are in the |
Thanks @ch4mpy, that's helpful. I don't want to speak for the Boot team, but I think general support from Spring Boot for some of those items might still be tricky. I like the idea of enhancing builders, but I don't yet see configuration properties as a general solution. I'll spend some time thinking about this from a Spring Security perspective as I have some ideas that could be a middle ground. I'll update this issue with those ideas once they're fully formed. This may take a bit so please be patient with me. |
That's my initial feeling as well, but I must admit I haven't had the time yet to look too closely. We'll wait until we get feedback from @sjohnr about the Spring Security side before we do anything in Boot. |
@sjohnr In my comment above, I pointed to the master branch of spring-addons. That was a mistake as what I mentioned changed a lot in the branch I created for Boot 3.4 and Security 6.4. I updated the link, but if you have a look at the source of the building blocks I listed, please be sure to read from the |
@philwebb some building blocks aren't directly related to Spring Security and might be investigated in parallel. Notably:
|
I forgot to mention the main reason why I favored YAML (over the Java annotations asked in #31337) for REST clients and In my use-cases, the Plus, YAML makes it easy to adapt a deployment to a target environment with things like a base URL, HTTP proxy, or read & connection timeouts. |
Spring Cloud offers some auto-configuration for its
@FeignClient
which entered maintenance mode in favor ofRestClient
andWebClient
used withHttpServiceProxyFactory
for@HttpExchange
.The new solution provides similar declarative REST client features, at the price of quite some Java conf especially when request authorization is involved - which should almost always be the case.
I experienced
@HttpExchange
proxies auto-configuration using application properties in this starter of mine and I think that the features I implemented are worth integrating into the "official" framework because they greatly improve developers' experience.Sample
Use case
Let's consider the pool of
oauth2ResourceServer
microservices from this sample repository.the 3 different declinations of the
MicroserviceChouette*Application
call:MicroserviceMachinApplication
on behalf of the resource owner at the origin of the requests: the requests are authorized re-using theBearer
token in the security-context (MicroserviceChouetteApplication
is a resource server, so the request it processes already is authorized with aBearer
token).MicroserviceBiduleApplication
in their own names: a newBearer
token is acquired using client-credentials flow.The
MicroserviceMachinApplication
exposes an OpenAPI document from which we can generate the following:The
MicroserviceBiduleApplication
exposes an OpenAPI document from which we can generate the following:MicroserviceChouetteApplication
collaborates with the two REST APIs above as follows:This requires implementations for
MachinApi
andBiduleApi
to be exposed as beans, internally using aRestClient
orWebClient
instance to retrieve REST resources from other services - authorizing these requests withBearer
tokens.Common security configuration
REST configuration with just "official"
3.4.0-RC1
startersI believe that we can hardly be more synthetic than the following for having
MachinApi
andBiduleApi
implementations generated byHttpServiceProxyFactory
, usingRestClient
instances configured with the requiredClientHttpRequestInterceptor
s:Things get even more complicated if the
ClientHttpRequestFactory
needs configuration for connect timeout, read timeout, or HTTP or SOCKS proxy (reach a remote service like Google API).REST configuration with
spring-addons-starter-rest
The
RestConfiguration
becomes:Features
What is already implemented:
- A base URI that is likely to change from one deployment to another.
- Request authorization with a choice of Basic and Bearer, and for the latter, the choice of forwarding the token in the security context of a resource server, or obtained using an OAuth2 client registration ID.
- Set
Proxy-Authorization
header and configure aClientHttpRequestFactory
for HTTP or SOCKS proxy. Enabled by default if the standardHTTP_PROXY
andNO_PROXY
environment variables or custom application properties are set, but can be disabled on any auto-configured client.RestClient
by default in servlets andWebClients
in Webflux apps, but any client can be switched toWebClient
in servlets.RestClient
orWebClient
. This can be useful when some more configuration is needed than what the starter implements.Builder
suffix ifexpose-builder=true
). A custom name can be defined in propertiesRoom for improvement: remove the need for the generated
@HttpExchange
proxies beans definition in theRestConfiguration
. I haven't found how to properly post-process theBeanDefinitionRegistry
. The additional properties could look like the following:The great point of using a client bean name (rather than a key under the
client
properties), is that it allows to use any REST client, which could be a bean exposed using an auto-configured builder or a completely hand-crafted one.Additional context
I already asked for this in Spring Security issues. @sjohnr wrote that such auto-configuration requests better fit here, and also that this shouldn't be implemented in the "official" framework because this would be "programming with yaml".
I have a different opinion about such auto-configuration. To me, it is about:
My starter is just fine for me and the (very) few teams getting to know it and accepting to use it, but I'm sure that many more would be glad to benefit from such auto-configuration using just the official Boot starters.
The text was updated successfully, but these errors were encountered: