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: unify all referencing mechanisms #852

Merged

Conversation

fmvilas
Copy link
Member

@fmvilas fmvilas commented Oct 13, 2022

Description

This PR unifies all the referencing mechanisms in the spec. So far, only the security requirements object had to be changed.

Related issues

#829

@sonarcloud
Copy link

sonarcloud bot commented Oct 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

@@ -373,7 +372,7 @@ Field Name | Type | Description
<a name="serverObjectProtocolVersion"></a>protocolVersion | `string` | The version of the protocol used for connection. For instance: AMQP `0.9.1`, HTTP `2.0`, Kafka `1.0.0`, etc.
<a name="serverObjectDescription"></a>description | `string` | An optional string describing the host designated by the URL. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation.
<a name="serverObjectVariables"></a>variables | Map[`string`, [Server Variable Object](#serverVariableObject) \| [Reference Object](#referenceObject)]] | A map between a variable name and its value. The value is used for substitution in the server's URL template.
<a name="serverObjectSecurity"></a>security | [[Security Requirement Object](#securityRequirementObject)] | A declaration of which security mechanisms can be used with this server. The list of values includes alternative security requirement objects that can be used. Only one of the security requirement objects need to be satisfied to authorize a connection or operation.
<a name="serverObjectSecurity"></a>security | [[Security Scheme Object](#securitySchemeObject) \| [Reference Object](#referenceObject)] | A declaration of which security schemes can be used with this server. The list of values includes alternative [security scheme objects](#securitySchemeObject) that can be used. Only one of the security scheme objects need to be satisfied to authorize a connection or operation.
Copy link
Member Author

Choose a reason for hiding this comment

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

Instead of having a weird syntax like:

security:
  - httpBearerToken: []

My proposal is that we do the following:

...
  security:
    - $ref: '#/components/securitySchemes/httpBearerToken'
...  
components:
  securitySchemes:
    httpBearerToken:
      type: http
      scheme: bearer

The array of the current syntax is just for OAuth2 and OpenIDConnect schemes so I created a new property called scopes in the Security Scheme Object. These will be the mandatory scopes needed to connect or perform an operation. It offers less reusability in the security property but you can anyway create as many Security Scheme Objects inside components so, yeah, not an issue.

Copy link
Sponsor Member

Choose a reason for hiding this comment

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

I like it!

Copy link
Member

Choose a reason for hiding this comment

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

Consider that in the security field we have 3 options:

  • defining one security (as in your case)

  • defining several security that must be met at once:

    ...
    security: 
      - - $ref: '#/components/securitySchemes/1schema'
        - $ref: '#/components/securitySchemes/2schema'
  • defining several security, for which only one security must be satisfied.

    ...
    security: 
      - $ref: '#/components/securitySchemes/1schema'
      - $ref: '#/components/securitySchemes/2schema'

So as you can see, we have problem with second case (several securities have to met at once). We have even issue for that #828

Copy link
Member

Choose a reason for hiding this comment

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

The array of the current syntax is just for OAuth2 and OpenIDConnect schemes so I created a new property called scopes in the Security Scheme Object. These will be the mandatory scopes needed to connect or perform an operation. It offers less reusability in the security property but you can anyway create as many Security Scheme Objects inside components so, yeah, not an issue.

Why not to create security item shape as:

security: 
  - scheme:
       $ref: '#/components/securitySchemes/1schema'
    scopes: [...]

?

Copy link
Member Author

Choose a reason for hiding this comment

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

Why not to create security item shape as:

security: 
  - scheme:
       $ref: '#/components/securitySchemes/1schema'
    scopes: [...]

?

Why should we? :) The proposed syntax looks much cleaner IMHO. It only has the problem of meeting multiple security schemes at once but I'm not sure it should be a requirement. Left a comment at #828 (comment).

Copy link
Sponsor Member

Choose a reason for hiding this comment

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

As I remember, we have issue for that (or mention about it in another issue, I don't know), but I'm not involving with it. cc @smoya

@magicmatatjahu you raised it as thoughts here: #778 (comment)

I don't think it has been discussed anywhere else 🧐

Or are we planning not to support merging an object when using $ref alongside other properties?

It's not that we are planning not to support it, but we have not planned or had a discussion about whether that should be a feature I think 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

Interesting. So maybe it's time to have it 😄 This could simplify life in cases like this. And tooling is already behaving this way, I think.

Copy link
Sponsor Member

Choose a reason for hiding this comment

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

And tooling is already behaving this way, I think.

That is only because the tooling has bugs, it is not intended behavior... 🙂

Adding this functionality will definitely complicate it from a spec perspective, but yea simplify it in this case 😆

Copy link
Member Author

Choose a reason for hiding this comment

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

Bug or feature? 😛 To be honest, this is a thing I see many people doing/trying expecting it to work. But yeah, that's not a discussion for this thread sorry for the noise.

Choose a reason for hiding this comment

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

I strongly encourage folks to file thoughts around potential reference merging in AsyncAPI as issues at the unified referencing discussion repo, where we can consider them alongside, for example, the limited merging of summary and description that OpenAPI 3.1 does outside of JSON Schema references.

This wouldn't mean AsyncAPI is blocked from taking other action, but unified referencing will only be unified if we know what's going on with each project.

"description": "This environment is meant for developers to run their own tests"
}
]
"url": "{username}.gigantic-server.com:{port}/{basePath}",
Copy link
Member Author

Choose a reason for hiding this comment

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

Here I'm just removing context information in the example. Just to keep it the same as in the rest of the spec.

@@ -2442,106 +2401,32 @@ Field Name | Type | Applies To | Description
<a name="oauthFlowAuthorizationUrl"></a>authorizationUrl | `string` | `oauth2` (`"implicit"`, `"authorizationCode"`) | **REQUIRED**. The authorization URL to be used for this flow. This MUST be in the form of an absolute URL.
<a name="oauthFlowTokenUrl"></a>tokenUrl | `string` | `oauth2` (`"password"`, `"clientCredentials"`, `"authorizationCode"`) | **REQUIRED**. The token URL to be used for this flow. This MUST be in the form of an absolute URL.
<a name="oauthFlowRefreshUrl"></a>refreshUrl | `string` | `oauth2` | The URL to be used for obtaining refresh tokens. This MUST be in the form of an absolute URL.
<a name="oauthFlowScopes"></a>scopes | Map[`string`, `string`] | `oauth2` | **REQUIRED**. The available scopes for the OAuth2 security scheme. A map between the scope name and a short description for it.
<a name="oauthFlowScopes"></a>availableScopes | Map[`string`, `string`] | `oauth2` | **REQUIRED**. The available scopes for the OAuth2 security scheme. A map between the scope name and a short description for it.
Copy link
Member Author

Choose a reason for hiding this comment

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

Renaming the scopes property of the OAuthFlow Object to availableScopes to differentiate from the other one added in this PR.

@fmvilas
Copy link
Member Author

fmvilas commented Dec 17, 2022

@derberg @dalelane @char0n @magicmatatjahu @jonaslagoni would you mind having a look and approving if you like it? I want to start getting rid of these small PRs.

@fmvilas fmvilas added the 💡 Proposal (RFC 1) RFC Stage 1 (See CONTRIBUTING.md) label Dec 17, 2022
Copy link

@handrews handrews left a comment

Choose a reason for hiding this comment

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

This consistency is great to see!

Is discriminator being considered as well? It uses property values as implicit references. I believe OpenAPI 4 is likely to deprecate it in favor of JSON Schema's forthcoming propertyDependencies (which uses $ref normally). So that would be one option (even with AsyncAPI 3.0 staying on draft-07, you could import that keyword as an extension in place of discriminator).

BTW, I am not demanding that it be addressed in this PR or this release, I'm just pointing out that it's an implicit reference as currently defined. Fixing security scheme is definitely higher-value!

@@ -373,7 +372,7 @@ Field Name | Type | Description
<a name="serverObjectProtocolVersion"></a>protocolVersion | `string` | The version of the protocol used for connection. For instance: AMQP `0.9.1`, HTTP `2.0`, Kafka `1.0.0`, etc.
<a name="serverObjectDescription"></a>description | `string` | An optional string describing the host designated by the URL. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation.
<a name="serverObjectVariables"></a>variables | Map[`string`, [Server Variable Object](#serverVariableObject) \| [Reference Object](#referenceObject)]] | A map between a variable name and its value. The value is used for substitution in the server's URL template.
<a name="serverObjectSecurity"></a>security | [[Security Requirement Object](#securityRequirementObject)] | A declaration of which security mechanisms can be used with this server. The list of values includes alternative security requirement objects that can be used. Only one of the security requirement objects need to be satisfied to authorize a connection or operation.
<a name="serverObjectSecurity"></a>security | [[Security Scheme Object](#securitySchemeObject) \| [Reference Object](#referenceObject)] | A declaration of which security schemes can be used with this server. The list of values includes alternative [security scheme objects](#securitySchemeObject) that can be used. Only one of the security scheme objects need to be satisfied to authorize a connection or operation.

Choose a reason for hiding this comment

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

I strongly encourage folks to file thoughts around potential reference merging in AsyncAPI as issues at the unified referencing discussion repo, where we can consider them alongside, for example, the limited merging of summary and description that OpenAPI 3.1 does outside of JSON Schema references.

This wouldn't mean AsyncAPI is blocked from taking other action, but unified referencing will only be unified if we know what's going on with each project.

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.

lgtm, just resolve conflicts and I'm ready to merge

@sonarcloud
Copy link

sonarcloud bot commented Jan 16, 2023

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

@fmvilas
Copy link
Member Author

fmvilas commented Jan 16, 2023

👍 Done!

@fmvilas
Copy link
Member Author

fmvilas commented Jan 17, 2023

/rtm

@asyncapi-bot asyncapi-bot merged commit 36061cd into asyncapi:next-major-spec Jan 17, 2023
@asyncapi-bot
Copy link
Contributor

🎉 This PR is included in version 3.0.0-next-major-spec.7 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

GreenRover pushed a commit to GreenRover/asyncapi-spec that referenced this pull request Jan 18, 2023
@fmvilas fmvilas deleted the unify-all-referencing-mechanisms branch January 18, 2023 15:19
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.

None yet

7 participants