Handling `config` and other class-level macros
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 theAction::Callbacksmodule) -
expose(viaAction::Exposable) -
accept(viaAction::Mime) -
use(viaAction::Rack) -
handle_exception(viaAction::Throwable) -
params(viaAction::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 toResponse, 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 theconfigurationobject (which is where it also resides in 1.x, with the class method just delegating toconfiguration)
To address this, I propose we:
- Restore a
handle_exceptionclass method that delegates toconfiguration - Move
accepttoconfigurationand rename itaccepted_formats, then addacceptback as a class method delegating toconfiguration. This keeps all config together in the same object, and ensures theacceptvalues are inheritable, which is not currently the case. - Leave
paramsas 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
configobjects - 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 inHanami::Action, and exposures inHanami::View. - All class-level behaviour (consisting of both the above) is inheritable.
@jodosha I'd like to go ahead and make the changes I proposed here. Are you fine with them?
I'm just going to go ahead and make these changes. I think they're sensible.