View Source OpenApiSpex.ControllerSpecs (open_api_spex v3.21.2)
Macros for defining operation specs, shared operation tags, and shared security specs in a Phoenix controller.
Example
Here is an example Phoenix controller that uses the ControllerSpecs Operation specs:
defmodule MyAppWeb.UserController do
use Phoenix.Controller
use OpenApiSpex.ControllerSpecs
alias MyAppWeb.Schemas.{UserParams, UserResponse}
tags ["users"]
security [%{}, %{"petstore_auth" => ["write:users", "read:users"]}]
operation :update,
summary: "Update user",
parameters: [
id: [
in: :path,
description: "User ID",
type: :integer,
example: 1001
]
],
request_body: {"User params", "application/json", UserParams},
responses: [
ok: {"User response", "application/json", UserResponse}
]
def update(conn, %{"id" => id}) do
json(conn, %{
data: %{
id: id,
name: "joe user",
email: "joe@gmail.com"
}
})
end
end
If you use Elixir Formatter, :open_api_spex
can be added to the :import_deps
list in the .formatter.exs
file of your project to make parentheses of the
macros optional.
.formatter.exs
:
[
import_deps: [:open_api_spex]
]
parameters
parameters
is a keyword list (or map) of request parameters (not body parameters). They each represent the
OpenAPI Parameter Object.
There is a convenient shortcut :type
for base data types supported by open api
parameters: [
id: [in: :query, type: :integer, required: true, description: "User ID", example: 1001]
]
This is equivalent to:
parameters: [
id: [in: :query, schema: %OpenApiSpex.Schema{type: :integer}, required: true, description: "User ID", example: 1001]
]
The keyword value is the parameter name. Each value in the keyword list correlates to a field in the OpenAPI ParameterObject.
request_body
The request_body
defines the OpenAPI RequestBodyObject.
The request_body
takes a tuple that is 2-4 elements in length. The elements of the tuple are:
- The RequestBody
description
field. - The RequestBody
content
field, consisting of a mapping of content types to theirMediaType
objects, or a simple content type string (e.g., "application/json").
Or:content: "application/json"
Or:content: %{"application/text" => [example: "some text!"]}
content: %{"application/text" => [%OpenApiSpex.MediaType{example: "some text!"}]}
- The default schema of the RequestBody.
- A keyword list of options.
responses
The responses
key defines the OpenAPI Responses Object
The responses
value is a keyword list or map that maps the HTTP status to a
ResponseObject.
If the the responses is defined using keyword list syntax, the HTTP status codes can be replaced with their text equivalents:
responses: [
ok: {"User response", "application/json", MyAppWeb.Schemas.UserResponse},
unprocessable_entity: {"Bad request parameters", "application/json", MyAppWeb.Schemas.BadRequestParameters},
not_found: {"Not found", "application/json", MyAppWeb.Schemas.NotFound}
]
The full set of atom keys are defined in Plug.Conn.Status.code/1
.
Alternately, the HTTP status codes can be specified directly:
responses: %{
200 => {"User response", "application/json", MyAppWeb.Schemas.UserResponse},
422 => {"Bad request parameters", "application/json", MyAppWeb.Schemas.BadRequestParameters},
404 => {"Not found", "application/json", MyAppWeb.Schemas.NotFound}
}
The ResponseObject is represented as a tuple that is 2-4 elements in length. The elements of the tuple are:
- The ResponseObject
description
field. - The ResponseObject
content
field, consisting of a mapping of content types to theirMediaType
objects, or a simple content type string (e.g., "application/json").
Or:content: %{"application/json" => [example: "{[]}"]}
content: "application/json"
- The default schema of the response body.
- A keyword list of options to add to the
OpenApiSpex.Response
orOpenApiSpex.MediaType
structs that are generated.
Summary
Functions
Defines an Operation spec for a controller action.
Define an Operation for a controller action.
Defines security requirements shared by all operations defined in a controller.
Defines a list of tags that all operations in a controller will share.
Functions
Defines an Operation spec for a controller action.
Example
operation :update,
summary: "Update user",
description: "Updates a user record from the given ID path parameter and request body parameters.",
parameters: [
id: [
in: :path,
description: "User ID",
type: :integer,
example: 1001
]
],
request_body: {"User params", "application/json", UserParams},
responses: [
ok: {"User response", "application/json", UserResponse}
],
security: [%{}, %{"petstore_auth" => ["write:pets", "read:pets"]}],
tags: ["users"]
Options
These options correlate to the
Operation fields specified in the Open API spec.
One difference however, is that the fields defined in Open API use camelCase
naming,
while the fields used in ControllerSpecs
use snake_case
to match Elixir's convention.
summary
The operation summaryparameters
The endpoint's parameters. The syntax forparameters
can take multiple forms:The common form is a keyword list, where each key is the parameter name, and the value is a keyword list of options that correlate to the fields in an Open API Parameter Object. For example:
parameters: [ id: [ in: :path, description: "User ID", type: :integer, example: 1001 ] ]
A
parameters
list can also contain references to parameter schemas. There are two ways to do that:parameters: [ "$ref": "#/components/parameters/user_id" # or %OpenApiSpex.Reference{"$ref": "#/components/parameters/user_id"} ]
request_body
The endpoint's request body. There are multiple ways to specify a request body:- A three or four-element tuple:
The tuple consists of the following:request_body: { "User update request body", "application/json", UserUpdateRequest, required: true }
- The description
- The content-type
- An Open API schema. This can be a schema module that implements the
OpenApiSpex.Schema
behaviour, or anOpenApiSpex.Schema
struct. - A optional keyword list of options. There is only one option available,
and that is
required: boolean
.
- A three or four-element tuple:
responses
The endpoint's responses, for each HTTP status code the endpoint may respond with. Multiple syntaxes are supported:A common syntax is a keyword list, where each key is the textual name of an HTTP status code. For example:
[ ok: {"User response", "application/json", User}, not_found: {"User not found", "application/json", NotFound} ]
The list of names and their code mappings is defined in
Plug.Conn.Status.code/1
.If a map is used, the keys can either be the same atom keys used in the keyword syntax (
%{ok: ...}
), or they can be integers representing the HTTP status code directly:responses: %{ 200 => {"User response", "application/json", User}, 404 => {"User not found", "application/json", NotFound} }
Each response can be a three-element tuple:
responses: [ ok: {"User response", "application/json", User} # Or ok: {"User response", "application/json", %OpenApiSpex.Schema{...}} ]
This tuple consists of:
- A Description string
- A content-type string
- An Open API schema. This can be a schema module that implements the
OpenApiSpex.Schema
behaviour, or anOpenApiSpex.Schema
struct. - An optional
Keyword
list with the following optional key/values: a. example: an example string b. examples: a list of example strings c. headers: aMap
with string keys defining the header name and anOpenApiSpex.Header
struct as a value.
If the response represents an empty response, the definition value can be a single string representing the response description. For example:
responses: [ no_content: "Empty response" ]
A response can also be defined as an
OpenApiSpex.RequestBody
struct. In fact, all response body syntaxes resolve to this struct.
Additional fields: There are other Operation fields that can be specified that are not described here. See
OpenApiSpex.Operation
for all the fields.
Define an Operation for a controller action.
See OpenApiSpex.ControllerSpecs
for usage and examples.
Defines security requirements shared by all operations defined in a controller.
See Security Requirement Object spec
and OpenApiSpex.SecurityRequirement
for more information.
Defines a list of tags that all operations in a controller will share.
Example
tags ["users"]
All operations defined in the controller will inherit the tags specified by this call. If an operation defines its own tags, the tags in this call will be appended to the operation's tags.