Current section
28 Versions
Jump to
Current section
28 Versions
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…