spring-projects / spring-framework

Spring Framework
https://spring.io/projects/spring-framework
Apache License 2.0
56.72k stars 38.15k forks source link

Support ModelAttributes / Databinding out of the box in HttpServiceProxyFactory #32142

Open aykborstelmann opened 10 months ago

aykborstelmann commented 10 months ago

Affects: 6.+


I really appreciate the HttpServiceProxyFactory, it is a great feature to easily create a client matching a interface. However, for large APIs, we usually like to encapsulate multiple parameters in convenience classes, which spring web supports with databinding.

public interface EndpointApi {
  @GetExchange("/endpoint")
  EndpointResponse getProcedures(
      EndpointFilterOptions filterOptions,
      EndpointSortOptions sortOptions,
      EndpointPaginationOptions paginationOptions);
}

@ParameterObject
public record GetProceduresFilterOptions(
        @BindParam("customName")
        UUID filterOne,
        String stringFilter,
        Boolean booleanFilter,
        Set<Types> setFilter) {}
}

However, when creating a client for EndpointApi and using it, no HttpServiceArgumentResolver exists per default to handle such parameters.

I would appreciate this feature out of the box, while I am are that, HttpServiceProxyFactory provides a way to register custom argumentResolvers.

rstoyanchev commented 9 months ago

@aykborstelmann, thanks for the suggestion. Note that there is currently no such mechanism if using RestClient or WebClient directly. In other words, no message converter that would take an object, turn it into form data, e.g. for POST, or query params for GET. It's not an argument against, but just mentioning.

While I understand the benefit, the main challenge is that in the general case an object can be of arbitrary depth and structure, and there will clearly need to be some limits around what is possible. It also increases the possibility of using objects that were not originally built for this, and end up sending information that wasn't meant to be sent. Even in your example record, the last property is a Set which cannot be expressed with data binding property paths since it is not an indexed collection.

spring-projects-issues commented 9 months ago

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

aykborstelmann commented 9 months ago

@rstoyanchev yes I'm aware of the difficulties involved. In theory this must be the inverse of the ModelAttributeMethodProcessor. I can imagine there might be even cases that are not invertible. Still I am convinced this feature would be great to encapsulate data in APIs.