lib/health_routes/health_router.ex

defmodule SignificaUtils.HealthRouter do
  @moduledoc """
  Simple all-in-one health router (with handlers).

  ## Usage:

  In you router, use `Phoenix.Router.html.forward/4` to use this router (or `match`).

  ```
  forward "/healthz", SignificaUtils.HealthRouter,
    repo: MyProject.Repo,
    otp_app: :my_project
  ```

  It will create 3 routes under the specified prefix (`/healthz` in the example above):

  - `/`: Returns `OK` (we include content as it is sometimes strange to have zero length responses).
  - `/db`: Uses ecto and the provided `repo` to return the `version` of the latest Ecto migration.
  - `/version`: Returns the value of the `:app_version` env, specified in your `otp_app`.
    Make sure you have used `Application.put_env/3` or defined the `app_version` in your configs:
    ```
    config :my_project,
      app_version: "1.2.3"
    ```

  """
  use Phoenix.Router

  @doc false
  def init(opts) do
    opts
  end

  @doc false
  def call(conn, opts) do
    assert_valid_opts(opts)

    conn
    |> put_private(:significa_utils_health_opts, opts)
    |> super(opts)
  end

  defp assert_valid_opts(opts) do
    otp_app = Keyword.get(opts, :otp_app)
    repo = Keyword.get(opts, :repo)

    if is_nil(otp_app) or is_nil(repo) or not is_atom(otp_app) or not is_atom(repo) do
      raise RuntimeError,
            "#{__MODULE__} requires passing valid 'otp_app' and 'repo' options."
    end
  end

  get("/", SignificaUtils.HealthController, :index)
  get("/version", SignificaUtils.HealthController, :version)
  get("/db", SignificaUtils.HealthController, :db_health)
end