-
-
Notifications
You must be signed in to change notification settings - Fork 99
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
refactor: interface and implementations for each major spec version #488
Conversation
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 see places to improve :)
src/models/v2/info.ts
Outdated
contact(): V2Contact | undefined { | ||
const doc = this.json("contact"); | ||
return doc && new V2Contact(doc); | ||
} | ||
|
||
license(): V2License | undefined { | ||
const doc = this.json("license"); | ||
return doc && new V2License(doc); | ||
} |
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.
contact()
should return ContactInterface
not V2Contact
etc
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.
It seems it is not necessary to do that since the returned type already implements the interface.
I'm coming from Go land, where it is standard to return the implementation types rather than the interface ones (even though from my point of view, I could find pros and cons in all ways).
I couldn't find examples of this in TS besides a few. I'm happy to change it if you consider it should be done.
What I understand for spec version |
I'm not a fan of calling things v2 v3 etc. of course we can and should have aliases, but the classes themselves can be called // mdoels/v2/contact.ts
export class Contact extends BaseModel implements ContactInterface {
...
}
export { Contact as ContactV2 }
// models/v2/index.ts
export { ContactV2 } from './contact';
// models/index.ts
export * from './v2'; and of course please write single factory to show how we should handle different classes across versions. I more or less know, but this will help other people :) That's all I have so far and I don't see any other problems. I like the idea and if something will be wrong, we will change it in the code :) |
This is a thing now |
The Interface will not change as far as https://github.com/asyncapi/parser-api/blob/master/docs/v1.md doesn't change. |
Kudos, SonarCloud Quality Gate passed! |
I finally implemented this change as it also will help reusing code later on. |
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.
Awesome! I don't see any problems, now 😆 Of course the errors themselves (their description) need to be improved, but it's not the most important thing right now :)
🚀
/rtm |
Description
The new Intent-driven API is made for keeping retro compatibility and also avoiding breaking changes as much as we can.
This means we should use the same API interface, but keep implementation logic that can differ between different AsyncAPI Spec versions.
This
POCis just one suggestion on how we can handle that in the most simple way, avoiding error-prone solutions, overengineered and/or unmaintainable code.My suggestion is about creating interfaces (actually TypeScript Interfaces) for all the models required for implementing the Intent-Driven API (See https://github.com/asyncapi/parser-api/blob/master/docs/v1.md).
Then, implementation classes per each major AsyncAPI Version, e.g.
v2
,v3
, etc.The code changed on this PR tries to illustrate that, having the interfaces located at
src/models
and all implementations under a directory, e.g.src/models/v2
andsrc/models/v3
, meaning v2.x and v3.x spec major versions respectively.For using one model or the other, we would just need to implement a factory pattern in a function that, based on the version of the provided AsyncAPI document when calling the parse method, will instantiate one or another model. That's all since the interface will be always the same, the only thing that changes is the implementation.
PROS
CONS
I would like to know WDYT about it. cc @magicmatatjahu @Souvikns @jonaslagoni
Related issue(s)