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: support AsyncAPI v3.0.0 #163

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 79 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Convert [AsyncAPI](https://asyncapi.com) documents older to newer versions.
* [From CLI](#from-cli)
* [In JS](#in-js)
* [In TS](#in-ts)
- [Conversion 2.x.x to 3.x.x](#conversion-2xx-to-3xx)
- [Known missing features](#known-missing-features)
- [Development](#development)
- [Contribution](#contribution)
Expand All @@ -32,7 +33,7 @@ npm i @asyncapi/converter

### From CLI

To convert an AsyncAPi document in the console needs the official [AsyncAPI CLI](https://github.com/asyncapi/cli).
To convert an AsyncAPI document in the console needs the official [AsyncAPI CLI](https://github.com/asyncapi/cli).

If you don't have CLI installed, run this command to install the CLI globally on your system:

Expand Down Expand Up @@ -70,8 +71,11 @@ const { convert } = require('@asyncapi/converter')

try {
const asyncapi = fs.readFileSync('streetlights.yml', 'utf-8')
console.log(convert(asyncapi, '2.0.0', {
id: 'urn:com.asyncapi.streetlights'
console.log(convert(asyncapi, '3.0.0', {
v2tov3: {
convertServerComponents: false,
convertChannelComponents: false,
}
}));
} catch (e) {
console.error(e);
Expand All @@ -85,9 +89,12 @@ import { convert } from '@asyncapi/converter';
import type { ConvertVersion, ConvertOptions } from '@asyncapi/converter';

try {
const toVersion: ConvertVersion = '2.0.0';
const toVersion: ConvertVersion = '3.0.0';
const options: ConvertOptions = {
id: 'urn:com.asyncapi.streetlights'
v2tov3: {
convertServerComponents: false,
convertChannelComponents: false,
}
};

const asyncapi = fs.readFileSync('streetlights.yml', 'utf-8')
Expand All @@ -97,6 +104,73 @@ try {
}
```

## Conversion 2.x.x to 3.x.x

Conversion to version `3.x.x` from `2.x.x` has several assumptions that should be know before converting:

- The input must be valid AsyncAPI document.
- External references are not resolved and converted, they remain untouched, even if they are incorrect.
- In version `3.0.0`, the channel identifier is no longer its address, but due to the difficulty of defining a unique identifier, we still treat the address as an identifier. If there is a need to assign an identifier other than an address, an `x-channelId` extension should be defined at the level of the given channel.

```yaml
# 2.x.x
channels:
users/signup:
x-channelId: 'userSignUp'
...
users/logout:
...

# 3.0.0
channels:
userSignUp:
...
users/logout:
...
```

- The `publish` operation is treated as a `receive` action, and `subscribe` is treated as a `send` action. Conversion by default is embraced from the application perspective. If you want to change this logic, you need to specify `v2tov3.pointOfView` configuration as `client`.
- If the operation does not have an `operationId` field defined, the unique identifier of the operation will be defined as a combination of the identifier of the channel on which the operation was defined + the type of operation, `publish` or `subscribe`. Identical situation is with messages. However, here the priority is the `messageId` field and then the concatenation `{publish|subscribe}.messages.{optional index of oneOf messages}`.

```yaml
# 2.x.x
channels:
users/signup:
publish:
message:
...
subscribe:
operationId: 'userSignUpEvent'
message:
oneOf:
- messageId: 'userSignUpEventMessage'
...
- ...


# 3.0.0
channels:
users/signup:
messages:
publish.message:
...
userSignUpEventMessage:
...
userSignUpEvent.message.1:
...
operations:
users/signup.publish:
action: receive
...
userSignUpEvent:
action: send
...
```

- Security requirements that use scopes are defined in the appropriate places inline, the rest as a reference to the `components.securitySchemes` objects.
- If servers are defined at the channel level, they are converted as references to the corresponding objects defined in the `servers` field.
- Channels and servers defined in components are also converted (unless configured - see [examples](#in-js)).

## Known missing features

* When converting from 1.x to 2.x, Streaming APIs (those using `stream` instead of `topics` or `events`) are converted correctly but information about framing type and delimiter is missing until a [protocolInfo](https://github.com/asyncapi/extensions-catalog/issues/1) for that purpose is created.
Expand Down
Loading