Current section

28 Versions

Jump to

Compare versions

6 files changed
+68 additions
-44 deletions
  @@ -31,4 +31,4 @@
31 31 {<<"name">>,<<"jason">>},
32 32 {<<"optional">>,false},
33 33 {<<"requirement">>,<<"~> 1.0">>}]]}.
34 - {<<"version">>,<<"0.3.0">>}.
34 + {<<"version">>,<<"0.3.1">>}.
  @@ -9,6 +9,21 @@ defmodule Camarero do
9 9
10 10 [
11 11 quote(location: :keep, do: @after_compile({Camarero, :handler!})),
12 + quote(
13 + location: :keep,
14 + do:
15 + @handler_fq_name(
16 + Keyword.get(
17 + unquote(opts),
18 + :as,
19 + Module.concat(__MODULE__ |> Module.split() |> hd(), "Camarero")
20 + )
21 + )
22 + ),
23 + quote(
24 + location: :keep,
25 + do: defstruct(handler_fq_name: @handler_fq_name, scaffold: unquote(scaffold))
26 + ),
12 27 case scaffold do
13 28 :full ->
14 29 quote(
  @@ -32,16 +47,35 @@ defmodule Camarero do
32 47
33 48 # idea by Dave Thomas https://twitter.com/pragdave/status/1077775018942185472
34 49 def handler!(env, _bytecode) do
35 - if Code.ensure_compiled?(Camarero.Handler) do
36 - :code.purge(Camarero.Handler)
37 - :code.delete(Camarero.Handler)
50 + fq_name = struct(env.module).handler_fq_name
51 +
52 + handler_name = Module.concat(fq_name, Handler)
53 + endpoint_name = Module.concat(fq_name, Endpoint)
54 +
55 + endpoints =
56 + [endpoint_name | Application.get_env(:camarero, :endpoints, [])]
57 + |> MapSet.new()
58 + |> MapSet.to_list()
59 +
60 + Application.put_env(:camarero, :endpoints, endpoints, persistent: true)
61 +
62 + if Code.ensure_compiled?(handler_name) do
63 + :code.purge(handler_name)
64 + :code.delete(handler_name)
38 65 end
39 66
40 - ast = handler_ast()
67 + handler_ast = handler_ast()
68 + endpoint_ast = endpoint_ast(handler_name)
41 69
42 70 Module.create(
43 - Camarero.Handler,
44 - quote(do: unquote(Macro.expand(ast, env))),
71 + handler_name,
72 + quote(do: unquote(Macro.expand(handler_ast, env))),
73 + Macro.Env.location(env)
74 + )
75 +
76 + Module.create(
77 + endpoint_name,
78 + quote(do: unquote(Macro.expand(endpoint_ast, env))),
45 79 Macro.Env.location(env)
46 80 )
47 81 end
  @@ -125,7 +159,9 @@ defmodule Camarero do
125 159 })
126 160 )
127 161 else
128 - {module, param} -> response!(conn, module, param)
162 + {module, param} ->
163 + IO.puts("Accessing #{unquote(full_path)} dynamically. Consider compiling routes.")
164 + response!(conn, module, param)
129 165 end
130 166 end
131 167
  @@ -160,37 +196,20 @@ defmodule Camarero do
160 196 end
161 197 end
162 198
163 - defmodule Handler do
164 - use Plug.Router
199 + defp endpoint_ast(handler) do
200 + quote do
201 + @moduledoc false
165 202
166 - @root "/" <> (:camarero |> Application.get_env(:root, "") |> String.trim("/"))
203 + use Plug.Builder
204 + plug(Plug.Logger)
167 205
168 - get("#{@root}/*full_path") do
169 - send_resp(
170 - conn,
171 - 503,
172 - Jason.encode!(%{
173 - error: "Warming up...",
174 - path: Enum.join([@root | full_path], "/")
175 - })
206 + plug(Plug.Parsers,
207 + parsers: [:json],
208 + pass: ["application/json"],
209 + json_decoder: Jason
176 210 )
211 +
212 + plug(unquote(handler))
177 213 end
178 -
179 - plug(:dispatch)
180 - end
181 -
182 - defmodule Endpoint do
183 - @moduledoc false
184 -
185 - use Plug.Builder
186 - plug(Plug.Logger)
187 -
188 - plug(Plug.Parsers,
189 - parsers: [:json],
190 - pass: ["application/json"],
191 - json_decoder: Jason
192 - )
193 -
194 - plug(Camarero.Handler)
195 214 end
196 215 end
  @@ -19,12 +19,16 @@ defmodule Camarero.Application do
19 19
20 20 # List all child processes to be supervised
21 21 children = [
22 - Plug.Cowboy.child_spec(
23 - scheme: Keyword.get(cowboy, :scheme, @default_scheme),
24 - plug: Camarero.Endpoint,
25 - options: options
26 - ),
27 22 {Camarero.Catering, [catering]}
23 + | :camarero
24 + |> Application.get_env(:endpoints, [])
25 + |> Enum.map(
26 + &Plug.Cowboy.child_spec(
27 + scheme: Keyword.get(cowboy, :scheme, @default_scheme),
28 + plug: &1,
29 + options: options
30 + )
31 + )
28 32 ]
29 33
30 34 # See https://hexdocs.pm/elixir/Supervisor.html
  @@ -100,6 +100,7 @@ defmodule Camarero.Catering do
100 100 """)
101 101 else
102 102 Camarero.Catering.Routes.put(route, module)
103 + # Camarero.handler!(%{module: %{handler_fq_name: module}}, nil)
103 104 end
104 105 end
105 106 end
  @@ -1,7 +1,7 @@
1 1 defmodule Camarero.Carta.Heartbeat do
2 2 @moduledoc """
3 - Ready-to-go implementation of the hearbeat; responds with 299 / empty object
3 + Ready-to-go implementation of the hearbeat; responds with 200 / empty object
4 4 at `"/api/v1/heartbeat"` endpoint.
5 5 """
6 - use Camarero, scaffold: :full
6 + use Camarero, as: Camarero
7 7 end
Loading more files…