Rolodex v0.7.1 Rolodex.Route

Collects metadata associated with an API route.

new/2 takes a Phoenix.Router.Route, finds the controller action function associated with the route, and collects metadata set in the @doc annotations for the function.

Fields

  • desc (Default: "")

Set via an @doc comment

@doc [
  # Other annotations here
]
@doc "My route description"
def route(_, _), do: nil
  • id (Default: "")

Route identifier. Used as an optional unique identifier for the route.

@doc [
  id: "foobar"
]
  • body *(Default: %{})

Request body parameters. Valid inputs: Rolodex.RequestBody, or a map or keyword list describing a parameter schema. When providing a plain map or keyword list, the request body schema will be set under the default content type value set in Rolodex.Config.

@doc [
  # A shared request body defined via [`Rolodex.RequestBody`](Rolodex.RequestBody.html)
  body: SomeRequestBody,

  # Request body is a JSON object with two parameters: `id` and `name`
  body: %{id: :uuid, name: :string},
  body: [id: :uuid, name: :string],

  # Same as above, but here the top-level data structure `type` is specified
  # so that we can add `desc` metadata to it
  body: %{
    type: :object,
    desc: "The request body",
    properties: %{id: :uuid}
  },
  body: [
    type: :object,
    desc: "The request body",
    properties: [id: :uuid]
  ],

  # Request body is a JSON array of strings
  body: [:string],

  # Same as above, but here the top-level data structure `type` is specified
  body: %{type: :list, of: [:string]},
  body: [type: :list, of: [:string]],

  # All together
  body: [
    id: :uuid,
    name: [type: :string, desc: "The name"],
    ages: [:number]
  ]
]
  • auth (Default: %{})

Define auth requirements for the route. Valid input is a single atom or a list of auth patterns. We only support logical OR auth definitions: if you provide a list of auth patterns, Rolodex will serialize this as any one of those auth patterns is required.

@doc [
  # Simplest: auth pattern with no scope patterns
  auth: :MySimpleAuth,

  # One auth pattern with some scopes
  auth: [OAuth: ["user.read"]],

  # Multiple auth patterns
  auth: [
    :MySimpleAuth,
    OAuth: ["user.read"]
  ]
]
  • headers (Default: %{})

Request headers. Valid inputs: a module that has defined shared heads via Rolodex.Headers, or a map or keyword list, where each key is a header name and each value is a description of the value in the form of a an atom, a map, or a list.

Each header value can also specify the following: minimum (default: nil), maximum (default: nil), default (default: nil), and required (default: required).

@doc [
  # Shared headers
  headers: MySharedRequestHeaders

  # Simplest header description: a name with a concrete type
  headers: %{"X-Request-ID" => :uuid},
  headers: ["X-Request-ID": :uuid],

  # Specifying metadata for the header value
  headers: %{
    "X-Request-ID" => %{
      type: :integer,
      required: true,
      minimum: 0,
      maximum: 10,
      default: 0
    }
  },
  headers: [
    "X-Request-ID": [
      type: :integer,
      required: true,
      minimum: 0,
      maximum: 10,
      default: 0
    ]
  ],

  # Multiple header values
  headers: [
    "X-Request-ID": :uuid,
    "Custom-Data": [
      id: :uuid,
      checksum: :string
    ]
  ]
]
  • path_params (Default: %{})

Parameters in the route path. Valid input is a map or keyword list, where each key is a path parameter name and each value is a description of the value in the form of an atom, a map, or a list.

Each parameter value can also specify the following: minimum (default: nil), maximum (default: nil), default (default: nil), and required (default: required).

@doc [
  # Simplest path parameter description: a name with a concrete type
  path_params: %{id: :uuid},
  path_params: [id: :uuid],

  # Specifying metadata for the path value
  path_params: %{
    id: %{
      type: :integer,
      required: true,
      minimum: 0,
      maximum: 10,
      default: 0
    }
  },
  path_params: [
    id: [
      type: :integer,
      required: true,
      minimum: 0,
      maximum: 10,
      default: 0
    ]
  ]
]
  • query_params (Default: %{})

Query parameters. Valid input is a map or keyword list, where each key is a query parameter name and each value is a description of the value in the form of an atom, a map, or a list.

Each query value can also specify the following: minimum (default: nil), maximum (default: nil), default (default: nil), and required (default: required).

