Packages
maru
0.10.5
0.14.0-pre.1
0.13.2
0.13.1
0.13.0
0.12.5
0.12.4
0.12.3
0.12.2
0.12.1
0.12.0
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.6
0.10.5
0.10.4
0.10.3
0.10.2
0.10.1
0.10.0
0.9.6
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.0
0.5.1
0.5.0
0.4.1
0.4.0
0.3.1
0.3.0
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
REST-like API micro-framework for elixir inspired by grape.
Current section
Files
Jump to
Current section
Files
lib/maru/builder/route.ex
defmodule Maru.Builder.Route do
@moduledoc """
Generate routes of maru router.
"""
@doc """
Generate general route defined by user within method block.
"""
def dispatch(route, env, adapter) do
pipeline = [
adapter.put_version_plug(route.version),
[{Maru.Plugs.SaveConn, [], true}],
Enum.map(route.plugs, fn p ->
{p.plug, p.options, p.guards}
end)
] |> Enum.concat |> Enum.reverse
{conn, body} = Plug.Builder.compile(env, pipeline, [])
params = quote do
Map.merge(
var!(conn).params,
Maru.Builder.Path.parse_params(
var!(conn).path_info,
unquote(adapter.path_for_params(route.path, route.version))
)
)
end
parameters_runtime = route.parameters |> Enum.map(fn p -> p.runtime end)
parser_block = quote do
Maru.Runtime.parse_params(
unquote(parameters_runtime), %{}, unquote(params)
)
end
params_block = quote do
var!(conn) =
Plug.Conn.put_private(
var!(conn),
:maru_params,
unquote(parser_block)
)
Maru.Helpers.Response.put_maru_conn(var!(conn))
end
func = exception_function(route.mount_link)
quote do
defp route(unquote(
adapter.conn_for_match(route.method, route.version, route.path)
)=unquote(conn), []) do
fn ->
case unquote(body) do
%Plug.Conn{halted: true} = conn ->
conn
%Plug.Conn{} = var!(conn) ->
unquote(params_block)
unquote(route.module).endpoint(var!(conn), unquote(route.func_id))
end
end |> unquote(func) |> apply([])
end
end
end
@doc """
Generate MethodNotAllow route for all path without `match` method.
"""
def dispatch_405(version, path, mount_link, adapter) do
method = Macro.var(:_, nil)
func = exception_function(mount_link)
quote do
defp route(unquote(
adapter.conn_for_match(method, version, path)
)=var!(conn), []) do
fn ->
Maru.Exceptions.MethodNotAllow
|> raise([method: var!(conn).method, request_path: var!(conn).request_path])
end |> unquote(func) |> apply([])
end
end
end
defp exception_function(mount_link) do
exception_modules =
Enum.filter(mount_link, fn module ->
if Module.open?(module) do
Module.get_attribute(module, :exceptions) != []
else
{:__error_handler__, 1} in module.__info__(:functions)
end
end)
quote do
fn func ->
Enum.reduce(
unquote(exception_modules),
func,
fn module, func ->
module.__error_handler__(func)
end
)
end.()
end
end
end