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

[FEATURE REQUEST] RAML-like traits #108

Closed
fmvilas opened this issue Feb 3, 2019 · 10 comments · Fixed by #183
Closed

[FEATURE REQUEST] RAML-like traits #108

fmvilas opened this issue Feb 3, 2019 · 10 comments · Fixed by #183
Assignees
Labels

Comments

@fmvilas
Copy link
Member

fmvilas commented Feb 3, 2019

Is your feature request related to a problem? Please describe.

I want to be able to better reuse parts of an AsyncAPI document. As an example, if all my messages have 4 headers in common, I'd like to be able to group them using a name and express it in each message.

Can't it be tackled using specification extensions?

No.

Describe the solution you'd like

The idea is to implement something similar to what RAML did with traits. Traits are pieces of information that will be merged into the referencing object. Here are some rules:

  1. Traits will be merged using the JSON Merge Patch algorithm.
  2. The object that uses traits MUST be valid before applying them.
  3. The resulting object after applying the traits MUST be valid too.
  4. Traits can only be applied to operation and message objects.
  5. Message traits MUST NOT contain the payload property. Operation traits MUST NOT contain the message property.
  6. Traits MUST be applied in the order they're defined.
  7. Traits MUST NOT contain traits.
  8. It MUST support variables, allowing for simple variable replacement. Variables MUST be enclosed between {{ and }}.
  9. Where used, the items in the array of traits MUST be either a trait definition or a 2-elements array where the first element is the trait definition and the second is a list of variable values. All variables MUST be fulfilled.

Example

channels:
  my/channel:
    publish:
      traits:
        - [{$ref: '#/components/traits/docs'}, {headerId: 'my-channel-publish'}]
      message:
        traits:
          - $ref: '#/components/traits/jsonOverProto3'
          - $ref: '#/components/traits/kafka'
components:
  traits:
    docs:
      externalDocs:
        url: https://mycompany.com/docs#{{headerId}}
    jsonOverProto3:
      schemaFormat: 'application/vnd.google.protobuf;version=3'
      contentType: application/json
    kafka:
      protocolInfo:
        kafka:
          compression: snappy
@MikeRalphson
Copy link
Contributor

https://gist.github.com/MikeRalphson/7ee0624fc1df70c0475717d89a5b6e4b

@fmvilas
Copy link
Member Author

fmvilas commented Feb 3, 2019

This is exactly how I was imagining it 👍

@fmvilas
Copy link
Member Author

fmvilas commented Mar 12, 2019

Just updated the description with the proposal.

@fmvilas
Copy link
Member Author

fmvilas commented Mar 23, 2019

This comment from @handrews is something to take into account: OAI/Overlay-Specification#39.

@fmvilas
Copy link
Member Author

fmvilas commented Mar 24, 2019

Updated the description. Changes are:

  • Traits have a limited set of properties you can apply. Namely, operation traits can have all the operation object properties except traits and message, and message traits can have all the message object properties except traits and payload.
  • Variable templating delimiters are now {{ and }} to match what the majority of templating systems use.

@handrews
Copy link

@fmvilas how did you take into account the comment of mine that you linked to? I have not had a chance to catch up on all of these traits proposals, so my apologies if the answer should be obvious. But given the ongoing discussion in OpenAPI for this I am curious as to your reasoning.

@fmvilas
Copy link
Member Author

fmvilas commented Mar 25, 2019

Well, the first of all the measures we took is that we're not allowing traits in schemas, just on the operation and message objects. And to be even more sure that we don't mess things up, only a set of safe/annotations fields are allowed to be "overridden". Plus, it is mandatory the object before and after applying traits MUST be valid.

As you can see, the intention is to roll this out slowly and see how it is used. I hope I'm not missing anything from your comment!

@fmvilas
Copy link
Member Author

fmvilas commented Mar 25, 2019

Also, traits are something will be preprocessed before diving into any JSON Schema validation. So it's actually syntax sugar on top of the AsyncAPI document.

@handrews
Copy link

@fmvilas thanks! That makes sense.

In the context of the problems I was describing in the referenced issue, even requiring all of the inputs and outputs of the merge to be valid on their own does not eliminate the problem (the example that I give to illustrate the problem actually meets those criteria). But if you are keeping traits out of the schema objects then it should be fine.

@asyncapi-bot
Copy link
Contributor

🎉 This issue has been resolved in version 1.0.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

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

Successfully merging a pull request may close this issue.

4 participants