Added
-
Parse request bodies based on formats config. (@timriley in #500, #503, #511, @cllns in #508)
Parsers for multipart form bodies and JSON are included by default. These require
formats.accept :htmlandformats.accept :jsonrespectively. When no formats are configured, multipart form bodies are parsed if found.Custom parsers may be registered via e.g.
formats.register(:custom, "application/custom", parser: ->(body, env) { ... })or directly viaformats.body_parsers["application/custom"] = parser.Parsed body keys are deeply symbolized. Non-hash bodies are wrapped in
{_: parsed_body}. -
Full JRuby support. (@katafrakt in #498)
Changed
-
Renamed gem from hanami-controller to hanami-action. You should now
require "hanami-action"orrequire "hanami/action". (@timriley in #507, @cllns in df365b5) -
Check for the dry-validation gem (instead of hanami-validations, which is now retired) before loading
Action.paramsandAction.contractsupport. (@timriley in #505) -
Cache the action’s resolved configuration as a frozen
Datasnapshot (via dry-configurable’s#to_data) at initialization, avoiding repeated config lookups on the request hot path for improved memory usage and speed. Required bumpingdry-configurableto~> 1.4. (@cllns in #512)Possibly breaking: the action’s config is now finalized (frozen) when the action is initialized, so mutating it from instance code is no longer possible. This was only ever an undocumented side-effect of implementation, not a supported pattern.
-
Cut per-request allocations on the
Hanami::Action#callhot path, roughly halving allocations and increasing throughput ~1.5–2.5× per action invocation. A minimal action drops from 51 to 16 allocations (69% fewer, 2.45× faster); an action with formats negotiating anAcceptheader drops from 95 to 61 allocations (36% fewer, 1.55× faster). (@cllns in #514) -
Require Ruby 3.3 or newer.
Removed
-
Removed deprecated format config methods:
Action.format,config.format,config.formats.add,config.formats.values. (@timriley in #504) -
Removed
Hanami::Action::Params.paramsand support for defining a contract by subclassingHanami::Action::Params. If you are subclassingHanami::Action::Params, take your params block and move it into aDry::Validation::Contractsubclass. Then pass this contract class toHanami::Action.paramsorHanami::Action.contract. (@timriley in #513)# Before # class SignupParams < Hanami::Action::Params # params do # required(:email).filled(:str?) # end # end # After class SignupContract < Dry::Validation::Contract params do required(:email).filled(:str?) end end class Signup < Hanami::Action params SignupParams end