I’ve built a light-weight API “monitoring endpoint” (a Phoenix project without Ecto, Brunch etc) that’s intended to be included as a dependency in other Phoenix projects. However, it seems that to get everything to work I have to do a bit of configuration in config.exs
ofthe web application that uses the monitoring endpoint; things like…
config :monitoring_endpoint, MyOrg.Monitoring.Endpoint,
http: [port: 5000],
render_errors: [view: MyOrg.Monitoring.ErrorView, accepts: ~w(json)],
server: true
I’m fine with setting the port, of course (every app will use a different one for its monitoring endpoint anyway), but… I really don’t think that setting up error rendering for the monitoring endpoint is a concern of the web application using it.
The reason it’s needed seems to be due to the default Phoenix setup, which…
- uses an HTML view
- incorrectly assumes that the view is called MyOrg.ErrorView
Can I somehow could have my monitoring endpoint override the compile-time defaults even when it’s being used as a dependency?
3 Likes
What I can think of off the top of my head is to provide eg. a Monitoring.configure(port: 5000)
call, that would be usable from mix.exs
in the web app using the monitoring endpoint, and would return all the necessary config items.
Or wait… Won’t even work, right? Since deps aren’t compiled yet at that point…
Answering my own question, for the specific case of the compile-time render_errors
configuration, it seems after some investigation that one can simply make use of Phoenix.Endpoint.RenderErrors in the router of the Phoenix-based dependency, the monitoring endpoint in my case:
defmodule MyOrg.Monitoring.Router do
use MyOrg.Monitoring.Web, :router
use Phoenix.Endpoint.RenderErrors, view: MyOrg.Monitoring.ErrorView, accepts: ~w(json)
pipeline :api do
plug :accepts, ["json"]
end
scope "/monitoring", MyOrg.Monitoring do
pipe_through :api
get "/status", StatusController, :index
end
end
For any runtime configuration issues that might come up, the answer should be more straightforward; set desired defaults in the env
section of the application configuration:
defmodule MyOrg.Monitoring.Mixfile do
use Mix.Project
# ...
def application do
[mod: {MyOrg.Monitoring, []},
applications: [:phoenix, :phoenix_pubsub, :cowboy, :logger, :gettext],
env: [some_config_key: "default value"]]
end
# ...
end
1 Like
I personally include a default config that the user can import_config
into their own then override the default values with their own. I find it the easiest to do for both me and the user. ^.^
Interesting! Can you actually include a default config from within a dependency?
Yep, I just do things like this in my base config.exs file:
import_config "../deps/somedep/config/config.exs"
I wish all deps followed this pattern, then I could just do this:
import_config "../deps/*/config/config.exs"
EDIT: Err, you said ‘from within a dependency’? Technically I think you could, by doing this:
import_config "../../../config/blah.exs"
And of course you could conditionally test for it, grab it from the environment, whatever. A config.exs file is just normal elixir after all. ^.^
1 Like
Oh, of course… Didn’t think about that approach
Thanks!
Most likely I’ll prefer to set things up in the dependency itself so that it only needs configuration that’s relevant from the perspective of the app using the dependency – but if I run across something in Phoenix etc that I just can’t seem to get past, at least I’ll have another option in my toolbox to bring out!
1 Like