# AsyncAPI

> Check messages against an AsyncAPI document: every message a scenario sends, which catches test data that drifted from the contract, and every message a check finds, which catches a service that broke it.

Source: https://axx.nimbusxr.us/next/references/packs/asyncapi/

Check messages against an AsyncAPI document: every message a scenario sends, which catches test data that drifted from the contract, and every message a check finds, which catches a service that broke it.

A broker's registration names the document in an `asyncapi` row, a file of the project or a URL:

```gherkin
Given the parcels mqtt broker with the following properties:
  | url      | mqtt://localhost:1883 |
  | asyncapi | asyncapi.yaml         |
```

The row works on every messaging registration: Kafka services, AMQP, MQTT and NATS brokers, AWS accounts (SQS and SNS), Google Cloud projects (Pub/Sub), Service Bus namespaces, WebSockets and event streams. Without this pack in `axx-packs.yaml`, the row fails the registration.

- **Documents:** AsyncAPI 2.x (2.6 and earlier) and 3.x, in YAML or JSON, with `$ref`s to other files and URLs.
- **Channels:** a message belongs to the channel whose address is the message's topic, queue, subject, exchange or routing key, or the path of a WebSocket or an event stream. A `{parameter}` in an address stands for any text without a slash: `depots/{depot}/scans` is the channel of `depots/LEJ/scans`. When channels say which servers they are on, only the servers of the message's protocol count.
- **Messages:** a message must be one of its channel's: its payload and headers follow that message's schemas, and its content type, when it has one, is the message's. When a channel has several messages, the failure names the one the message comes closest to.
- **Schemas:** JSON Schema (draft 7 unless the schema says otherwise, and the AsyncAPI schema format), or Avro, whose payloads are in Avro's JSON encoding. Payloads are JSON unless their content type says YAML or text.

Findings have keys and levels, like the REST pack's OpenAPI findings:

| Key | Found when |
|---|---|
| `validation.channel.unknown` | the document has no channel for the message |
| `validation.message.contentType` | the message's content type is not its message's |
| `validation.message.payload.format` | the payload is not JSON (or YAML) |
| `validation.message.payload.schema.<keyword>` | the payload breaks a JSON Schema keyword (`required`, `type`, `enum`...), or `avro` its Avro schema |
| `validation.message.headers.schema.<keyword>` | the headers break a keyword of their schema |

- **Levels:** `ERROR` (or `FAIL`) fails the step, `WARN` and `INFO` log the finding, `IGNORE` drops it. Every finding is an `ERROR` unless `packs.asyncapi.levels` in axx.yaml, or the scenario's `the AsyncAPI validation levels are:`, says otherwise.
- **Keys cover the keys below them:** `validation.message.payload` sets every payload finding; the most specific key set wins.

Add it to a project with `axx pack add asyncapi`.

## Settings

In `axx.yaml`, under `packs.asyncapi`:

| Setting | Takes | Values |
|---|---|---|
| `levels` | Validation key -> ERROR (or FAIL), WARN, INFO or IGNORE, for every scenario. | names and values |

## Steps

### `asyncapi.levels`

```gherkin
Given the AsyncAPI validation levels are:
  | validation key | level |
```

The table may start with the row naming its columns, as above, or go straight to its rows.

Set the level of AsyncAPI validation findings for this scenario, on every contract it checks messages against.

- A key also sets the keys below it: `validation.message.payload` relaxes `validation.message.payload.schema.required` too. The most specific key set wins.
- The rows are merged over `packs.asyncapi.levels` of axx.yaml.
- The pack's documentation lists the keys, and what each level does.

A row is a validation key and its level: `ERROR` (or `FAIL`), `WARN`, `INFO` or `IGNORE`. The key must be one the pack reports, or a prefix of such keys, like `validation.message.payload`: any other fails the step, which names the closest keys.

**Example:**

```gherkin
Given the AsyncAPI validation levels are:
  | validation.message.payload.schema.required | WARN |
```

_Since 0.1.5._
