-
-
Notifications
You must be signed in to change notification settings - Fork 98
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: add models for server object #497
refactor: add models for server object #497
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.
Welcome to AsyncAPI. Thanks a lot for creating your first pull request. Please check out our contributors guide useful for opening a pull request.
Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out this issue.
I am opening this for review, I think I am done with most of the work, will be adding tests now. |
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.
Good, but we need some improvements. Please @smoya look at my comments, because we probably should change Parser API.
src/models/asyncapi.ts
Outdated
servers(): Record<string, ServerInterface>; | ||
hasServers(): boolean; | ||
serverNames(): Array<string>; | ||
server(name: string): ServerInterface; |
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.
First one, we don't have such a hasServers
method in the https://github.com/asyncapi/parser-api/blob/master/docs/v1.md#asyncapidocument API.
Also I think that we should go with direction like in mixins with rest of methods:
hasServer(name: string): boolean;
servers(): ServerInterface[];
servers(name: string): ServerInterface | undefined;
you can check at example https://github.com/asyncapi/parser-js/blob/next-major/src/models/mixins/bindings.ts#L24
@smoya What do you think?
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 did an initial implementation in plain JS in this PR #453.
Btw, that PR is like a first implementation draft on the parser-api and we should stick as much as we can with it.
In particular, this is how we solve all the collection of models:
We create an intermediate model, in this case servers
which has some methods on it, like isEmpty()
.
You can see: https://github.com/asyncapi/parser-js/pull/453/files#diff-e871b9dd78d395cf3023273d1db969ee7638c3f5079fb1ac9323a921f46d6016
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.
Sorry I didn't know about that 😆
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.
Yeah, my bad. I created a new issue in parser-api to let parser-api to keep up with that implementation: asyncapi/parser-api#53
import { BaseModel } from "./base"; | ||
|
||
export interface ServerSecurityRequirementInterface extends BaseModel { | ||
|
||
} |
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.
ServerSecurityRequirementInterface
is unnecessary because it should not be a model, but only type https://github.com/asyncapi/spec/blob/master/spec/asyncapi.md#securityRequirementObject
src/models/server.ts
Outdated
url(): string; | ||
protocol(): string; | ||
protocolVersion(): string | ||
variables(): Record<string, ServerVariableInterface>; | ||
variable(name: string): ServerVariableInterface; | ||
hasVariables(): boolean; | ||
security(): [ServerSecurityRequirementInterface] | undefined; |
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.
url
and protocol
are required, rest of fields are optional, so they should return ... | undefined
.
Also I opt to have methods like:
hasVariables(): boolean;
hasVariables(name: string): boolean;
variables(): Record<string, ServerVariableInterface> | undefined;
variables(name: string): ServerVariableInterface | undefined;
cc @smoya
also type like [ServerSecurityRequirementInterface]
is a tuple, not array of the items.
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.
Please also read #497 (comment).
Intermediate models are the preferred solution (unless better alternative).
@Souvikns I'm not sure if I mentioned already, if not I'm so sorry, but @jonaslagoni and me did an initial implementation of the new Intent API but in the current plain javascript parser. It is here and has been through several iterations getting feedback: #453 So we would need to port that to TS "mainly". |
@smoya I didn't know about that 😆 |
…r-js into next/model-server
I have a question @smoya In Can you give me some insight on this? |
@Souvikns |
@magicmatatjahu I read asyncapi/spec#618 now this kind of makes sense, so are we following this proposal for v3 completely (I didn't read all the 77 comments kinda hard to track 😄 ). The Doubt I havewhy does the server have operations? what I get from reading asyncapi/spec#618 is operations is going to reuse channels how does |
@Souvikns At the moment you should only focus on 2.x.x not on 3.x.x (we don't have any merged PR for 3.x.x yet), so in the ^2.2.x versions you have |
@Souvikns But atm we don't have implemented operations and other needed models so please skip methods (create only signature) related to them, ok? |
@magicmatatjahu should I be waiting for this #499 since I think I need to use the |
@Souvikns As I know Sergio now is making review, so yes, please wait :) |
It is done, and there is no blocker for merging (there is one thing we can change later after merging). So it's just a fact of merging it now 🚀 |
Merged :) |
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.
Good, but some things don't work at all and need to be improved and some methods removed because they are unnecessary. I know, ParserAPI says something different, but ParserAPI needs to be changed in several places.
src/models/v2/server.ts
Outdated
id(): string { | ||
return this.json('id'); | ||
} |
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 had discussion in Slack that id
should not be a part of _json
:) I also gave you example how it should work - https://github.com/asyncapi/parser-js/blob/next-major/src/models/v2/mixins/extensions.ts#L11
id(): string { | |
return this.json('id'); | |
} | |
constructor( | |
private readonly _id: string, | |
_json: Record<string, any>, | |
) { | |
super(_json); | |
} | |
id(): string { | |
return this._id; | |
} |
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 did this because I modeled the utils function to convert object to array something like this
export function createArrayFromMap(json: Record<string,any>){
const ArrayObject = [];
for (const [key, value] of Object.entries(json)) {
value['id'] = key;
ArrayObject.push(value);
};
return ArrayObject;
}
so I thought maybe I don't need the add a separate id variable can just get it to format it. Main reason was so that the v2
and v3
have minimal changes, because to add seperate _id
parameter now we have to pass something like new Servers(id, this._json)
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.
v3 changes may be much bigger than they are now (to be honest we don't have anything approved so v3=v2 now), so please don't look at this proposal from Fran as something final.
About id
. Have in mind that if someone will run json()
should get the value that is defined for the object in the specification (not including traits because we have to combine them) without any additional fields that are not defined in the object, so what you want to get with adding the id
field is nothing more than changing the original json. I know that adding an id as an argument to a constructor can be weird, but in this case the id is outside the object, and in v3 it can be part of the object and it will be easier to handle.
src/models/v2/server.ts
Outdated
hasName(): boolean { | ||
return !!this.json('name'); | ||
} | ||
|
||
name(): string | undefined { | ||
return this.json('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.
@smoya what is the name
method in the server - https://github.com/asyncapi/parser-api/blob/master/docs/v1.md#server?
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.
The name
is the key in the map of servers. But I think we can change it to ID to be consistent?
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.
what is id
then?
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.
the key in the map of servers
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 name
and hasName
is out @Souvikns
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 then what is id
? I was thinking that id
is the key
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 makes sense to use id()
for all objects like Channel, Server, Operation, etc, instead of path()
for Channels, name
for Servers, etc
If we add a ID method for all of those models, no matter if we later change the source of them between versions.
I know the parser-api doesn’t reflect that but we learnt a lot during the last few months :)
I am getting code smell warnings from |
as I see, it's from my PR (weird that sonarcloud didn't check it on my PR). I will remove smells from my next PR, no worries. |
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.
Overall good, but I see that we have redundant unit tests and also in v2
version we have unnecessary methods. I create suggestions :)
@Souvikns Good, last thing because I see that sonarcloud fails on duplicated code - please create # Disable specific duplicate code since it would introduce more complexity to reduce it.
sonar.cpd.exclusions=src/models/**/*.ts and we can merge :) |
Kudos, SonarCloud Quality Gate passed! 0 Bugs No Coverage information |
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.
LGTM! Thanks for contribution! :)
/rtm |
Description
server
modelRelated issue(s)
Part of #482