controller icon indicating copy to clipboard operation
controller copied to clipboard

Handling `config` and other class-level macros

Open timriley opened this issue 3 years ago • 3 comments

In hanami-controller 1.3.x, we have the following public class methods available inside Hanami::Action subclasses:

  • before, append_before, prepend_before, after, append_after, prepend_after (via the Action::Callbacks module)
  • expose (via Action::Exposable)
  • accept (via Action::Mime)
  • use (via Action::Rack)
  • handle_exception (via Action::Throwable)
  • params (via Action::Validatable)

Along with this, every action class has a class-level configuration available, which is set by the framework.

As we move to 2.0, we need to consider the overall configuration experience, to ensure it is (a) sensible on its own, (b) provides a reasonable migration path from 1.x, and (c) is coherent with hanami-view as Hanami-controller's counterpart in the overall web stack.

In hanami-controller 2.0, the configuration object is largely the same, but there's a different set of public class methods:

  • before, append_before, prepend_before, after, append_after, prepend_after
  • params
  • accept

This leaves the following 1.x class methods without direct equivalents:

  • expose — exposures have moved to Response, where they can be set with #[]=)
  • use — using rack middleware in actions has been dropped due to unwanted internal complexity (if I understand correctly)
  • handle_exception — this now exists only on the configuration object (which is where it also resides in 1.x, with the class method just delegating to configuration)

To address this, I propose we:

  • Restore a handle_exception class method that delegates to configuration
  • Move accept to configuration and rename it accepted_formats, then add accept back as a class method delegating to configuration. This keeps all config together in the same object, and ensures the accept values are inheritable, which is not currently the case.
  • Leave params as a class method (this is key behaviour, and doesn't feel like "config" at all), but update it to be inheritable, so a params defined on a parent class is copied to its children

In doing this, I think we could then outline the following principles for how we manage config and behaviour across hanami-controller and hanami-view

  • Most fine-grained configuration lives on class level config objects
  • Any key or commonly adjusted class-specific behaviour is defined by dedicated class methods. These may be backed by their own state, or may delegate to config. Examples of this are the callbacks in Hanami::Action, and exposures in Hanami::View.
  • All class-level behaviour (consisting of both the above) is inheritable.

timriley avatar Aug 02 '22 02:08 timriley

@jodosha I'd like to go ahead and make the changes I proposed here. Are you fine with them?

timriley avatar Oct 10 '22 22:10 timriley

I'm just going to go ahead and make these changes. I think they're sensible.

timriley avatar Oct 13 '22 10:10 timriley