5.4. MetadataExtractor

์‘๋‹ต์ž๋Š” ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ๋ฅผ ํ•ด์„ํ•ด์•ผ ํ•œ๋‹ค. Composite metadata๋Š” ๊ฐ๊ฐ ๊ณ ์œ ํ•œ mime ํƒ€์ž…์œผ๋กœ ํฌ๋งทํŒ…๋œ ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ ๊ฐ’(์˜ˆ๋ฅผ ๋“ค๋ฉด, ๋ผ์šฐํŒ…, ๋ณด์•ˆ, ์ถ”์ )์„ ํ—ˆ์šฉํ•œ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ง€์›ํ•  ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ mime ํƒ€์ž…์„ ์„ค์ •ํ•˜๊ณ , ์ถ”์ถœ๋œ ๊ฐ’์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ•˜๋‹ค.

MetadataExtractor๋Š” ์ง๋ ฌํ™”๋œ ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์™€์„œ ๋””์ฝ”๋”ฉํ•œ ์ด๋ฆ„-๊ฐ’(name-value) ์Œ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ด ๊ฐ’์€ ํ—ค๋”์ฒ˜๋Ÿผ ์ด๋ฆ„์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด, ํ•ธ๋“ค๋Ÿฌ ๋ฉ”์„œ๋“œ์— ์ ์šฉ๋œ @Header

DefaultMetadataExtractor์— ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋””์ฝ”๋”ฉํ•˜๊ธฐ ์œ„ํ•œ Decoder๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ String์œผ๋กœ ๋””์ฝ”๋”ฉํ•˜์—ฌ โ€œrouteโ€ ํ‚ค์— ์ €์žฅํ•˜๋Š” โ€œmessage/x.rsocket.routing.v0โ€ ์— ๋Œ€ํ•œ ์ง€์› ๊ธฐ๋Šฅ์ด ๋‚ด์žฅ๋˜์–ด ์žˆ๋‹ค. ๋‹ค๋ฅธ mime ํƒ€์ž…์˜ ๊ฒฝ์šฐ Decoder๋ฅผ ์ œ๊ณตํ•˜๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์ด mime ํƒ€์ž…์„ ๋“ฑ๋กํ•ด์•ผ ํ•œ๋‹ค.

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)๋Š” ๋…๋ฆฝ์ ์ธ ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ ๊ฐ’์„ ๊ฒฐํ•ฉํ•˜๋Š”๋ฐ ํšจ๊ณผ์ ์ด๋‹ค. ํ•˜์ง€๋งŒ ์š”์ฒญ์ž(requester)๊ฐ€ ๋ณตํ•ฉ ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด์„œ DefaultMetadataExtractor๋Š” ๋””์ฝ”๋”ฉํ•œ ๊ฐ’์„ ์ถœ๋ ฅ map์— ๋งคํ•‘ํ•˜๋Š” ์ปค์Šคํ…€ ๋กœ์ง์ด ํ•„์š”ํ•˜๋‹ค. ๋‹ค์Œ์€ ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ์— JSON์„ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์ œ๋‹ค:

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)
}

RSocketStrategies๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ MetadataExtractor๋ฅผ ์„ค์ •ํ•  ๋•Œ๋Š”, RSocketStrategies.Builder์—์„œ ์„ค์ •๋œ ๋””์ฝ”๋”๋กœ ์ถ”์ถœ์ž(extractor)๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ฝœ๋ฐฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋“ฑ๋ก ์ž‘์—…์„ ์ปค์Šคํ…€ํ•  ์ˆ˜ ์žˆ๋‹ค.

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()

๋ชฉ์ฐจ ๊ฐ€์ด๋“œ