Writing Phoenix Plugs as Separate Apps (in Umbrella)?

I’m working on a Phoenix app within an umbrella: it’s more or less one app per resource. That keeps things super-clean and tightly scoped, and it allows each app to operate independently because only the Phoenix app lists the other apps as dependencies.

What I’m wondering is how one can develop Phoenix Plugs as separate apps? Can anyone point me to existing packages available that do this? Mostly I can figure out how to set up the tests because Phoenix has a way of bootstrapping the conn Plug.Conn object. Any tips for this approach (or warnings against it)?

Thanks!

See the acme bank example

https://elixirforum.com/t/phoenix-generator-for-master-proxy/18856

Thanks! I got started with the plug package, but my plug is returning JSON errors in some circumstances, e.g. when an error is encountered. In those cases, I am currently using Phoenix.Controller.json() to send a JSON error response. That makes this plug dependent on Phoenix… is there a better way to “throw” an error within a plug? Is there a better way to have Phoenix send the error response?

What plug package? Do you mean master_proxy package? I suggest you do something like acme_bank example. I am running something similar to that in production and working just fine. Your main application router which delegates the the sub apps will be called through their specific endpoints. Here is a link to the specific file you might want to look into for guidance.

1 Like

I got things to work without Phoenix and only with plug as a dependency – I just had to rework some of the responses, e.g.

import Plug.Conn

def send_error!(conn, msg) do
  conn
  |> put_status(:unauthorized)
  |> Plug.Conn.put_resp_header("content-type", "application/json")
  |> Plug.Conn.resp(400, ~s({"status": 400, "message": "#{msg}}"}))
  |> halt
end

I just needed to look past the syntactic sugar of all the functions that are available when you import Phoenix.Controller

2 Likes

Good job! Since you are importing Plug.Conn both put_resp_header and resp are added directly in your module so you do not need to call them with Plug.Conn.