-
-
Notifications
You must be signed in to change notification settings - Fork 11
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
Proposal for extensions and protocolInfo objects versioning #1
Comments
@fmvilas Regarding non-object extensions, such as your x-twitter example, would it be better to have an extensions section in the asyncapi definition that provides the extension prefix(es) used, e.g. x-twitter, the version of the extension, and the URL to the extension spec? That way, you don't have to provide it inline (especially if you use the extension more than once within a given asyncapi file). +1 for expanded names, such as protocolVersion, extensionVersion, etc. whenever possible to avoid confusion by authors and consumers of the definition file. |
That sounds good. I wonder if we lose reusability (across documents) if we have an extensions section. Can you provide an example of your vision? |
Versioning
If a new version of
This makes it clear that the kafka protocol has version The Re-use
Literals In this case an extension would always have to be an object since you want to allow for the possibility of versioning. Like so:
Then with versioning:
Benefits/Costs
Cons
Personally I believe that giving up the ability to define extensions as literals is minor compared to what is gained through versioning. |
@RobertDiebels I see what you mean but let me clarify something: Specification extensions ( asyncapi: '2.0.0'
info:
x-twitter: '@PermittedSoc' Then we have the protocolInfo extensions which are protocol-specific and they don't start by That said, Hope it helps clarify the challenge. Thanks! |
This cons must be avoided to keep compatibility between OpenAPI and AsyncAPI extensions, and also backward compatibility with AsyncAPI 1.x extensions. |
I'd rather prefer to have something like the following: "if your extension doesn't have a metadata key (and it includes strings, like the Twitter one) then we assume you're using the latest definition available." If you want to avoid the (sometimes undesirable) effect of getting the latest version, change the extension format to an object. That's the trade-off. |
Understood. My proposal would be to add the
Can you elaborate on the need to keep compatibility with OpenAPI extensions?
I thought this change to the spec concerns 2.0 so adding a breaking change wouldn't be an issue.
Seems fair.
So that would be off-loading the decision to the extensions' maintainer. Seems good to me 👍 . One other pro I could think of like this is that the parser can avoid having to check each key for the |
Companies and tooling are already using their own extensions in OpenAPI. We want people to use their existing extensions on AsyncAPI too, if that makes sense for them. For instance, the Twitter one is one of these cases.
Yes, we can add breaking changes, and we could provide migration scripts to migrate from version 1.x to version 2. However, this decision is causing breaking changes on user extensions and not much on our side. If we think this is something we really need to do, that's fine, but I think we can avoid it.
It's not that "we can't" but let's think on the user experience first, and they will want to reuse as much as possible. That's why we keep the compatibility with OpenAPI schemas in version 2. |
On second thought. That might not be the best. Consider this: If you're working with a team and team-member A uses the same spec team-member B. However, team-member B is performing a fresh tooling run and suddenly nothing is working due to the using the latest version of a Maybe adding an extensions section would be best.
So it's not so much about adding a
Seems good to me 👍 .
In this case that would be the extensions being defined as a |
I don't see how an extensions section would solve this problem. You still have to create another extension that's not just a string. Am I missing something?
Users can define extensions with the value they'd prefer. It's an opaque value for us and should remain the same unless the user explicitly wants to validate some of them. Another example could be an extension called Specification extensions ( |
No you're correct. I meant an extensions section such as @jhigginbotham proposed. I should have been clearer about that.
What I meant was that in essence you have 2 options, an object or a literal. In language parsing a literal means any token representing a concrete value. Like you said:
In that case adding a That would leave only @jhigginbotham 's proposal of adding an extensions section and adding any metadata there. |
Correct. That's why I wanted to use a name like x-my-extension:
_meta:
version: 0.1.0
Yes. My fear with this solution is that we may reduce the "portability" of extensions but it's a great solution in any case. We can consider that version is "latest" if it's not found in the extensions section. Or we just ignore them. We have to define the behavior in this case. |
@fmvilas I'd suggest to try and avoid using As an example, in the past I've had some problems with implicit versioning where I couldn't find the cause of an issue in an NPM package. It ended up being caused by a |
I understand your concern but this is a problem that appears when you have dependencies of dependencies. In this case, there's only one level and you're the one specifying what versions you want. If you're concerned about it, just don't use wildcards ("x.x" or anything similar), but it can be useful many other times. |
@fmvilas This is a problem when you have dependencies. If the spec contains a dependency on an extension and suddenly the extensions' version is increased by a major version, due to the latest tag being moved, users will have a different output even-though they didn't alter their spec. It's not so much about using wildcards. It's about implicit versions causing unexpected behavior. That's why I suggested the warning or error message if a version hasn't been provided. |
Sorry for the confusion. I meant the problem with "x.x" you mentioned. If the parser should trigger an error, ignore it or download the latest version, is something that we can put in the parser as an option, and we let people decide. |
No problem. I could have been a tad clearer.
That would help tremendously. In the end users would benefit from it since their specs won't have any unexpected behavior. Or at the very least they would know about the possibility of the spec possibly exhibiting unexpected behavior. |
This issue has been automatically marked as stale because it has not had recent activity 😴 |
closing for now catalog is super simplified now, as binding, any other improvements can be pushed but when there is really a dedicated person that can work on it, own discussion and lead till the end |
After thinking thoroughly about extensions and protocolInfo objects and their schemas, this is the proposal I have.
Context
AsyncAPI (and also OpenAPI) allows you to annotate your document with properties starting by
x-
and whose values can be anything. We now want to provide a catalog of extensions but we MUST not break this "freedom".In version 2, we introduced "protocol info" objects. They are also treated as extensions but, unlike the other ones, they can only live inside the
protocolInfo
object. They consist of a key (e.g.,kafka
) and a value of type object. The value will contain protocol-specific information.Problem
We'll want to iterate on extensions independently, i.e., without having to release a new AsyncAPI specification version. Therefore, when using an extension inside an AsyncAPI document, we should have the possibility to specify the version of the extension we're using.
As an example, if we have the following definition:
We're saying that, when using Kafka, we want the code to subscribe using
my-client-id
as the Client Id. Thiskafka
protocolInfo object is validated using the following (simplified) schema:However, after some time, our extension is growing a lot and we want to reorganize the fields in the
kafka
object as follows:And the new schema is the following:
This is a breaking change so, suddenly, we would be breaking the workflow for these people using the Kafka protocolInfo extension. This is an undesirable side-effect we can avoid by specifying a version string in the extension:
Note this version is the version of the extension, not the Kafka version.
It seems clear we need a version strategy, however, while this is fine for protocolInfo extensions, it might not be the case for specification extensions, because they may not be of type "object". Consider the following example:
In this case, we can't add the version (
_v: 'x.x.x'
). Even more, specification extensions do not have to follow our formatting. Remember they are free-form values and they may not be in our catalog or people just don't want to validate them at all.Solution
For specification extensions, we assume the following:
_v
) is omitted and the extension is in our catalog, we MUST perform validation against the "latest" version of the extension._v
) is omitted and the tooling provides the definition, we MUST perform validation against the provided extension definition._v
) is provided and the extension is in our catalog, we MUST perform validation against the provided version of the extension._v
) is provided and the tooling provides the definition for another version, we MUST NOT perform validation on the extension.For protocolInfo extensions, we assume the following:
_v
) is mandatory.Open questions
_v
? Another options:_version
,version
,extension_version
,_extension_version
. Please, take into account that protocolInfo extensions may have to use theversion
field for the protocol version. I personally prefer the_v
name because 1) it starts with an underscore and makes it look like something special or "meta"; and 2) it's short and not similar toversion
._v
field? E.g.,1.3.x
,1.x
,*
,latest
, etc.The text was updated successfully, but these errors were encountered: