Skip to content

Commit

Permalink
update for feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
iancooper committed Jul 15, 2021
1 parent b64dcf6 commit f28f6eb
Showing 1 changed file with 47 additions and 52 deletions.
99 changes: 47 additions & 52 deletions Conventions.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
# Conventions
## What is this?
This document describes a set of conventions that implementers may adopt when describing [Channel](https://github.com/asyncapi/spec/blob/master/spec/asyncapi.md#channelBindingsObject), [Operation](https://github.com/asyncapi/spec/blob/master/spec/asyncapi.md#operationBindingsObject) or [Message](https://github.com/asyncapi/spec/blob/master/spec/asyncapi.md#messageBindingsObject) bindings for different protocols.
This document describes a set of conventions that implementers may adopt when describing [Server](https://github.com/asyncapi/spec/blob/master/spec/asyncapi.md#serverBindingsObject), [Channel](https://github.com/asyncapi/spec/blob/master/spec/asyncapi.md#channelBindingsObject), [Operation](https://github.com/asyncapi/spec/blob/master/spec/asyncapi.md#operationBindingsObject) or [Message](https://github.com/asyncapi/spec/blob/master/spec/asyncapi.md#messageBindingsObject) bindings for different protocols.

## Why Adopt These?
AsyncAPI does not constrain how Bindings are defined, beyond a valid JSON schema. This makes Bindings flexible extension points for implementers. This flexibility is powerful, but it comes at a price in that it can be hard for implementers to understand how to use Bindings consistently, which makes it difficult for those writing tools that work with AsyncAPI to support a range of protocols.
AsyncAPI does not constrain how Bindings are defined, beyond a valid JSON schema. This makes Bindings flexible extension points for implementers. This flexibility is powerful, but it comes at a price in that it can be hard for implementers to understand how to use Bindings consistently, which makes it difficult for those writing tools that work with AsyncAPI to support a range of protocols.

## What Belongs on a Binding?
The Binding should be used to provide configuration data that a protocol requires. That configuration may be exposed via Message-Oriented-Middleware (MoM) using a Management API that allows code to configure the MoM as described. The fields in a Binding should represent protocol specific metadata, that is not exposed as an existing field on the Channel, Operation or Message objects.
The Binding should be used to provide configuration data that a protocol requires. That configuration may be exposed via Message-Oriented-Middleware (MoM) using a Management API that allows code to configure the MoM as described. The fields in a Binding should represent protocol specific metadata, that is not exposed as an existing field on the Server, Channel, Operation or Message objects.

A Binding may also be used by the providers of SDKs for MoM to provide metadata to configure producers or consumers using that SDK. That is outside the scope of advice here, but SDK owners wishing to use Bindings may follow the general advice here.

## Effective Bindings
### **Item 1** Use the Extensions Format
Prefer use of the [Bindings Extensions](https://github.com/asyncapi/extensions-catalog) format when defining a binding over raw JSON Schema.

The Binding Extensions format works with tools because it indicates where in the specification the binding should be used via a Hook. Using a Hook signals clearly to the user of an extension on which of Channel, Operation or Message the binding can be used. Implementers may choose to use author a binding so that the only fields on the binding are those appropriate to the object identified by the Hook. It also makes it possible for tools to determine correctness of an AsyncAPI file by ensuring that the binding is only used where permitted.
The Binding Extensions format works with tools because it indicates where in the specification the binding should be used via a Hook. Using a Hook signals clearly to the user of an extension on which of Server, Channel, Operation or Message the binding can be used. Implementers may choose to use author a binding so that the only fields on the binding are those appropriate to the object identified by the Hook. It also makes it possible for tools to determine correctness of an AsyncAPI file by ensuring that the binding is only used where permitted.

### **Item** 2 Prefer JSON for Bindings
Prefer the use of JSON to define a Binding.
Expand All @@ -35,11 +35,11 @@ Not all uses of a Binding have Infrastructure as Code as a goal, and not all par
Some transports do not provide a specification of a management API used to create infrastructure but instead have middleware specific APIs. To support a protocol that does not define infrastructure creation as part of its standard, consider a binding for the middleware in addition to the protocol i.e. AMQP 1-0-0.

### **Item 4** Support Contract First && Scaffolding
Design your binding to support Contract First definition of an endpoint that is later used with [Scaffolding](https://en.wikipedia.org/wiki/Scaffold_(programming)) to generate the skeleton of an application. Contract Fist scenarios requires the binding to support the necessary parameters to either produce or consume messages via the API or SDK.
Design your binding to support Contract First definition of an endpoint that is later used with [Scaffolding](https://en.wikipedia.org/wiki/Scaffold_(programming)) to generate the skeleton of an application. Contract-First scenarios require the binding to support the necessary parameters to either produce or consume messages via the API or SDK.

Code generation from an AsyncAPI definition, particularly for consumers, is a use case that improves developer productivity and tends to drive adoption. Not all uses of a Binding have later generation of code via Scaffolding as a goal.

There may be multiple SDKs for a particular protocol, for different languages and frameworks. In many cases the variables required by these targets remain common across the targets and can simply be inferred from the protocol. In this case it is possible to define a common set of fields for a binding that can be used by Scaffolding regardless of the SDK. In other cases, SDKs vary considerably for the middleware. In this case you may prefer to provide a binding for the middleware that facilitates code generation for that middleware.
There may be multiple SDKs for a particular protocol, for different languages and frameworks. In many cases the variables required by these targets remain common across the targets and can simply be inferred from the protocol. In this case, it is possible to define a common set of fields for a binding that can be used by Scaffolding regardless of the SDK. In other cases, SDKs vary considerably for the middleware. In this case, you may prefer to provide a binding for the middleware that facilitates code generation for a specific SDK.

### **Item 5** Assume Separate Endpoints Have Separate AsyncAPI Files
Producers and consumers are usually separate apps, they may belong to separate teams, and under models such as pub-sub, there may an architectural goal to decouple producer and consumer by ensuring that each knows about the channel, but not the other. For this reason, you should assume that it will be common to define separate endpoints for the producer and consumer, but that the channel and the message schema will be shared. (Users may use $ref to prevent duplication, but that does not change these guidelines).
Expand Down Expand Up @@ -195,7 +195,7 @@ Where a protocol defines metadata that forms part of the message sent via middle
Tooling to validate that messages match the schema will expect to verify against the schema of the message payload and headers, putting message metadata into a Message Binding makes this harder as tooling must know to look there as well.
Implementers of producers or consumers are also likely to assume that the the can refer to #/Components/Schema to understand payloads and headers, and adding metadata into bindings in addition makes it harder to comprehend the schema of a message.
Implementers of producers or consumers are also likely to assume that the they can refer to #/Components/Schema to understand payloads and headers, and adding metadata into bindings, in addition, makes it harder to comprehend the schema of a message.
A [Message Binding](https://github.com/asyncapi/spec/blob/master/spec/asyncapi.md#messageBindingsObject) should be used to define metadata about the protocol's message format that is used for [Infrastructure as Code](#item-3-support-infrastructure-as-code) or [Scaffolding](#item-4-support-contract-first--scaffolding). Don't use the Message Bindings to describe what is sent; use the Message Binding to describe how it is sent, if required.
Expand All @@ -206,56 +206,51 @@ channels:
summary: Messages about quux
operationId: sendQuux
$ref: "#/components/messages/quuxEvent"

...

components:
schemas:
quux:
type: object
properties:
quuxDetails:
type: string
amqpBasicProperties:
type: object
properties:
content_encoding:
type: string
delivery-mode:
type: integer
minimum: 0
maximum: 1
priority:
type: integer
minimum: 0
maximum: 9
correlation-id:
type: string
reply-to:
type: string
expiration:
type: string
message-id:
type: string
timestamp:
type: string
type:
type: string
user-id:
type: string
app-id:
type: string

quux:
type: object
properties:
quuxDetails:
type: string
amqpBasicProperties:
type: object
properties:
content_encoding:
type: string
delivery-mode:
type: integer
minimum: 0
maximum: 1
priority:
type: integer
minimum: 0
maximum: 9
correlation-id:
type: string
reply-to:
type: string
expiration:
type: string
message-id:
type: string
timestamp:
type: string
type:
type: string
user-id:
type: string
app-id:
type: string
messages:
quuxEvent:
summary: Raised when a quux occurs.
summary: Raised when a quux occurs.
description: When a quux happens, describes the quux
contentType: application/json
payload:
$ref: "#/components/schemas/quux"
traits:
$ref: "#/components/schemas/amqpBasicProperties"

contentType: application/json
payload:
$ref: "#/components/schemas/quux"
traits:
$ref: "#/components/schemas/amqpBasicProperties"

```

Expand Down

0 comments on commit f28f6eb

Please sign in to comment.