PhoenixSpectral (phoenix_spectral v0.5.0)

Copy Markdown View Source

Generates OpenAPI 3.1 specifications from Phoenix router and typed controllers.

Controllers that use PhoenixSpectral.Controller and define typespecs on their action functions become the single source of truth for OpenAPI documentation.

Usage

{:ok, spec} = PhoenixSpectral.generate_openapi(MyAppWeb.Router, %{title: "My API", version: "1.0.0"})

Summary

Functions

Generates an OpenAPI 3.1 specification from a Phoenix router module.

Functions

generate_openapi(router, metadata)

@spec generate_openapi(module(), map()) :: {:ok, iodata()} | {:error, list()}

Generates an OpenAPI 3.1 specification from a Phoenix router module.

Introspects all routes in the router, extracts type information from controllers, and builds an OpenAPI spec.

Parameters

  • router - A Phoenix router module
  • metadata - Map with API metadata. Required keys:
    • :title — API title
    • :version — API version string
    Optional keys:
    • :summary — short one-line summary of the API (appears in info.summary)
    • :description — longer description of the API (appears in info.description)
    • :terms_of_service — URL string for terms of service
    • :contact — map with :name, :url, and/or :email
    • :license — map with :name and optional :url or :identifier
    • :servers — list of server maps, each with :url and optional :description

Returns

  • {:ok, iodata} - Complete OpenAPI 3.1 specification as JSON iodata
  • {:error, errors} - List of errors if generation fails

Parameter descriptions via typed type aliases

To add a description to a path or header parameter, define a named type alias for the parameter's type and annotate it with spectral description: "...":

spectral description: "The user's unique identifier"
@type user_id :: String.t()

@spec show(%{id: user_id()}, %{}, nil) :: {200, %{}, User.t()}
def show(%{id: id}, _headers, _body), do: ...

PhoenixSpectral reads the type's metadata when building the spec and adds the description field to the parameter object in the OpenAPI output.

generate_openapi(router, metadata, options)

@spec generate_openapi(module(), map(), [:pre_encoded]) ::
  {:ok, iodata() | map()} | {:error, list()}