Hi,
I’m working on an API and I need to maintain previous versions. My current design is:
- a
Plugwhich extract the version from Headers, validates it, and stores it inconn.assigns - a pattern matching in my controllers to branch on different versions when needed
For example, in my controllers, I have things like:
defmodule MyApp.MyController do
use MyApp.Web, :controller
def create(conn=%Plug.Conn{assigns: %{api_version: 20160422}}, %{"data" => %{"attributes" => params}}) do
# ...
end
end
It works well but typing the whole %Plug.Conn{assigns: %{api_version: 20160422}} every time I need to specify a version is very tedious, and clutter a bit the function definition. Moreover, if I decide to change my assign variable, I would have to update a bunch of functions.
I thought it would be great to create a guard for this, an example of what I wanted:
defmodule MyApp.MyController do
use MyApp.Web, :controller
def create(conn, %{"data" => %{"attributes" => params}}) when api_version(conn, 20160422) do
# ...
end
end
Unfortunately the list of functions available available to create guards (GitHub - itsgreggreg/elixir_quick_reference: Quick reference for the Elixir programming language and standard library. · GitHub) doesn’t allow me to work with Map.
Do you have any suggestion about how I could make it work?
If guards are not possible, another solution which came in my mind, is to defined a default new, create,… to process the version and call the same method with one more parameter. For example:
# my_app/web.ex
# ... in def controller do
def create(conn=%Plug.Conn{assigns: %{api_version: version}}, params) do
create(conn, version, params)
end
# my_app/my_controller.ex
defmodule MyApp.MyController do
use MyApp.Web, :controller
def create(conn, 20160422, %{"data" => %{"attributes" => params}}) do
# ...
end
# or, if I don't care about the version
def create(conn, _version, %{"data" => %{"attributes" => params}}) do
# ...
end
end
Thanks for you suggestions/feedbacks ![]()






















