-
Notifications
You must be signed in to change notification settings - Fork 40
Introduces reworked Payload API and new Metadata API #117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Introduce Metadata API Composite Metadata support Extensions Metadata support (Routing, Tracing, Auth, PerStream)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to try with a downstream project and give feedback then
@@ -51,6 +51,6 @@ suspend fun connectToApiUsingTCP(name: String): Api { | |||
|
|||
private fun connector(name: String): RSocketConnector = RSocketConnector { | |||
connectionConfig { | |||
setupPayload { Payload(name) } | |||
setupPayload { buildPayload { data(name) } } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why change this line. Seems simpler before
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Old Payload constructors were removed in favor of buildPayload
. They were really like example constructors
. F.e. in that particular case it was Payload(data: String, metadata: String? = null)
but for sure, such constructor will be needed in very small amount of cases. And f.e. upper I've used general buildPayload
to create such narrow case constructor.
So from user perspective, similar functions can be created per use cases they need
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's a matter of preference. I'd consider using buildPayload() when I want to incrementally build the payload like buildString(). But if I have the full content already ready, even allowing string -> byte conversions, I'd like Payload(...).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
main question for me is, Do we really need functions like Payload(String, String?)
?
anyway, may be it's better to change name of buildPayload
? to what? Payload {}
? not sure about this
Im not sure that a constructor per combination of data/metadata possible types is good.
So, if we want to support all cases with Payload
we need 15 functions for that to combine data=String|BRP|ByteArray and metadata=String|ByteArray|BRP|Metadata|null.
In current solution those constructors can be emulated on user side, if they use it frequently with 3-4 lines of code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was only asking for constructor for complete string or byte[] cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, will return back string/string and bytes/bytes functions
@@ -43,6 +45,8 @@ fun main() { | |||
|
|||
val rSocketServer = RSocketServer() | |||
|
|||
fun Payload.route(): String = metadata?.read(RoutingMetadata)?.tags?.first() ?: error("No route provided") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should put these as part of the public API for each specific domain via extension methods. Seems here it's a local helper we would duplicate a lot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why?
It's really local helper to get one route, for particular example. In real world, getting only first tag will not be enough I assume
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you gave the best example, for each domain there will be different conventions to use these. Rather that just providing access as a dictionary, it would be nice to have extension methods you can import to make it feel natural to each domain.
val tm: ZipkinTracingMetadata = cm.get(ZipkinTracingMetadata) | ||
|
||
//or | ||
val rm1: RoutingMetadata = cm[RoutingMetadata] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think examples like this are better through well known extension methods
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain a little?
Or, show better example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cm.route()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so, you propose to add something like val Payload.routingMetadata: RoutingMetadata
or fun Payload.routingMetadata(): RoutingMetadata
which can be read once, right?
and same accessors for other out-of-the-box metadatas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it's weird on Payload, but as an extension method you choose to import it.
Also the domain specific helper could hide any logic to check is CompositeMetadata vs single (non-composite) types, or potentially include defaults that make sense for that type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks ok, will add it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not overthink it. Let's land and iterate for now. I use the routing rules from client side, so let's see that in the context of rsocket-cli and my own project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, So may be, let's merge it now and you will check it
If so, we can at least release 0.11.0 with those changes already done
and continues with incremental releases per feature
More attention on mime-types,
payload
andmetadata
packages and tests for them