refactor: decompose & simplify streaming multipart body encoding#3430
refactor: decompose & simplify streaming multipart body encoding#3430yvasyliev wants to merge 3 commits into
Conversation
velo
left a comment
There was a problem hiding this comment.
Thanks for continuing to simplify the multipart streaming internals. I can't merge this shape on the 14.x line because it removes public API that downstream users can already compile against. In api/src/main/java/feign/codec/Encoder.java, the public default supports(String) method is removed, and api/src/main/java/feign/codec/JsonEncoder.java loses its content-type behavior. The diff also removes public multipart extension points such as PartEncoder/PartResolver and replaces the existing MultipartFormEncoder builder customizers like partBodyEncoders/partEncoders/partResolvers. Those are source/binary compatibility breaks for a minor branch.\n\nPlease keep the existing public/protected symbols working and add the new design alongside them, or deprecate the old surface with replacement javadocs first and leave removal for a future major. Once the refactor is additive from a downstream user's point of view, I can take another pass.
|
my bad, sorry, you are correct, on 14.x api can be broken |
| * Session login(@Param("username") String username, @Param("password") String password); | ||
| * </pre> | ||
| */ | ||
| @FunctionalInterface |
| * </pre> | ||
| */ | ||
| public class JsonEncoder implements feign.codec.JsonEncoder { | ||
| public class JsonEncoder implements Encoder { |
There was a problem hiding this comment.
this is unacceptable, as graphql module requires a jsonEncoder/decoder and this breaks the pattern
Description
The 4th PR in a series related to #2734.
This PR is a follow-up to #3414. While #3414 successfully introduced streaming
multipart/form-datarequest bodies, the supporting architecture brought along a heavy footprint of specialized encoders and resolvers (AbstractPartEncoder,LeafPartResolver,ArrayPartResolver, etc.).This change partially reverts the over-extended class hierarchies introduced there and replaces them with a highly decomposed, modular, and simplified design that aligns strictly with the Single Responsibility Principle (SRP).
Proposed Changes
1. Separation of Concerns via Dedicated Factories
Instead of managing encoding across multiple deeply nested classes, the part creation pipeline is now orchestrated by a lightweight
PartFactorythat delegates cleanly to specialized components:PartHeadersFactory: Handles the calculation and construction of content-disposition and field-specific metadata headers.PartBodyFactory: Responsible for determining and invoking the correct encoding strategy for the part payload.2. Guarded Delegation with
ConditionalEncoder&EncoderPredicateIntroduces an expressive rule-matching layout to safely map core Feign encoders to specialized body media types:
EncoderPredicate: A functional abstraction used to check capability matches (such as evaluation of normalizedContent-Typeheaders) before encoding begins.ConditionalEncoder: A clean Decorator pattern implementation that guards a single delegate encoder and validates it against given capability criteria prior to execution, failing fast with a transparent exception if unsupported.3. Substantial Code Reduction
By flattening the pipeline, we are able to completely remove a substantial amount of redundant structural overhead:
AbstractPartEncoder,PartEncoder,DelegatingPartEncoder,ByteArrayPartEncoder,DefaultPartEncoder,FilePartEncoder,InputStreamPartEncoder.PartResolver,ArrayPartResolver,FormDataPartResolver,IterablePartResolver,LeafPartResolver.XmlEncoder.Related Pull Requests
Target Branch
14.xVerification Results