Modules don't compose well

Sorry, but I am still not seeing how that is different to this:

children = [
  {Plug.Cowboy, scheme: :http, plug: MyRouter, plug_opts: some_initial_options, options: [port: 4001])
]

While init is called at compile-time, call will be invoked with the custom options. But if you ignore the names and think they are init_compile and init_runtime, the result is the same (basically, for a process that runs sequentially, like a task, there is no difference between a init+run and just having init or just run).

Maybe the complaint is that Phoenix.Endpoint does not allow you do the same (which can be fixed in like 10LOC) but again, I am not sure which problem it solves. You have to build the supervision tree inside the Application callback. And how do you pass information to the application callback? Usually with the application environment. Then we are back to square one.

4 Likes

I haven’t read the details of everything in this thread but in summary Raxx has a few opinions about these things.

Configuration is passed in at boot time of a server, that handles the problem of having to do stuff on every request, but it is entirely up to the developer what shape of stuff is in config. I normally have a MyApp.Config struct and that module has setup function that will create a struct by whatever means necessary (e.g. pulling env variables).

For testing I start a separate server for each test so have the option to override any config value for the duration of the test.

I haver personally never made business logic configurable, but most side effect things that the business logic needs are passed in, e.g. sending emails, calling third party apis, db access (sometimes).

Normally I don’t test at the business logic/interaction layer but instead I have a lot of tests that create requests, pass them to the endpoint and assert on the response.

def handle_request(%{method: :GET, path: []}, config) do
  MyApp.BusinessAction.create(data_from_request, config.mailer)
  response(:ok)
end

Hope that’s helpful. It might be time for me to write a blog post about some of these things, but on the other hand I don’t feel my web layer needs to prescribe anything about how the various pieces of the whole application are composed together.

1 Like