Reusing swagger parameters
View SourceWhen building an API it can be common to have headers or parameters that are common to multiple actions.
Scenario
For example, let's say we've got two endpoints:
GET /projectsGET /books
Both of these endpoints can be sorted using by sort_by and sort_direction parameters and both require an Authorization header.
Here's what the swagger spec in our ProjectsController would look like:
defmodule ProjectsController do
use PhoenixSwagger
swagger_path :index do
get "/projects"
produces "application/json"
parameter("Authorization", :header, :string, "OAuth2 access token", required: true)
parameters do
sort_by :query, :string, "The property to sort by"
sort_direction :query, :string, "The sort direction", enum: [:asc, :desc], default: :asc
company_id :string, :query, "The company id"
end
end
endOur BooksController swagger would look very similar, also defining the Authorization header and the sort_by and sort_direction headers.
Extracting parameters into a module for reuse
The swagger_path macro layer is actually just some syntactic sugar over regular elixir functions, intended to be easily extended. Any function that accepts a %PhoenixSwagger.Path.PathObject{} as its first argument and returns an updated %PathObject{} can be used in the swagger_path macro.
Knowing this, we can easily extract some of the common logic into a module and reuse it in our controllers.
defmodule CommonParameters do
@moduledoc "Common parameter declarations for phoenix swagger"
alias PhoenixSwagger.Path.PathObject
import PhoenixSwagger.Path
def authorization(path = %PathObject{}) do
path |> parameter("Authorization", :header, :string, "OAuth2 access token", required: true)
end
def sorting(path = %PathObject{}) do
path
|> parameter(:sort_by, :query, :string, "The property to sort by")
|> parameter(:sort_direction, :query, :string, "The sort direction", enum: [:asc, :desc], default: :asc)
end
endThis can also be done using the parameters macro:
def sorting(path = %PathObject{}) do
parameters path do
sort_by :query, :string, "The property to sort by"
sort_direction :query, :string, "The sort direction", enum: [:asc, :desc], default: :asc
end
endReusing the common parameters
Now, instead of defining these parameters in every controller, we can just reference the CommonParameters module:
defmodule ProjectsController do
use PhoenixSwagger
swagger_path :index do
get "/users"
produces "application/json"
CommonParameters.authorization
CommonParameters.sorting
parameters do
company_id :string, :query, "The company id"
end
end
end