AsyncApiSpex.Schema (async_api_spex v0.2.0)

Copy Markdown View Source

Declares a reusable AsyncAPI Schema Object (JSON Schema draft-07).

There are two forms. Pass exactly one of :schema and :fields.

schema: — write the JSON Schema

defmodule MyApp.Schemas do
  use AsyncApiSpex.Schema,
    name: "OrderCreatedV1",
    schema: %{type: "object", required: ["id"], properties: %{id: %{type: "string"}}}
end

schema must be a map literal.

fields: — decorate an existing struct

defmodule MyApp.Events.OrderCreated do
  defstruct [:id, :customer_id, :items, :placed_at]

  use AsyncApiSpex.Schema,
    name: "OrderCreated",
    title: "Order created",
    description: "Emitted once per checkout.",
    fields: [
      id: [type: :string, required: true],
      customer_id: :string,
      items: {:array, MyApp.Events.LineItem},
      placed_at: :datetime
    ]
end

Every key of the struct becomes a property of an object schema. fields refines the keys it names; a struct key it does not name is an unconstrained property (%{}). Naming a key the struct does not have, or using fields in a module without defstruct, raises ArgumentError at compile time. Struct defaults are not emitted and additionalProperties is left unset. use may come before or after defstruct.

A field is either a type, or a keyword list with a required :type and the optional :required (boolean) and :description (string).

TypeSchema
:string, :integer, :number, :boolean%{"type" => "string"} and so on
:map%{"type" => "object"}
:any%{}
:datetime%{"type" => "string", "format" => "date-time"}
:date%{"type" => "string", "format" => "date"}
{:array, type}%{"type" => "array", "items" => <type>}
{:enum, values}%{"enum" => values}; a non-empty list of strings, atoms, or numbers
a mapused verbatim, for anything else
a modulea reference to that module's schema; it must itself use AsyncApiSpex.Schema

A module may reference itself (children: {:array, __MODULE__}). A module type is not checked at compile time, because the module may not be compiled yet; AsyncApiSpex.validate/1 reports one that does not use AsyncApiSpex.Schema.

:title and :description are only valid with :fields; with :schema put them inside the map.

Both forms

Both define schema/0 returning the schema map and __async_api_schema__/0 returning {name, schema}. AsyncApiSpex.resolve/1 moves a schema module used from a message into components.schemas and replaces the use with a reference.

name must be a string literal matching ~r/\A[A-Za-z0-9_.-]+\z/. A bad name, a bad :schema or :fields, and any unknown option raise ArgumentError at compile time.

Summary

Functions

Declares schema/0 and __async_api_schema__/0 on the calling module.

Functions

__using__(opts)

(macro)

Declares schema/0 and __async_api_schema__/0 on the calling module.