Home

Awesome

BlueBird

Build Status Hex.pm Coverage Status license Deps Status

BlueBird is an api documentation builder for the Phoenix framework. The documentation is generated in the API Blueprint format from annotations in your controllers and from automated tests.

Installation

  1. Add BlueBird to your mix.exs dependencies:
defp deps do
  [{:blue_bird, "~> 0.4.0"}]
end
  1. Run mix deps.get to fetch the dependencies:
$ mix deps.get
  1. In test/test_helper.exs, start the BlueBird logger with BlueBird.start() and configure ExUnit as follows:
BlueBird.start()
ExUnit.start(formatters: [ExUnit.CLIFormatter, BlueBird.Formatter])
  1. Add the following lines to config.exs:
config :blue_bird,
  docs_path: "priv/static/docs",
  theme: "triple",
  router: AppWeb.Router
  1. Add blue_bird_info to your mix.exs to add global information:
def blue_bird_info do
  [
    host: "https://api.acme.com",
    title: "ACME API",
    description: """
                 API requires authorization. All requests must have valid
                 `auth_token`.
                 """
  ]
end
  1. Add BlueBird.Controller to your web.ex controller function:
def controller do
  quote do
    ...
    use BlueBird.Controller
    ...
  end
end
  1. Install aglio:
$ npm install aglio -g

Usage

Router

By default, documentation is only generated for routes that use the :api pipeline. You can configure which pipelines to use in the configuration.

config :blue_bird,
  pipelines: [:something_else]

Controller

Use the api/3 macro to annotate your controller functions.

defmodule AppWeb.CommentController do
  use AppWeb, :controller

  api :GET, "/posts/:post_id/comments" do
    title "List comments"
    description "Optional description"
    note "Optional note"
    warning "Optional warning"
    parameter :post_id, :integer, [description: "Post ID or slug"]
  end
  def index(conn, %{"post_id" => post_id}) do
    ...
  end
end

BlueBird groups routes by controller. By default, it uses the controller names as group names in the headings. You can change the group name of a controller by adding the apigroup macro to your controller modules. The macro can also be used to add a group description.

defmodule AppWeb.CommentController do
  use AppWeb, :controller

  apigroup "Blog Comments", "some description"
  ...
end

Tests

In your tests, select which requests and responses you want to include in the documentation by saving conn to BlueBird.ConnLogger:

test "list comments for post", %{conn: conn} do
  insert_posts_with_comments()

  conn = conn
  |> get(comments_path(conn, :index))
  |> BlueBird.ConnLogger.save(title: "Without params")

  assert json_response(conn, 200)
end

Generating the documentation

First, run your tests:

$ mix test

All conns that were saved to the ConnLogger will be processed. The documentation will be written to the file api.apib in the directory specified in the configuration. The file uses the API Blueprint format.

There are several tools that can render apib files to html. BlueBird has a mix task which uses Aglio renderer to generate an html document from the generated apib file.

$ mix bird.gen.docs

If you use BlueBird in an umbrella app, you must run the command from within the folder of the child app (e.g. apps/myapp_web).

Configuration

config.exs

The configuration options can be setup in config.exs:

config :blue_bird,
  docs_path: "priv/static/docs",
  theme: "triple",
  router: YourAppWeb.Router,
  pipelines: [:api],
  ignore_headers: ["not-wanted"]

Options

blue_bird_info()

Options

FAQ

Route is not generated after adding API annotations to the controller

Please make sure that the route you are using in the annotation matches the route from the phoenix router (including params) exactly. Run mix phoenix.routes (or mix phx.routes if Phoenix >= 1.3) and compare the routes.

Also note that only routes that use the api pipeline (or the pipelines you configured in config.exs) will be added to the documentation.

Body Parameters are not rendered

BlueBird reads the body_params from %Plug.Conn{}. This map is only set if body_params is a binary.

Example

post build_conn(), "/", Poison.encode! %{my: data}  # recommended
post build_conn(), "/", "my=data"