Rolodex v0.8.0 Rolodex
Rolodex generates documentation for your Phoenix API.
Rolodex inspects a Phoenix Router and transforms the @doc
annotations on your
controller actions into documentation in the format of your choosing.
Rolodex.run/1
encapsulates the full documentation generation process. When
invoked, it will:
- Traverse your Phoenix Router
- Collect documentation data for the API endpoints exposed by your router
- Serialize the data into a format of your choosing (e.g. Swagger JSON)
- Write the serialized data out to a destination of your choosing.
Rolodex can be configured in the config/
files for your Phoenix project. See
Rolodex.Config
for more details on configuration options.
Features and resources
- Reusable components - See
Rolodex.Schema
for details on how define reusable parameter schemas. SeeRolodex.RequestBody
for details on how to use schemas in your API request body definitions. SeeRolodex.Response
for details on how to use schemas in your API response definitions. SeeRolodex.Headers
for details on how to define reusable headers for your route doc annotations and your responses. - Structured annotations - See
Rolodex.Route
for details on how to format annotations on your API route action functions for the Rolodex parser to handle - Generic serialization - The
Rolodex.Processor
behaviour encapsulates the basic steps needed to serialize API metadata into documentation. Rolodex ships with a valid OpenAPI (Swagger) JSON processor (see:Rolodex.Processors.OpenAPI
) - Generic writing - The
Rolodex.Writer
behaviour encapsulates the basic steps needed to write out formatted docs. Rolodex ships with a file writer ( see:Rolodex.Writers.FileWriter
)
High level example
# 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 [
auth: :BearerAuth,
headers: ["X-Request-ID": uuid, required: true],
query_params: [include: :string],
path_params: [user_id: :uuid],
body: MyRequestBody,
responses: %{200 => MyResponse},
metadata: [public: true],
tags: ["foo", "bar"]
]
@doc "My index action"
def index(conn, _), do: conn
end
# Your request body
defmodule MyRequestBody do
use Rolodex.RequestBody
request_body "MyRequestBody" do
desc "A request body"
content "application/json" do
schema do
field :id, :integer
field :name, :string
end
example :request, %{id: "123", name: "Ada Lovelace"}
end
end
end
# Some shared headers for your response
defmodule RateLimitHeaders do
use Rolodex.Headers
headers "RateLimitHeaders" do
header "X-Rate-Limited", :boolean, desc: "Have you been rate limited"
header "X-Rate-Limit-Duration", :integer
end
end
# Your response
defmodule MyResponse do
use Rolodex.Response
response "MyResponse" do
desc "A response"
headers RateLimitHeaders
content "application/json" do
schema MySchema
example :response, %{id: "123", name: "Ada Lovelace"}
end
end
end
# Your schema
defmodule MySchema do
use Rolodex.Schema
schema "MySchema", desc: "A schema" do
field :id, :uuid
field :name, :string, desc: "The name"
end
end
# Your Rolodex config
defmodule MyConfig do
use Rolodex.Config
def spec() do
[
title: "MyApp",
description: "An example",
version: "1.0.0",
router: MyRouter
]
end
def auth_spec() do
[
BearerAuth: [
type: "http",
scheme: "bearer"
]
]
end
def pipelines_spec() do
[
api: [
headers: ["Include-Meta": :boolean]
]
]
end
end
# In mix.exs
config :rolodex, module: MyConfig
# Then...
Application.get_all_env(:rolodex)[:module]
|> Rolodex.Config.new()
|> Rolodex.run()
# The JSON written out to file should look like
%{
"openapi" => "3.0.0",
"info" => %{
"title" => "MyApp",
"description" => "An example",
"version" => "1.0.0"
},
"paths" => %{
"/api/test" => %{
"get" => %{
"security" => [%{"BearerAuth" => []}],
"metadata" => %{"public" => true},
"parameters" => [
%{
"in" => "header",
"name" => "X-Request-ID",
"required" => true,
"schema" => %{
"type" => "string",
"format" => "uuid"
}
},
%{
"in" => "path",
"name" => "user_id",
"schema" => %{
"type" => "string",
"format" => "uuid"
}
},
%{
"in" => "query",
"name" => "include",
"schema" => %{
"type" => "string"
}
}
],
"responses" => %{
"200" => %{
"$ref" => "#/components/responses/MyResponse"
}
},
"requestBody" => %{
"$ref" => "#/components/requestBodies/MyRequestBody"
},
"tags" => ["foo", "bar"]
}
}
},
"components" => %{
"requestBodies" => %{
"MyRequestBody" => %{
"description" => "A request body",
"content" => %{
"application/json" => %{
"schema" => %{
"type" => "object",
"properties" => %{
"id" => %{"type" => "string", "format" => "uuid"},
"name" => %{"type" => "string", "description" => "The name"}
}
},
"examples" => %{
"request" => %{"id" => "123", "name" => "Ada Lovelace"}
}
}
}
}
},
"responses" => %{
"MyResponse" => %{
"description" => "A response",
"headers" => %{
"X-Rate-Limited" => %{
"description" => "Have you been rate limited",
"schema" => %{
"type" => "string"
}
},
"X-Rate-Limit-Duration" => %{
"schema" => %{
"type" => "integer"
}
}
},
"content" => %{
"application/json" => %{
"schema" => %{
"$ref" => "#/components/schemas/MySchema"
},
"examples" => %{
"response" => %{"id" => "123", "name" => "Ada Lovelace"}
}
}
}
}
},
"schemas" => %{
"MySchema" => %{
"type" => "object",
"description" => "A schema",
"properties" => %{
"id" => %{"type" => "string", "format" => "uuid"},
"name" => %{"type" => "string", "description" => "The name"}
}
}
},
"securitySchemes" => %{
"BearerAuth" => %{
"type" => "http",
"scheme" => "bearer"
}
}
}
}
Link to this section Summary
Functions
Runs Rolodex and writes out documentation to the specified destination
Link to this section Functions
Link to this function
run(config)
run(config)
run(Rolodex.Config.t()) :: :ok | {:error, any()}
run(Rolodex.Config.t()) :: :ok | {:error, any()}
Runs Rolodex and writes out documentation to the specified destination