# AMQP requests

Source: https://apigenie.pl/docs/reference/cli/test/amqp
Part of the reference of [test](https://apigenie.pl/docs/reference/cli/test.md).
Its other pages: [Request files](https://apigenie.pl/docs/reference/cli/test/requests.md), [Variables and OAuth 2](https://apigenie.pl/docs/reference/cli/test/variables.md), [Assertions and scripts](https://apigenie.pl/docs/reference/cli/test/assertions.md), [Validation](https://apigenie.pl/docs/reference/cli/test/validation.md), [Generated requests](https://apigenie.pl/docs/reference/cli/test/generate.md), [GraphQL requests](https://apigenie.pl/docs/reference/cli/test/graphql.md), [WebSocket and MQTT requests](https://apigenie.pl/docs/reference/cli/test/websocket-mqtt.md), [Kafka requests](https://apigenie.pl/docs/reference/cli/test/kafka.md), [gRPC requests](https://apigenie.pl/docs/reference/cli/test/grpc.md), [Importing collections](https://apigenie.pl/docs/reference/cli/test/import.md), [httpYac compatibility](https://apigenie.pl/docs/reference/cli/test/httpyac.md).

An `AMQP` region publishes to an AMQP 0-9-1 broker and reads what comes to its queues (ADR-171). The
URL is `amqp://[user:password@]host[:port][/vhost]` (port 5672, the virtual host percent-encoded:
`/%2Fcarpet-express`), or `amqps://` (5671, over TLS, verified as `https://`).

```http
### File a declaration: the decision comes to the decisions queue
# @expect 1
# @property delivery-mode 2
# @property correlationId {{$uuid}}
AMQP amqp://localhost:5672/%2Fcarpet-express
exchange: customs
routing-key: customs.GB.filing
subscribe: customs.decisions

{"destinationCountry": "GB"}

### Await what the application publishes to the customs exchange
# @expect 1
AMQP amqp://localhost:5672/%2Fcarpet-express
bind: customs customs.*.filing
```

| Header | Meaning |
| --- | --- |
| `exchange` | The exchange the messages go to; without it, the default exchange (routing keys are queue names) |
| `routing-key` | The messages' routing key |
| `subscribe` | Queues consumed, separated by commas; a queue's messages go to the region, not to the application |
| `bind` | `EXCHANGE KEY`: a queue of the region's own, bound to the exchange with that binding key (none for fanout); can be repeated |
| `mandatory` | `false`: a message no queue takes isn't an error (`true` by default) |
| `username`, `password` | PLAIN credentials; without them the URL's, then `APIGENIE_AMQP_USERNAME` and `APIGENIE_AMQP_PASSWORD`, then `guest`. They are `[redacted]` in the output and reports |

`# @property NAME VALUE` lines with the name of a basic property set it: `content-type`,
`content-encoding`, `delivery-mode`, `priority`, `correlation-id`, `reply-to`, `expiration`
(milliseconds), `message-id`, `timestamp` (seconds since the epoch, or `now`), `type`, `user-id` and
`app-id`. Other names, and `# @property user NAME VALUE`, are application headers. The region
consumes its queues before it publishes, then reads until it has `# @expect` messages or `# @timeout`
has passed; its own messages coming back are left out. RabbitMQ's direct reply-to works:
`subscribe: amq.rabbitmq.reply-to` with `# @property reply-to amq.rabbitmq.reply-to`.

With an AsyncAPI `--spec`, the channel is the one of the exchange and routing key (a queue channel's
for the default exchange and its queue's name), and a message read from a queue is that queue's
channel's. What is published is checked against the channel's receive operations and what is read
against its send operations or as a reply: the body, the headers against the message's `headers`,
and the properties against the AMQP bindings (`message.properties.invalid`). A reply is paired with
its request by its correlation id in a header or a property: properties are seen by their AMQP and
AsyncAPI names (`correlation_id` and `correlationId`, `reply_to` and `replyTo`), so
`$message.header#/correlationId` finds either.
