Swagger integration to phoenix
Elixir
Latest commit 892be55 Jan 7, 2017 @0xAX 0xAX committed on GitHub Merge pull request #37 from frodeaa/parentheses
fix warning about missing parentheses

README.md

PhoenixSwagger Build Status

PhoenixSwagger is the library that provides swagger integration to the phoenix web framework. The PhoenixSwagger generates Swagger specification for Phoenix controllers and validates the requests.

Installation

PhoenixSwagger provides phoenix.swagger.generate mix task for the swagger-ui json file generation that contains swagger specification that describes API of the phoenix application.

You just need to add the swagger DSL to your controllers and then run this one mix task to generate the json files.

To use PhoenixSwagger with a phoenix application just add it to your list of dependencies in the mix.exs file:

def deps do
  [{:phoenix_swagger, "~> 0.3.0"}]
end

Now you can use phoenix_swagger to generate swagger-ui file for you application.

Usage

To generate Info Object you must provide swagger_info/0 function in your mix.exs file. This function returns a keyword list that contains Info Object fields:

def swagger_info do
  [version: "0.0.0", title: "My awesome phoenix application"]
end

The version and title are mandatory fields. By default the version will be 0.0.1 and the title will be <enter your title> if you will not provide swagger_info/0 function.

Fields that can be in the swagger_info:

Name Required Type Default value
title true string <enter your title>
version true string 0.0.1
description false string
termsOfService false string
contact false [name: "...", url: "...", email:"..."]
license false [name: "...", url: "..."]

PhoenixSwagger provides swagger_model/2 macro that generates swagger specification for the certain phoenix controller.

Example:

use PhoenixSwagger

swagger_model :index do
  description "Short description"
  parameter :query, :id, :integer, :required, "Property id"
  responses 200, "Description"
end

def index(conn, _params) do
  posts = Repo.all(Post)
  render(conn, "index.json", posts: posts)
end

The swagger_model macro takes two parameters:

  • Name of controller action;
  • do block that contains swagger definitions.

The PhoenixSwagger supports three definitions:

  1. The description takes one elixir's String and provides short description for the given controller action.

  2. The parameter provides description of the routing parameter for the given action and may take five parameters:

  • The location of the parameter. Possible values are query, header, path, formData or body. [required];
  • The name of the parameter. [required];
  • The type of the parameter. Allowed only swagger data types [required];
  • Determines whether this parameter is mandatory, just remove it if a parameter non-required;
  • Description of a parameter. Can be elixir's String or function/0 that returns elixir's string;

Note that order of parameters is important now.

And the third definition is responses that takes three parameters (third parameter is not mandatory) and generates definition of the response for the given controller action. The first argument is http status code and has :integer data type. The second is the short description of the response. The third non-mandatory field is a schema of the response. It must be elixir function/0 that returns a map in a swagger schema format.

For example:

use PhoenixSwagger

swagger_model :get_person do
  description "Get persons according to the age"
  parameter :query, :id, :integer, :required
  responses 200, "Description", schema
end

def schema do
  %{type: :array, title: "Persons",
    items:
      %{title: "Person", type: :object, properties: %{ name: %{type: :string}}}
   }
  end

def get_person_schema(conn, _params) do
    ...
    ...
    ...
end

That's all. Recompile your app mix phoenix.server, then run the phoenix.swagger.generate mix task for the swagger-ui json file generation into directory with phoenix application:

mix phoenix.swagger.generate

As the result there will be swagger.json file into root directory of the phoenix application. To generate swagger file with the custom name/place, pass it to the main mix task:

mix phoenix.swagger.generate ~/my-phoenix-api.json

For more informantion, you can find swagger specification here.

Validator

Besides generator of swagger schemas, the phoenix_swagger provides validator of input parameters of resources.

Suppose you have following resource in your schema:

...
...
"/history": {
    "get": {
        "parameters": [
        {
            "name": "offset",
            "in": "query",
            "type": "integer",
            "format": "int32",
            "description": "Offset the list of returned results by this amount. Default is zero."
        },
        {
            "name": "limit",
            "in": "query",
            "type": "integer",
            "format": "int32",
            "description": "Integer of items to retrieve. Default is 5, maximum is 100."
        }]
     }
}
...
...

Before usage of swagger validator, add the PhoenixSwagger.Validator.Supervisor to the supervisor tree of your application.

The phoenix_swagger provides PhoenixSwagger.Validator.parse_swagger_schema/1 API to load a swagger schema by the given path or list of paths. This API should be called during application startup to parse/load a swagger schema.

After this, the PhoenixSwagger.Validator.validate/2 can be used to validate resources.

For example:

iex(1)> Validator.validate("/history", %{"limit" => "10"})
{:error,"Type mismatch. Expected Integer but got String.", "#/limit"}

iex(2)> Validator.validate("/history", %{"limit" => 10, "offset" => 100})
:ok

Besides validate/2 API, the phoenix_swagger validator can be used via Plug to validate intput parameters of your controllers.

Just add PhoenixSwagger.Plug.Validate plug to your router:

pipeline :api do
  plug :accepts, ["json"]
  plug PhoenixSwagger.Plug.Validate
end

scope "/api", MyApp do
  pipe_through :api
  post "/users", UsersController, :send
end