Add versioning to your Elixir Plug and Phoenix built API's.
The package can be installed by adding :versionary
to your list of dependencies
in mix.exs
:
def deps do
[
{:versionary, "~> 0.3"}
]
end
def MyAPI.Router do
use Plug.Router
plug Versionary.Plug.VerifyHeader, versions: ["application/vnd.app.v1+json"]
plug Versionary.Plug.EnsureVersion, handler: MyAPI.MyErrorHandler
plug :match
plug :dispatch
end
It's possible to verify versions against configured MIME types. If multiple MIME types are passed and at least one matches the version will be considered valid.
config :mime, :types, %{
"application/vnd.app.v1+json" => [:v1],
"application/vnd.app.v2+json" => [:v2]
}
plug Versionary.Plug.VerifyHeader, accepts: [:v1, :v2]
Please note that whenever you change media type configurations you must
recompile the mime
library.
To force mime
to recompile run mix deps.clean --build mime
.
When a version has been verified :version
and :raw_version
private keys will
be added to the conn. These keys will contain version that has been verified.
The :version
key may contain either the string version provided by the
request or, if configured, the MIME extension. The :raw_version
key will
always contain the string version provided by the request.
Versionary is just a plug. That means Versionary works with Phoenix out of the
box. However, if you'd like Versionary to render a Phoenix error view when
verification fails use Versionary.Plug.PhoenixErrorHandler
.
defmodule MyAPI.Router do
use MyAPI.Web, :router
pipeline :api do
plug Versionary.Plug.VerifyHeader, accepts: [:v1, :v2]
plug Versionary.Plug.EnsureVersion, handler: Versionary.Plug.PhoenixErrorHandler
end
scope "/", MyAPI do
pipe_through :api
get "/my_controllers", MyController, :index
end
end
You can pattern match which version of a controller action to run based on the
:version
(or :raw_version
) private key provided by the conn.
defmodule MyAPI.MyController do
use MyAPI, :controller
def index(%{private: %{version: [:v1]}} = conn, _params) do
render(conn, "index.v1.json", %{})
end
def index(%{private: %{version: [:v2]}} = conn, _params) do
render(conn, "index.v2.json", %{})
end
end
Verify that the version passed in to the request as a header is valid. If the version is not valid then the request will be flagged.
This plug will not handle an invalid version. If you would like to halt the
request and handle an invalid version please see
Versionary.Plug.EnsureVersion
.
accepts
- a list of strings or atoms representing versions registered as
MIME types. If at least one of the registered versions is valid then the
request is considered valid.
versions
- a list of strings representing valid versions. If at least one of
the provided versions is valid then the request is considered valid.
header
- the header used to provide the requested version (Default: Accept
)
Checks to see if the request has been flagged with a valid version. If the version is valid, the request continues, otherwise the request will halt and the handler will be called to process the request.
handler
- the module used to handle a request with an invalid version
(Default: Versionary.Plug.ErrorHandler)
Behaviour for handling requests with invalid versions. You can create your own custom handler with this behaviour.
Copyright (c) 2017 Sticksnleaves
This library is licensed under the MIT license.