Spring Web Reactive | 5. RSocket | 5.4. MetadataExtractor

Responders must interpret metadata. Composite metadata uses its own MIME type and can contain individually formatted metadata values for routing, security, tracing, and other purposes. Applications need a way to configure the metadata MIME types they support and access extracted values.

MetadataExtractor extracts serialized metadata and returns decoded name-value pairs. These can be accessed like named headers, for example through @Header in an annotated handler method.

You can provide decoder instances to DefaultMetadataExtractor to decode metadata. It includes built-in support for "message/x.rsocket.routing.v0", decoding it as a String and storing it under the "route" key. For other MIME types, provide a Decoder and register the MIME type as follows.

Java

DefaultMetadataExtractor extractor = new DefaultMetadataExtractor(metadataDecoders);
extractor.metadataToExtract(fooMimeType, Foo.class, "foo");

Kotlin

import org.springframework.messaging.rsocket.metadataToExtract

val extractor = DefaultMetadataExtractor(metadataDecoders)
extractor.metadataToExtract<Foo>(fooMimeType, "foo")

Composite metadata is well suited to combining separate metadata values. However, a requester may not support composite metadata or may choose not to use it. Therefore, DefaultMetadataExtractor sometimes needs custom logic to map decoded values into the output map. The following example uses JSON metadata.

Java

DefaultMetadataExtractor extractor = new DefaultMetadataExtractor(metadataDecoders);
extractor.metadataToExtract(
    MimeType.valueOf("application/vnd.myapp.metadata+json"),
    new ParameterizedTypeReference<Map<String,String>>() {},
    (jsonMap, outputMap) -> {
        outputMap.putAll(jsonMap);
    });

Kotlin

import org.springframework.messaging.rsocket.metadataToExtract

val extractor = DefaultMetadataExtractor(metadataDecoders)
extractor.metadataToExtract<Map<String, String>>(MimeType.valueOf("application/vnd.myapp.metadata+json")) { jsonMap, outputMap ->
    outputMap.putAll(jsonMap)
}

When configuring RSocketStrategies with a MetadataExtractor, you can use the decoders configured on RSocketStrategies.Builder to create the extractor and define registrations with a callback.

Java

RSocketStrategies strategies = RSocketStrategies.builder()
    .metadataExtractorRegistry(registry -> {
        registry.metadataToExtract(fooMimeType, Foo.class, "foo");
        // ...
    })
    .build();

Kotlin

import org.springframework.messaging.rsocket.metadataToExtract

val strategies = RSocketStrategies.builder()
        .metadataExtractorRegistry { registry: MetadataExtractorRegistry ->
            registry.metadataToExtract<Foo>(fooMimeType, "foo")
            // ...
        }
        .build()