# NATS

> Publish messages to NATS subjects, and check the messages your services publish on subjects and into JetStream streams.

Source: https://axx.nimbusxr.us/references/packs/nats/

Publish messages to NATS subjects, and check the messages your services publish on subjects and into JetStream streams.

Register the server once, usually in the `Background`; every NATS step of the scenario uses it:

```gherkin
Given the tracking nats server with the following properties:
  | url   | nats://localhost:4222 |
  | token | ${env:NATS_TOKEN}     |
```

Steps name a **subject** or a **stream**: `the deliveries.confirmed nats subject`, `the TRACKING nats stream`. Messages carry headers (`with the following headers:`, and `header <name>` rows in checks). A message published to a subject a stream captures is published through JetStream, and the step waits for the stream to store it.

- **A subject check subscribes for the run:** for the subjects a run checks, Axx subscribes once the services are up. A subject in a check can have the wildcards `*` and `>`: `the tracking.> nats subject`, and a `subject` row checks the subject a message came on.
- **A stream check reads only what is new:** for the streams a run checks, Axx reads each with an ordered consumer of its own that starts with the messages stored after the services are up, so what earlier runs stored never counts. It takes nothing from the stream's other consumers; a work-queue stream allows no other consumer, so check its subject instead.
- **A check only looks at the messages received since its scenario started,** so scenarios running in parallel check their own messages, by data unique to them.
- **Secrets stay secret:** `${env:..}` values in the properties are masked in logs and failures.

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

## Steps

### `nats.server`

```gherkin
Given the {word} nats server with the following properties:
  | property | value |
```

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

Register the NATS server the steps talk to.

- The first server registered is the one the scenario's NATS steps use.
- Give it at most one of a `token`, a `username` and `password`, and `creds`.
- Values expand `${env:..}` and `${sys:..}`; `${env:..}` values are masked.

| Parameter | Takes | For example |
|---|---|---|
| `{word}` | one word, with no spaces | `parcels`, `PX-4101` |

| Property | Takes |
|---|---|
| `url` | the server's URL, `nats://host:4222` or `tls://` for TLS; several, separated by commas, for a cluster |
| `token` | the token Axx connects with, like `${env:NATS_TOKEN}` |
| `username` | the user Axx connects as |
| `password` | its password |
| `creds` | a credentials file (JWT and seed), relative to the directory of axx.yaml |
| `asyncapi` | an AsyncAPI document, a file of the project or a URL, that the subjects follow: every message a scenario sends there, and every message a check finds, is checked against it (with the asyncapi pack) |

**Example:**

```gherkin
Given the tracking nats server with the following properties:
  | url | nats://localhost:4222 |
Given the tracking nats server with the following properties:
  | url   | tls://nats.parcels.example:4222 |
  | creds | nats/axx.creds                  |
```

_Since 0.1.5._

### `nats.subject.send`

```gherkin
When a message is published to the {word} nats subject:
  """
  ...
  """
```

Send a message to the nats subject; the doc string is its body.

| Parameter | Takes | For example |
|---|---|---|
| `{word}` | one word, with no spaces | `parcels`, `PX-4101` |

**Example:**

```gherkin
When a message is published to the deliveries.confirmed nats subject:
  """
  {"reference": "PX-8301", "signedBy": "H. Wolf", "deliveredAt": "2026-09-28T10:12:00Z"}
  """
```

_Since 0.1.5._

### `nats.subject.send.file`

```gherkin
When the {filepath} message is published to the {word} nats subject[[ with the following headers:]]
```

Send a message whose body is the file to the nats subject, with the headers of the table when the step has one.

| Parameter | Takes | For example |
|---|---|---|
| `{filepath}` | a file of the project: a path relative to the feature file's directory, the `resources` directories or axx.yaml's directory (looked for in that order), or an absolute path, quoted when it has a space | `seeds/parcels.yaml`, `kafka/scan-delivered.json` |
| `{word}` | one word, with no spaces | `parcels`, `PX-4101` |

Each row is a header sent with the message, as text: its name and its value.

**Variants**, the parts in `[[...]]` said or left out:

- `the {filepath} message is published to the {word} nats subject`
- `the {filepath} message is published to the {word} nats subject with the following headers:`

**Example:**

```gherkin
When the nats/delivery-confirmed.json message is published to the deliveries.confirmed nats subject
When the nats/delivery-confirmed.json message is published to the deliveries.confirmed nats subject with the following headers:
  | courier | CR-LEJ-12 |
```

_Since 0.1.5._

### `nats.subject.received`

```gherkin
Then [[within {duration} ]]the {word} nats subject has a message where:
  | path | value |
```

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

Check that the nats subject has a message with those values, received since the scenario started.

- The check waits for it: 10 seconds, or `within {duration}`.
- Axx subscribes to a subject it checks for the run.

| Parameter | Takes | For example |
|---|---|---|
| `{duration}` | a duration in seconds (`s`) or minutes (`m`) | `5s`, `2m` |
| `{word}` | one word, with no spaces | `parcels`, `PX-4101` |

Each row is a path into the message's JSON body (a field name, a dotted path or a JSONPath) and the value it has, compared as text: `null` for null and `undefined` for absent. A row `header <name>` is instead on the header of that name sent with the message: `undefined` when there is none. A row `subject` is on the message itself, not its body.

**Variants**, the parts in `[[...]]` said or left out:

- `the {word} nats subject has a message where:`
- `within {duration} the {word} nats subject has a message where:`

**Example:**

```gherkin
Then within 30s the tracking.> nats subject has a message where:
  | subject       | tracking.PX-8301 |
  | status        | DELIVERED        |
  | header source | courier          |
```

_Since 0.1.5._

### `nats.stream.received`

```gherkin
Then [[within {duration} ]]the {word} nats stream has a message where:
  | path | value |
```

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

Check that the nats stream has a message with those values, received since the scenario started.

- The check waits for it: 10 seconds, or `within {duration}`.
- Axx reads a stream it checks with an ordered consumer of its own, from the messages stored after the services are up.

| Parameter | Takes | For example |
|---|---|---|
| `{duration}` | a duration in seconds (`s`) or minutes (`m`) | `5s`, `2m` |
| `{word}` | one word, with no spaces | `parcels`, `PX-4101` |

Each row is a path into the message's JSON body (a field name, a dotted path or a JSONPath) and the value it has, compared as text: `null` for null and `undefined` for absent. A row `header <name>` is instead on the header of that name sent with the message: `undefined` when there is none. A row `subject` is on the message itself, not its body.

**Variants**, the parts in `[[...]]` said or left out:

- `the {word} nats stream has a message where:`
- `within {duration} the {word} nats stream has a message where:`

**Example:**

```gherkin
Then within 30s the TRACKING nats stream has a message where:
  | subject | tracking.PX-8302 |
  | status  | OUT_FOR_DELIVERY |
```

_Since 0.1.5._
