# `PhoenixMicro.Message`
[🔗](https://github.com/iamkanishka/phoenix_micro/blob/v1.0.0/lib/phoenix_micro/message.ex#L1)

The canonical message envelope for all inter-service communication.

Every message flowing through `phoenix_micro` — whether published to a broker,
consumed from a queue, or passed through an RPC call — is wrapped in this struct.

## Fields

* `:id`            — UUID v4; assigned at publish time; used for idempotency tracking.
* `:topic`         — The routing key / topic name (e.g. `"payments.created"`).
* `:payload`       — The decoded message body. Any term.
* `:headers`       — Arbitrary key-value metadata map (string keys).
* `:attempt`       — Delivery attempt counter; starts at 1, incremented on retry.
* `:timestamp`     — UTC `DateTime` of original publish time.
* `:reply_to`      — Optional reply-topic for RPC correlation.
* `:correlation_id`— Optional ID linking an RPC request to its response.
* `:raw`           — The raw broker-native message (transport-specific). Opaque.
* `:acked?`        — Whether this message has been ack'd/nack'd by the consumer.
* `:metadata`      — Transport-specific extra data (partition, offset, routing key, …).

# `headers`

```elixir
@type headers() :: %{required(String.t()) =&gt; String.t()}
```

# `metadata`

```elixir
@type metadata() :: %{required(atom()) =&gt; term()}
```

# `t`

```elixir
@type t() :: %PhoenixMicro.Message{
  acked?: boolean(),
  attempt: pos_integer(),
  correlation_id: String.t() | nil,
  headers: headers(),
  id: String.t(),
  metadata: metadata(),
  payload: term(),
  raw: term(),
  reply_to: String.t() | nil,
  timestamp: DateTime.t(),
  topic: String.t()
}
```

# `ack`

```elixir
@spec ack(t()) :: t()
```

Marks the message as acknowledged.

# `increment_attempt`

```elixir
@spec increment_attempt(t()) :: t()
```

Returns a new message with the attempt counter incremented.

# `new`

```elixir
@spec new(String.t(), term(), keyword()) :: t()
```

Creates a new message with a generated UUID and current UTC timestamp.

## Examples

    iex> msg = PhoenixMicro.Message.new("payments.created", %{amount: 100})
    iex> msg.topic
    "payments.created"
    iex> msg.attempt
    1

# `put_header`

```elixir
@spec put_header(t(), String.t(), String.t()) :: t()
```

Adds or updates a header.

# `put_metadata`

```elixir
@spec put_metadata(t(), metadata()) :: t()
```

Merges additional metadata into the message.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
