lib/xapi/plug.ex

defmodule Xmeta.Xapi.Plug do
  use Plug.Router

  if Mix.env() == :dev do
    use Plug.Debugger
  end

  use Plug.ErrorHandler

  plug(Plug.Parsers,
    parsers: [:urlencoded, :json],
    json_decoder: Jason
  )

  plug(Plug.Logger, log: :debug)
  plug(:match)
  plug(:dispatch)

  @impl true
  def init(options) do
    # initialize options
    options
  end

  defp module_name_upcase(name) do
    {first,last} = String.next_grapheme(name)  
    String.upcase(first) <> last
  end

  defp format_params(params) do
    params 
      |> Map.delete("glob") 
      |>Map.delete("xapi_site") 
      |>Map.delete("xapi_router") 
      |>Map.delete("xapi_view") 
  end

  #api 路由
  match "/:xapi_site/:xapi_router/:xapi_view" do
    params = conn.params
    site = module_name_upcase(params["xapi_site"])
    router = module_name_upcase(params["xapi_router"])
    view = module_name_upcase(params["xapi_view"])

    mod =
      Module.concat(["Xapi", site, router, view])

    response = apply(mod, :call, [conn, format_params(conn.params)])
    render_json(conn, response)
  end

  match _ do
    send_resp(conn, 404, "not found")
  end

  defp render_json(conn, response) when is_map(response) do
    conn
    |> put_resp_content_type("application/json")
    |> send_resp(200, Jason.encode!(response))
  end

  defp render_json(conn, response) when is_binary(response) do
    conn
    |> send_resp(200, response)
  end
end