# `AsyncApiSpex.Spec`
[🔗](https://github.com/jamescarr/ankusa/blob/async_api_spex-v0.2.0/packages/async_api_spex/lib/async_api_spex/spec.ex#L1)

Behaviour for a module that returns a static AsyncAPI document.

`AsyncApiSpex.Plug.RenderSpec` and `mix async_api_spex.gen` both call
`spec/0`. Applications whose channels are known only at runtime do not
implement this behaviour; they build the `AsyncApiSpex.Document` themselves.

## Assembling the document from channel modules

`use AsyncApiSpex.Spec` implements `spec/0` for you by collecting every module
that declares a channel with `use AsyncApiSpex.Channel`:

    defmodule Shop.AsyncApi do
      use AsyncApiSpex.Spec,
        otp_app: :shop,
        info: [title: "Shop", version: "1.0.0"]
    end

Options:

  * `:info` (required) — a keyword list literal of `AsyncApiSpex.Info` fields
    that includes `:title` and `:version`. Values are evaluated when the
    document is built.
  * `:otp_app` — an atom literal; every module of that application that uses
    `AsyncApiSpex.Channel` is included, in module-name order. The application
    must be loaded. Zero modules yield a document with no channels.
  * `:channels` — a non-empty list of channel modules to include, instead of
    `:otp_app`. Exactly one of `:otp_app` and `:channels` is required.
  * `:id`, `:default_content_type`, `:extensions` — the same fields of
    `AsyncApiSpex.Document`.

Two channels may share a server only if both declare the same
`AsyncApiSpex.Server`; two channels with the same id, or two different
servers with the same id, raise `ArgumentError` when the document is built.

`spec/0` is overridable, so an application can extend the generated document:

    def spec do
      doc = super()
      %{doc | extensions: Map.put(doc.extensions, "x-team", "payments")}
    end

A hand-written `spec/0` that builds the `AsyncApiSpex.Document` itself remains
supported; implement the behaviour without `use`.

# `spec`

```elixir
@callback spec() :: AsyncApiSpex.Document.t()
```

Returns the AsyncAPI document to serve or serialize.

# `__using__`
*macro* 

Implements `spec/0` by assembling a document from channel modules.

See the module documentation for the options.

---

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