Affects: \
To my knowledge, for RSocket request, the hints on client and server side are both an empty map.
Even I add a metadata into header by RSocketRequester.RequestSpec#metadata, there is no way for me to use the metadata on server side.
To support hints on client and server side will in favor of user to pass encode/decode context.
And I'll pull a request if any one expect this change.For how to implement it, we could discuss on below.
On RSocket client, in DefaultRequestSpec#encodeData method uses an empty hints to call encoder:
private <T> DataBuffer encodeData(T value, ResolvableType elementType, @Nullable Encoder<?> encoder) {
if (encoder == null) {
elementType = ResolvableType.forInstance(value);
encoder = strategies.encoder(elementType, dataMimeType);
}
return ((Encoder<T>) encoder).encodeValue(
value, bufferFactory(), elementType, dataMimeType, EMPTY_HINTS);
}
On RSocket server side, in PayloadMethodArgumentResolver#decodeContent method uses an empty hints to call decoder:
private Mono<Object> decodeContent(MethodParameter parameter, Message<?> message,
boolean isContentRequired, Flux<DataBuffer> content, MimeType mimeType) {
ResolvableType targetType = ResolvableType.forMethodParameter(parameter);
Class<?> resolvedType = targetType.resolve();
ReactiveAdapter adapter = (resolvedType != null ? getAdapterRegistry().getAdapter(resolvedType) : null);
ResolvableType elementType = (adapter != null ? targetType.getGeneric() : targetType);
isContentRequired = isContentRequired || (adapter != null && !adapter.supportsEmpty());
Consumer<Object> validator = getValidator(message, parameter);
Map<String, Object> hints = Collections.emptyMap();
for (Decoder<?> decoder : this.decoders) {
if (decoder.canDecode(elementType, mimeType)) {
if (adapter != null && adapter.isMultiValue()) {
Flux<?> flux = content
.map(buffer -> decoder.decode(buffer, elementType, mimeType, hints))
.onErrorResume(ex -> Flux.error(handleReadError(parameter, message, ex)));
if (isContentRequired) {
flux = flux.switchIfEmpty(Flux.error(() -> handleMissingBody(parameter, message)));
}
if (validator != null) {
flux = flux.doOnNext(validator);
}
return Mono.just(adapter.fromPublisher(flux));
}
else {
// Single-value (with or without reactive type wrapper)
Mono<?> mono = content.next()
.map(buffer -> decoder.decode(buffer, elementType, mimeType, hints))
.onErrorResume(ex -> Mono.error(handleReadError(parameter, message, ex)));
if (isContentRequired) {
mono = mono.switchIfEmpty(Mono.error(() -> handleMissingBody(parameter, message)));
}
if (validator != null) {
mono = mono.doOnNext(validator);
}
return (adapter != null ? Mono.just(adapter.fromPublisher(mono)) : Mono.from(mono));
}
}
}
return Mono.error(new MethodArgumentResolutionException(
message, parameter, "Cannot decode to [" + targetType + "]" + message));
}
Comment From: rstoyanchev
It's not very clear what you are requesting. We do support access to metadata. Metadata sent by a client can be extracted by a sever (and vice versa) and accessed as message headers, see the section on MetadataExtractor. That aside, hints and metadata are unrelated to each other so I'm not sure what you need to use hints for?
Comment From: rudy2steiner
It's not very clear what you are requesting. We do support access to metadata. Metadata sent by a client can be extracted by a sever (and vice versa) and accessed as message headers, see the section on MetadataExtractor. That aside, hints and metadata are unrelated to each other so I'm not sure what you need to use hints for?
I want to use metadata of headers on Decoder hints. Even I could extract my metadata by self-defined MetadataExtractor, but can't access metadata of headers on decoders on server side. And can't provide hints for encoders on RSocket client(DefaultRequestSpec)
Comment From: rstoyanchev
I see now, thanks. We could pass the message headers map as a hint. That would work with the MetadataExtractor mechanism, so that whatever gets extracted is available to decoders.
Comment From: rudy2steiner
@rstoyanchev Yes, would you mind assigning it to me, I'd like to work on it as my first try!
Comment From: rstoyanchev
We don't generally assign like that but you can submit a PR. You'll have to do so before the end of this week if this is to make the 5.3.2 release next week. Let me know if you are up for that given this.
Comment From: rudy2steiner
We don't generally assign like that but you can submit a PR. You'll have to do so before the end of this week if this is to make the 5.3.2 release next week. Let me know if you are up for that given this.
Thanks, i'll try my best to make it ready before the 5.3.2 release
Comment From: rstoyanchev
Superseded by #26220.