Closed damaru-inc closed 9 months ago
the "verb confusion" would remain, true: it can only be resolved by a backwards-incompatible renaming: trivial to do and trivial to automate "upgrade" tooling for AsyncAPI docs.
but it seems that all other restrictions of the v2 spec can be resolved by introducing fully backwards-compatible relaxations of what's required (say,
channel
) and what can be referenced via an$ref
rather than having to be specified there-and-then by containment (similar to how #531 relaxes the association between channels and servers in a backwards-compatible way).
@GeraldLoeffler, thanks, I think I understand what you're getting at. It seems very similar to @jhigginbotham suggestion as well. Let me spend some time today working through the implications and writing up some examples to solidify things a bit more in my mind.
It's helpful to understand what's "easy" and "hard" in terms of breaking changes. @nictownsend and @dalelane , how much would changing publish
to sends
(or something similar) and subscribe
to receives
(or something similar) affect your product?
how much would changing publish to sends (or something similar) and subscribe to receives (or something similar) affect your product?
Breaking changes in the spec can definitely be accounted for
It may not be your intent, but note that a channel is not necessarily constrained to a particular message schema. Yes, the DataType Channel pattern would constrain a channel to a single message type, but I don't think that AsyncAPI should constrain to just one type.
I agree with @iancooper that we shouldn't constrain a channel to one data type. This is particularly important with Avro over Kafka, where LightMeasured v1 schema and LightMeasured v2 schema might both be presented on the same topic.
However, I do think for decoupling purposes, data types should be properties of the channel, not the endpoint. If the purpose of a channel is to eliminate dependencies between information providers and information consumers, forcing consumers to determine what datatypes each provider sends would undermine that.
This is particularly important with Avro over Kafka, where LightMeasured v1 schema and LightMeasured v2 schema might both be presented on the same topic.
Interesting point, as that brings up the definition of a channel and message type, including their relationship cardinality.
Clarifying these definitions and providing copious examples will likely clarify intent across this discussion, avoid confusion in the future, and lay the groundwork for future spec documentation + examples. It sounds like a few people are doing that now, so as part of the work, I'd recommend defining what you mean with each term introduced to ensure alignment as part of the write-ups and examples being produced. In some cases, we may end up talking about the same thing, but in other cases we may be using the words in different contexts.
@GeraldLoeffler So, I've been trying to piece together an example. I think there is general agreement that publish and subscribe are not generic enough for all async use cases. You suggested replace subscribe
with applicationSent
replace publish
with applicationReceived
. Based on @iancooper 's [helpful suggestion] (https://github.com/asyncapi/spec/issues/390#issuecomment-884269174) , I've taken the liberty of changing them to endpointSends
and endpointReceives
The as-is API representation of the Streetlights Control Hub then becomes:
channels:
light/measured:
endpointSends: #breaking change
summary: Inform about environmental lighting conditions for a particular streetlight.
operationId: onLightMeasured
message:
name: LightMeasured
control/lightOn:
endpointReceives: #breaking change
summary: Commands lights on
operationId: lightOn
message:
name: LightControl
In this use, it is assumed the API describes:
In other words, the endpoint may choose tosend onLightMeasured
events, and may choose to receive controlLightOn
commands. (I find this still to be a bit of mental gymnastics, but maybe that's just me.) It sounds like for your use case, those are appropriate assumptions.
For those with different assumptions, requirements, use cases and/or perspectives, in proposed v3 it becomes possible--though not mandatory--to explicitly create endpoints and/or classes of endpoints.
endpoint:
StreetLight:
endpointSends:
light/measured
$ref: /uri/channels/light/measured
endpointReceives:
control/lightOn
$ref: /uri/channels/control/lightOn
channels:
light/measured:
message:
name: LightMeasured
control/lightOn:
message:
name: LightControl
In the optional v3 usage the API describes how either
intent:implementation
)intent:interface
)To accomplish this--and this basically just restating @GeraldLoeffler--:
publish
to endpointSends
, subscribe
to endpointReceives
(breaking)As @iancooper stated, the devil is in the details, but this seems like a way to make the spec evolve towards more enterprise functionality, while (mostly) maintaining backwards compatibility through reasonable assumptions. However, I'd be interested in the opinions of those making tooling. Does having this flexibility make it harder/impossible to generate code, for instance?
To make the issue title better reflective of the primary topic of conversation, I have opened a new issue centered on the endpoint
proposal
Leaving here the discussion @dalelane and I had during the last ThinkingOutLoud episode: https://youtu.be/Qsu_yC-5YYM?t=64. I hope it serves as a basement for those who are still reluctant to get involved in the discussion.
Also, please if you think your proposal is very different from this one submit a new one separately as @jmenning-solace did with #599 🙏 Just so the discussion is easier to follow. I'm tracking all of them on #520.
Yo folks. As a result of the Thinking Out Loud episodes, I've come up with a proposal of how to solve this problem. Hope it makes sense and captures the feedback and ideas that y'all gave me: https://github.com/asyncapi/spec/issues/618.
The specification regards publishing and subscribing from the point of view of what a client is allowed to do. For example, if the spec has a publish operation, then applications will actually be subscribing. This is consistent with OpenAPI server side code, where if one sees a GET, it is not the server that does the GET but rather other applications.
However some users of AsyncAPI find it more intuitive to consider things from the opposite perspective. If they have a document with a publish operation and want to generate code, they expect that the code will publish, not subscribe.
I propose adding a parameter called 'view' that can have two values:
'client' - this is consistent with the current specification. It means that the document says what a client of the application can do. 'provider' - this means that the document describes what the provider of the service is doing, i.e. a subscribe operation means that the application is subscribing.
Can't it be tackled using specification extensions? It can be done using specification extensions, but so far there are three generator templates using their own extensions and terminology - it would be nice to make this consistent.
Describe the solution you'd like I would like to see an addition to the info section that supports this parameter, e.g.
Describe alternatives you've considered The java-spring-cloud-stream and paho-python templates currently support this through the use of specification extentions and parameters. The java-template also has this feature but uses different terminology.