Reusability with traits

Found an error? Have a suggestion?Edit this page on GitHub

Traits work only with the operations and messages fields. Traits allow the definition of properties to be reused across multiple messages and operations within the specification. Reusing traits promotes code maintainability and reduces duplication while making your AsyncAPI documents cleaner to manage.

Defining traits

Traits are meant to be reused, so it's best to define them in the components section of your AsyncAPI document, either under operationTraits or messageTraits. Choose depending on whether they're for operations or messages. Give each trait a unique name and list the properties it includes. You can reference these traits with the $ref keyword, allowing you to keep traits in a separate file outside the AsyncAPI document. For more on using $ref and reusability, check out the reusable parts document.

Message traits do not fully cover all fields that a normal message has, such as the payload. The same is true with Operation traits which represent only selected fields usually used in an operation.

Here is a part of a message that has a trait defined inline in a message:

1description: Example description.
2traits:
3  - name: UserSignup
4    description: Trait description.
5  - tags:
6      - name: user

When traits are combined with a message object, the resulting message will look like the example shown below:

1name: UserSignup
2description: Example description.
3tags:
4  - name: user

Notice that the trait description didn't override the already defined description in a message outside the trait.

Applying traits from components

Once a trait is defined, you can apply it to an operation or a message using the $ref keyword in the traits section. The $ref value should point to the path of the trait within the components section.

For example, let's say we have a trait named commonHeaders defined in messageTraits:

1components:
2  messageTraits:
3    commonHeaders:
4      headers:
5        type: object
6        properties:
7          content-type:
8            type: integer

To apply the above trait to a message object, you can do:

1name: lightMeasured
2title: Light measured
3summary: Inform about environmental lighting conditions of a particular streetlight.
4headers:
5  type: object
6  properties:
7    custom-header:
8      type: string
9traits:
10  - $ref: '#/components/messageTraits/commonHeaders'

Notice how the commonHeaders trait includes a content-type header and is merged into the headers object in a message:

1name: lightMeasured
2title: Light measured
3summary: Inform about environmental lighting conditions of a particular streetlight.
4headers:
5  type: object
6  properties:
7    content-type:
8      type: integer
9    custom-header:
10      type: string

Trait merging mechanism

In the AsyncAPI document, traits are merged into the operation or message object in the order they are defined, without overriding any properties. For detailed information on how this merging works, refer to the specification's section on the traits merge mechanism.

Was this helpful?
Help us improve the docs by adding your contribution.
OR
Github:AsyncAPICreate Issue on GitHub