This is an enhancement request for rSocket Metadata strategy.
Can we simplify the current design as shown in this pseudo code.? I have used Person object for metadata just to explain. do not take that seriously.
// create mimetype or metatdata key
MimeType pMime1 = MimeType.from("pKey1", Person.class);
MimeType pMime2 = MimeType.from("pKey2", Person.class);
// pass it with requester
rSocketRequester
.metadata(new Person("name1", age), pMime1)
.metadata(new Person("name2", age), pMime2)
// access it on the responder side
// find the value from metatdata based on the header key
@MessageMapping
public Mono<Sting> method(@Header("pKey1") Person person){
}
Can we use Jackson2Cbor as default encoders/decoders for metadata? Currently we need to provide our own encoders/decoders for any custom metadata mime type. Also currently looks like we can not pass 2 different objects same type.
Comment From: rstoyanchev
It is possible to to map metadata to message headers and access that via @Header
. It is done through the MetadataExtractorRegistry
and set on the RSocketStrategies
(e.g. in RSocketMessageHandler
). This section of the docs describes that.
The codecs for Jackson are in spring-web
and not available to spring-messaging
to be configured by default, but in a Spring Boot application, you will get CBOR with Jackson by default.
Comment From: kitkars
I tried something similar.
@Bean
public RSocketStrategiesCustomizer strategies(){
return s -> s.metadataExtractorRegistry(registry -> {
registry.metadataToExtract(someMimeType, Something.class, "something");
// ...
});
}
but getting this exception.
Caused by: java.lang.IllegalArgumentException: No decoder for messaging/x.something and com.demo.Something
I was suggesting
- can we have CBOR as default when it is not specified in the above case?.
- I have to create another mime like
messaging/x.something.2
if I want to pass one more instance of same type and I need to provide multiple extraction strategy. So I was asking can we simplify this further as I had mentioned above.
Please feel free to close this if it does not make any sense!
Comment From: rstoyanchev
Composite Metadata is just a sequence of sections, each preceded by a MIME type and having metadata payload content. I don't think it's meant to be used such that the same MIME type is present twice. There would be no definitive way to know which is which unless you follow the exact same order and that seems brittle.
In short I don't see a way to simplify this. I would suggest one CBOR metadata payload with both objects you have embedded within it, or perhaps a List
or a Map
. A different MIME type is necessary when the metadata has a different purpose or is maybe managed by an independent library (e.g. routing, security, tracing, metrics).
Comment From: rstoyanchev
Actually the composite metadata extension does say "Multiple metadata payloads with the same MIME type are allowed". I'll have another look at this.
Comment From: rstoyanchev
After further consideration, multiple metadata payloads with the same MIME type are allowed, but aren't necessarily a good fit in all scenarios. In our context, where we take a list of metadata records and use registrations to turn that into a map, we'll stick to expecting unique MIME types to avoid ambiguity.
If the same Object type is expected, you could use a list and register as follows:
registry.metadataToExtract("application/cbor", new ParameterizedTypeReference<List<Person>>(){}, "personList");
Along with that, defaulting to CBOR in registrations doesn't make much sense, as it should be unique and appear only once.