Skip to content
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

feat: allow servers and channels to be fetched from components #430

Merged

Conversation

smoya
Copy link
Member

@smoya smoya commented Dec 16, 2021

Note that this PR is targeting asyncapi:2022-01-release branch, so merging it won't release a new version.

Description
This PR is part of asyncapi/spec#660.
It allows both servers and channels to be retrieved from components, meaning the following will be now valid:

servers:
  production:
    $ref: '#/components/servers/myserver'
channels:
  some/events:
    $ref: '#/components/channels/myChannel'
components:
  servers:
    myserver:
      url: "http://localhost:5000/ws"
      protocol: ws
  channels:
    myChannel:
      description: "mychannel"

Related issue(s)
asyncapi/spec#660

@smoya smoya changed the base branch from master to 2022-01-release December 16, 2021 16:58
Copy link

@github-actions github-actions bot left a 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.

@smoya smoya force-pushed the feat/serversChannelsAsComponents branch from 04309f5 to 2094035 Compare December 16, 2021 17:04
@smoya smoya marked this pull request as ready for review December 16, 2021 17:06
@smoya smoya changed the title feat: allow servers and channels as components feat: allow servers and channels to be fetched from components Dec 16, 2021

if (this.hasComponents()) {
Object.entries(this.components().channels()).forEach(([key, value]) => {
// TODO This means that if two channels have the same name (but located in different place), the first one will be overwritten.
Copy link
Member Author

@smoya smoya Dec 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps the assumption is wrong? Am I missing something?

This code is based on current allMessages() function code

WDYT about this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Messages as saved with uid based on

return this.name() || this.ext('x-parser-message-name') || Buffer.from(JSON.stringify(this._json)).toString('base64');
so you can end with overrides. Hmm 🤔 In the case of channels you should name it with url path, so you can end with duplication but I think that your spec will be invalid - I mean two url for that same event - so here we can accept your solution.

In the case of servers, we should collect them by urls, not by names, because in components and servers they may have different names but they will be the same servers. It would be best to add servers from the #/servers section first and then check the url of servers from #/components/servers to see if such a server already exists, if it does then don't add the new item to the Map :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having the following example doc:

asyncapi: 2.2.0
info:
  title: test
  version: 1.0.0
servers:
  test:
    url: 'test.asyncapi.com'
    protocol: ws
channels:
  /:
    subscribe:
      message:
        $ref: '#/components/messages/testMessage'
components:
  messages:
    testMessage: {}
  channels:
    /: 
      publish:
        message:
          $ref: '#/components/messages/testMessage'

Don't you think we should keep both / channels instead of overwriting one of them? They can be totally different channels. As channels don't have any extra property such name or id (related asyncapi/spec#614) I don't think we should overwrite them.

And I would say the same issue happens with servers if we consider a same URL can be used for let's say different protocols, URL field is not enough for making a server unique.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe it should be delegated to the spec, and spec should require unique names for server and channel across document, as it is with correlationId?

@fmvilas thoughts? it is related to asyncapi/spec#660

Copy link
Member Author

@smoya smoya Dec 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding implementation here... From what I see, two servers will be equal only if all their properties are equal. Using only URL field is not enough because you can have two servers with the same URL but different protocols.

Does it make sense to compare the whole object to determine if they should be merged? What should we do if they are not equal but share the same name? Shall we use some kinda prefix? cc @derberg @magicmatatjahu

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with Lukasz. I'd not add them for now. Let's make sure this is considered for v3 and then we can work back a solution for v2.x documents.

Copy link
Member Author

@smoya smoya Jan 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that since there is code already that uses asyncapi.allMessages() this is needed. See https:/search?q=org%3Aasyncapi+asyncapi.allMessages%28%29&type=code. Maybe those templates don't need that method and they should change their call to asyncapi.Messages()? Not sure, maybe you @magicmatatjahu or @derberg or @fmvilas can answer that.

In fact, if we move forward, I realize now I would need to create a PR on those repositories changing all asyncapi.Channels() to asyncapi.AllChannels() and the same for servers then.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you rephrase your question? I did not get it.

allMessages is indeed needed, so this is why it was added and is used in templates. This should stay as it is. There is a use case for it, as some folks simply do not use channels, and have messages only under components.

What we mean here is that Servers and Channels are new. We know we need to access them using regular helpers. So technically speaking, we need to have Servers and Channels part of Components model as you did it in this PR, and we can drop allChannels and allServers implementation for now, as it is nice to have, and can be added later when we really need it.

I tried to answer your questions without clarification from your side, but I'm not 100% sure I did it? Thoughts?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I didn't think we could access those channels and servers without those new methods but indeed you can always get them via asyncapi.components(). Then I agree it is fine to drop those new methods.

I tried to answer your questions without clarification from your side, but I'm not 100% sure I did it? Thoughts?

Yes you did 👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok @magicmatatjahu @fmvilas @derberg allChannels and allServers functions has been removed from my PR now.

@smoya smoya force-pushed the feat/serversChannelsAsComponents branch from 2094035 to 5bae790 Compare December 28, 2021 11:29
@derberg
Copy link
Member

derberg commented Dec 28, 2021

/help

@asyncapi-bot
Copy link
Contributor

Hello, @derberg! 👋🏼

I'm Genie from the magic lamp. Looks like somebody needs a hand! 🆘

At the moment the following comments are supported in pull requests:

  • /ready-to-merge or /rtm - This comment will trigger automerge of PR in case all required checks are green, approvals in place and do-not-merge label is not added
  • /do-not-merge or /dnm - This comment will block automerging even if all conditions are met and ready-to-merge label is added

@derberg
Copy link
Member

derberg commented Jan 3, 2022

2 more comments from my side, before you merge, do not forget:

  • we do not update bundle on PR, but it will be anyway overwritten during release so maybe we can ignore
  • remember to bump spec schema dependency to the release candidate before merging

@smoya
Copy link
Member Author

smoya commented Jan 5, 2022

  • remember to bump spec schema dependency to the release candidate before merging

Done:

"@asyncapi/specs": "asyncapi/spec-json-schemas#2022-01-release",

we do not update bundle on PR, but it will be anyway overwritten during release so maybe we can ignore

We can leave it here right? Or should I remove it?

@fmvilas
Copy link
Member

fmvilas commented Jan 7, 2022

We can leave it here right? Or should I remove it?

I'd remove it as it could be a source of git conflicts.

@smoya
Copy link
Member Author

smoya commented Jan 7, 2022

We can leave it here right? Or should I remove it?

I'd remove it as it could be a source of git conflicts.

It's done!

Copy link
Member

@fmvilas fmvilas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

package.json Outdated
@@ -67,7 +67,7 @@
},
"dependencies": {
"@apidevtools/json-schema-ref-parser": "^9.0.6",
"@asyncapi/specs": "^2.11.0",
"@asyncapi/specs": "asyncapi/spec-json-schemas#2022-01-release",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fmvilas are you sure we should grab sources from github?
imho we should either pull a specific version from npm 2.13.0-2022-01-release.1 or just fix to the release candidate tag, so 2022-01-release

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: If we use 2022-01-release as version, it will point to the same code as latest commit in that branch? So it is the same as I added but pointing to the npm package tag instead of github branch, right? If so, I can change to it as IMHO it also makes sense as you said.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

technically if you point to 2022-01-release and you do npm install then @asyncapi/specs version 2.13.0-2022-01-release.1 will be installed, if 2 release candidate is available, then 2.13.0-2022-01-release.2 will be installed.

so yeah, might be that the best solution is to point to the 2022-01-release npm tag instead of a specific version each time

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's done!

@smoya smoya requested review from derberg and fmvilas January 12, 2022 10:58
Copy link
Member

@derberg derberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/dnm

@derberg
Copy link
Member

derberg commented Jan 13, 2022

@smoya yo, https:/asyncapi/spec-json-schemas/releases/tag/v2.13.0-2022-01-release.3 is out, so you either need to just regenerate package-json or in package.json also point directly to v2.13.0-2022-01-release.3, more intuitive and straightforward indicator that this needs to be updated with every release candidate

@smoya
Copy link
Member Author

smoya commented Jan 13, 2022

@smoya yo, https:/asyncapi/spec-json-schemas/releases/tag/v2.13.0-2022-01-release.3 is out, so you either need to just regenerate package-json or in package.json also point directly to v2.13.0-2022-01-release.3, more intuitive and straightforward indicator that this needs to be updated with every release candidate

@asyncapi/specs updated to v2.13.0-2022-01-release.3 is now a thing 🚀

@sonarcloud
Copy link

sonarcloud bot commented Jan 13, 2022

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

@derberg
Copy link
Member

derberg commented Jan 13, 2022

/rtm

@asyncapi-bot asyncapi-bot merged commit 2f465bb into asyncapi:2022-01-release Jan 13, 2022
@smoya smoya deleted the feat/serversChannelsAsComponents branch January 13, 2022 11:21
@asyncapi-bot
Copy link
Contributor

🎉 This PR is included in version 1.14.0-2022-01-release.2 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants