Rolodex v0.10.1 Rolodex.Route
Parses and collects documentation metadata for a single Phoenix API route.
new/2
generates a Rolodex.Route.t()
, a struct of route metdata passed into
a Rolodex.Processor
for serialization. This module also contains information
on how to structure @doc
annotations for your controller action functions.
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. Another valid input is a Rolodex.Schema
module. The attributes at the top-level of the schema will be serialized as
the path parameters.
Each parameter value can also specify the following: minimum
(default:
nil
), maximum
(default: nil
), default (default: nil
), and required
(default: required
).
@doc [
# Reference to a schema module
path_params: PathParamsSchema,
# Simple inline 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. Another valid input is a Rolodex.Schema
module. The attributes at the top-level of the schema will be serialized as
the query parameters.
Each query value can also specify the following: minimum
(default: nil
),
maximum
(default: nil
), default (default: nil
), and required (default:
required
).
@doc [
# Reference to a schema module
path_params: QueryParamsSchema,
# Simple inline 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
]
]
]
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 API paths. In these cases, you can document the same controller action multiple times, split across either router path or HTTP method.
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
# Same action used across multiple paths
get "/first", MyController, :index
get "/:id/second", MyController, :index
# Same action used across multiple HTTP methods
get "/search", MyController, :search
post "/search", MyController :search
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
@doc [
multi: true,
get: [
query_params: SearchQuery
responses: %{200 => MyResponse}
],
post: [
body: SearchBody,
responses: %{200 => MyResponse}
]
]
def search(conn, _), do: conn
end
Link to this section Summary
Functions
Takes a Rolodex.Router.RouteInfo.t()
and parses the doc annotation metadata
into a structured form a Rolodex.Processor
can serialize into a docs output
Link to this section Types
Link to this section Functions
new(route_info, config)
new(Rolodex.Router.RouteInfo.t() | nil, Rolodex.Config.t()) :: t() | nil
new(Rolodex.Router.RouteInfo.t() | nil, Rolodex.Config.t()) :: t() | nil
Takes a Rolodex.Router.RouteInfo.t()
and parses the doc annotation metadata
into a structured form a Rolodex.Processor
can serialize into a docs output.