@doc [
  # Simplest query parameter description: a name with a concrete type
  query_params: %{id: :uuid},
  query_params: [id: :uuid],

  # Specifying metadata for the parameter value
  query_params: %{
    id: %{
      type: :integer,
      required: true,
      minimum: 0,
      maximum: 10,
      default: 0
    }
  },
  query_params: [
    id: [
      type: :integer,
      required: true,
      minimum: 0,
      maximum: 10,
      default: 0
    ]
  ],

  # Multiple query values
  query_params: [
    id: :uuid,
    some_object: [
      id: :uuid,
      checksum: :string
    ]
  ]
]
  • responses (Default: %{})

Response(s) for the route action. Valid input is a map or keyword list, where each key is a response code and each value is a description of the response in the form of a Rolodex.Response, an atom, a map, or a list.

@doc [
  responses: %{
    # A response defined via a reusable schema
    200 => MyResponse,

    # Use `:ok` for simple success responses
    200 => :ok,

    # Response is a JSON object with two parameters: `id` and `name`
    200 => %{id: :uuid, name: :string},
    200 => [id: :uuid, name: :string],

    # Same as above, but here the top-level data structure `type` is specified
    # so that we can add `desc` metadata to it
    200 => %{
      type: :object,
      desc: "The response body",
      properties: %{id: :uuid}
    },
    200 => [
      type: :object,
      desc: "The response body",
      properties: [id: :uuid]
    ],

    # Response is a JSON array of a schema
    200 => [MyResponse],

    # Same as above, but here the top-level data structure `type` is specified
    200 => %{type: :list, of: [MyResponse]},
    200 => [type: :list, of: [MyResponse]],

    # Response is one of multiple possible results
    200 => %{type: :one_of, of: [MyResponse, OtherResponse]},
    200 => [type: :one_of, of: [MyResponse, OtherResponse]],
  }
]
  • metadata (Default: %{})

Any metadata for the route. Valid input is a map or keyword list.

  • tags (Default: [])

Route tags. Valid input is a list of strings.

Handling Route Pipelines

In your Rolodex.Config, you can specify shared route parameters for your Phoenix pipelines. For each route, if it is part of a pipeline, new/2 will merge in shared pipeline config data into the route metadata

# Your Phoenix router
defmodule MyRouter do
  pipeline :api do
    plug MyPlug
  end

  scope "/api" do
    pipe_through [:api]

    get "/test", MyController, :index
  end
end

# Your controller
defmodule MyController do
  @doc [
    headers: ["X-Request-ID": uuid],
    responses: %{200 => :ok}
  ]
  @doc "My index action"
  def index(conn, _), do: conn
end

# Your config
config = %Rolodex.Config{
  pipelines: %{
    api: %{
      headers: %{"Shared-Header" => :string}
    }
  }
}

# Parsed route
%Rolodex.Route{
  headers: %{
    "X-Request-ID" => %{type: :uuid},
    "Shared-Header" => %{type: :string}
  },
  responses: %{200 => :ok}
}

Handling Multi-Path Actions

Sometimes, a Phoenix controller action function will be used for multiple router paths. Sometimes, the documentation for each path will differ significantly. If you would like for each router path to pair with its own docs, you can use the multi flag.

# Your router
defmodule MyRouter do
  scope "/api" do
    get "/first", MyController, :index
    get "/:id/second", MyController, :index
  end
end

# Your controller
defmodule MyController do
  @doc [
    # Flagged as an action with multiple docs
    multi: true,

    # All remaining top-level keys should be router paths
    "/api/first": [
      responses: %{200 => MyResponse}
    ],
    "/api/:id/second": [
      path_params: [
        id: [type: :integer, required: true]
      ],
      responses: ${200 => MyResponse}
    ]
  ]
  def index(conn, _), do: conn
end

Link to this section Summary

Functions

Checks to see if the given route matches any filter(s) stored in Rolodex.Config

Looks up a Phoenix.Router.Route controller action function, parses any doc annotations, and returns as a struct

Link to this section Types

Link to this type

t()
t() :: %Rolodex.Route{
  auth: map(),
  body: map(),
  desc: binary(),
  headers: %{},
  id: binary(),
  metadata: %{},
  path: binary(),
  path_params: %{},
  pipe_through: [atom()],
  query_params: %{},
  responses: %{},
  tags: [binary()],
  verb: atom()
}

Link to this section Functions

Link to this function

matches_filter?(route, filters)
matches_filter?(t(), any()) :: boolean()

Checks to see if the given route matches any filter(s) stored in Rolodex.Config.

Link to this function

new(phoenix_route, config)

Looks up a Phoenix.Router.Route controller action function, parses any doc annotations, and returns as a struct.