Introducing Radex
Radex is a new hex package that lets you document Phoenix APIs similar to rspec_api_documentation. By generating your API documentation to your tests, you can be sure that your documentation remains up-to-date as your API changes or evolves. It is like DocTests but at the endpoint of your Phoenix API.
We like this new approach because it generates the same output as rspec_api_documentation json does, while the existing approach generates markdown and swagger/slate.
Radex uses a simple declarative approach to define the resources in your REST API. Then passing your Plug.Conn
into Radex's record
function tells Radex to build a JSON file with the information about the request. You can then continue to test your response as you normally would in any other ConnCase
test.
Getting Started
As expected, start by adding Radex to your mix.exs
file:
defp deps do
[
{:radex, "~> 0.1.0"},
]
end
Then within a controller test for your API controllers, using your application's <Name>Web.ConnCase
, describe an endpoint and use Radex.Endpoint
defmodule MyAPIWeb.MyControllerTest do
use MyAPIWeb.ConnCase
describe "index" do
use Radex.Endpoint
Then you can define some metadata about the request...
# inside the `describe`
use Radex.Endpoint
@resource "Items"
@route {"GET", "/items"}
...and define your test, passing a Plug.Conn
through your controller and into Radex's record
# inside the `describe`
test "Viewing Items", %{conn: conn} do
conn =
conn
|> get(items_path(conn, :index))
|> record()
Finally, you can ensure the response is correct, testing your API and ensuring that the recorded interaction is correct.
# Inside the `test`
assert json_response(conn, 200)["data"] == []
end
end
end
To generate documentation simply run the tests with a special formatter...
mix test --formatter Radex.Formatter
...or integrate it into your Mix file...
defp aliases do
[
"radex.test": ["test --formatter Radex.Formatter"],
]
end
...and then run:
MIX_ENV=test mix radex.test
A Full Example
defmodule StorefrontWeb.OrderControllerTest do
use StorefrontWeb.ConnCase
alias Storefront.Orders
alias Storefront.Orders.Order
# ...
describe "index" do
use Radex.Endpoint
@resource "Orders"
@route {"GET", "/orders"}
test "Viewing orders", %{conn: conn} do
conn =
conn
|> get(order_path(conn, :index))
|> record()
assert json_response(conn, 200)["data"] == []
end
end
describe "create order" do
use Radex.Endpoint
@resource "Orders"
@route {"POST", "/orders"}
# Define parameters to show in the documentation
@parameter {"order[email]", "Email address for the Order"}
@parameter {"order[paid]", "Status of the order", type: :boolean}
test "renders order when data is valid", %{conn: conn} do
# Override the default description to let your test
# title to be more descriptive
radex_metadata(description: "Creating an order")
conn =
conn
|> post(order_path(conn, :create), order: @create_attrs)
|> record()
assert %{"id" => id} = json_response(conn, 201)["data"]
conn =
conn
|> get(order_path(conn, :show, id))
|> record()
assert json_response(conn, 200)["data"] == %{
"id" => id,
"email" => "some email",
"paid" => true}
end
# This will not be documented as nothing is recorded
test "renders errors when data is invalid", %{conn: conn} do
conn =
conn
|> post(order_path(conn, :create), order: @invalid_attrs)
assert json_response(conn, 422)["errors"] != %{}
end
end
end
Learning More and Helping Out
Here are all the Radex links:
We are open to suggestions and pull requests, and we will continue to evolve the library as we integrate it into new and existing projects.