rsocket / rsocket-kotlin

RSocket Kotlin multi-platform implementation
http://rsocket.io
Apache License 2.0
547 stars 37 forks source link

Kotlinx.serialization integration for payload #112

Open whyoleg opened 3 years ago

whyoleg commented 3 years ago

It would be good to provide out of the box integration with kotlinx.serialization for serializing models into payload data (is metadata serialization needed?). kotlinx.serialization supports both binary formats such as CBOR and ProtoBuf, and string JSON format (and other custom community driven formats). Possible implementations:

  1. reading value from payload: format.decodeFromPayload<ModelType>(payload) where: ModelType - resulting type (should be annotated with Serializable annotation), format - JSON/ProtoBuf/CBOR format (or any other custom format)
  2. writing value to payload: format.encodeToPayload(model, [optional metadata]) where model - entity to serialize, format - supported format
  3. typed interface for interactions (for requester): fun <T, R> requestResponse(data: R, metadata: ???): TypedPayload<R> where: T - type of request data, R - type of respose data, TypedPayload - payload, which contains data as type R and metadata
  4. something else ???
yschimke commented 3 years ago

+1 That's quite nice. Metadata serialization is important, I assume you mean independently from the data.

whyoleg commented 3 years ago

Metadata serialization is important

If so, we will need to integrate it somehow with future composite metadata support, and also 3 point become harder to design right API. As first step, serialization to ByteReadPacket will be good:

  1. read: format.decodeFromPacket<ModelType>(payload.data) and format.decodeFromPacket<ModelType>(payload.metadata)
  2. write: Payload(format.encodeToPacket(dataModel), mayBeAnotherFormat.encodeToPacket(metadataModel))
yschimke commented 3 years ago

"future composite metadata support" - that was my point. I'm finding that I'm needing to serialize with the rsocket-java code, and porting that looks like not much fun. Ideally we would have nice kotlin support for routing, tracing etc. But maybe these can't be converged?

whyoleg commented 3 years ago

Composite metadata support is my next task in todo list (together with extension metadatas like routing, tracing, auth). Will look later if it's possible to combine them in nicer way, than in my previous message.

OlegDokuka commented 3 years ago

+1. The API proposal looks good to me as well!

yschimke commented 3 years ago

This is the metadata section that's quite awkward for me (but discrete thankfully).

https://github.com/rsocket/rsocket-cli/blob/a8f29f05e1195f500d34b3d6cae4f0f5a77ada07/src/main/kotlin/io/rsocket/cli/Main.kt#L211-L218

    this.route != null -> {
      val compositeByteBuf = CompositeByteBuf(ByteBufAllocator.DEFAULT, false, 1)
      val routingMetadata = TaggingMetadataCodec.createRoutingMetadata(ByteBufAllocator.DEFAULT, listOf(route))
      CompositeMetadataCodec.encodeAndAddMetadata(compositeByteBuf, ByteBufAllocator.DEFAULT,
        WellKnownMimeType.MESSAGE_RSOCKET_ROUTING, routingMetadata.content)
      ByteBufUtil.getBytes(compositeByteBuf)
    }