Complete, fast and testable actions for Rack
- [Tom de Bruijn, Tim Riley] When an action is called, add the action instance to the Rack environment under the
"hanami.action_instance"
key (#446)
- [Tim Riley, Krzysztof Piotrowski] Add support for using full dry-validation contracts for action param validation, via
Hanami::Action.contract
(#453, #454)
- Drop support for Ruby 3.0
- [Luca Guidi] Ensure Rack compatibility of
Hanami::Action::Response#send_file
(#431)
- [Luca Guidi]
Hanami::Action::Config#root
: don't check realpath existence to simplify the boot process of Hanami (#429)
- [Tim Riley] Add
Request#session_enabled?
andResponse#session_enabled?
(#423)
- [Adam Lassek] Params Pattern Matching
- [Adam Lassek, Luca Guidi] Allow to
halt
using aSymbol
:halt :unauthorized
- [Adam Lassek, Luca Guidi] Introduce
Hanami::Action::Response#status=
to accept anInteger
or aSymbol
- [Pat Allan] Ensure action accepting the request with a custom MIME Type
- [Luca Guidi] Halting with an unknown HTTP code will raise a
Hanami::Action::UnknownHttpStatusError
- [Luca Guidi] Fix error message for missing format (MIME Type)
- [Luca Guidi] Official support for Ruby 3.2
- [Tim Riley] Use Zeitwerk to autoload the gem
- [Tim Riley] Introduce
Hanami::Action::Config#formats
. Useconfig.actions.formats.add(:json)
. Custom formats can useconfig.actions.formats.add(:graphql, ["application/graphql"])
- [Tim Riley] Changed
Hanami::Action::Config#format
semantic: it's no longer used to add custom MIME Types, but as a macro to setup the wanted format for action(s) - [Tim Riley] Removed
Hanami::Action::Config#default_request_format
and#default_response_format
, use#format
for both - [Tim Riley] Removed
Hanami::Action::Config#accept
, use#format
- [Tim Riley] Simplify assignment of response format:
response.format = :json
(wasresponse.format = format(:json)
)
- [Tim Riley] Add
Response#flash
, and delgate to request object for bothResponse#session
andResponse#flash
, ensuring the same objects are used when accessed via either request or response (#399)
- [Benjamin Klotz] When a params validation schema is provided (in a
params do
block), only return the validated params fromrequest.params
(#375) - [Sean Collins] Handle dry-schema's messages hash now being frozen by default (#391)
- [Tim Riley] When
Action.accept
is declared (orAction::Config.accepted_formats
configured), return a 406 error if anAccept
request header is present but is not acceptable. In the absence of anAccept
header, return a 415 error if aContent-Type
header is present but not acceptable. If neither header is provided, accept the request. (#396) - [Tim Riley] Add
Action.handle_exception
class method as a shortcut forHanami::Action::Config#handle_exception
(#394) - [Tim Riley] Significantly reduce memory usage by leveraging recent dry-configurable changes, and relocating
accepted_formats
,before_callbacks
,after_callbacks
inheritable attributes toconfig
(#392) - [Tim Riley] Make params validation schemas (defined in
params do
block) inheritable to subclasses (#394) - [Benhamin Klotz, Tim Riley] Raise
Hanami::Action::MissingSessionError
with a friendly message ifRequest#session
,Request#flash
,Response#session
orResponse#flash
are called for an action that does not already includeHanami::Action:Session
mixin (#379 via #395)
- [Benjamin Klotz] Using
Hanami::Action.params
without havinghanami-validations
installed now returns a user-friendly error - [Narinda Reeders] Ensure HEAD responses to send empty body, but preserve headers
- [Narinda Reeders] Ensure HEAD redirect responses to return redirect headers
- [Andrew Croome] Do not automatically render halted requests
- [Tim Riley] Removed automatic integration of
Hanami::Action
subclasses with their surrounding Hanami application. Action base classes within Hanami apps should inherit fromHanami::Application::Action
instead.
- [Luca Guidi] Official support for Ruby: MRI 3.1
- [Luca Guidi] Drop support for Ruby: MRI 2.6, and 2.7.
- [Sean Collins] Align with Rack list of HTTP supported status. Added:
103
,306
,421
,425
,451
, and509
. Removed:418
,420
,444
,449
,450
,451
,499
,598
,599
.
- [Philip Arndt] Added "rss" ("application/rss+xml") to list of supported MIME types
- [Luca Guidi] Manage Content Security Policy (CSP) defaults and new API via
Hanami::Action::ApplicationConfiguration#content_security_policy
- [Tim Riley & Marc Busqué] Provide access to routes inside all application actions via
Hanami::Action::ApplicationAction#routes
- [Luca Guidi] Automatically include session behavior in
Hanami::Action
when sessions are enabled via Hanami application config - [Sean Collins] Pass exposures from action to view
- [Tim Riley] (Internal) Updated settings to use updated
setting
API in dry-configurable 0.13.0 - [Sean Collins] Move automatic view rendering from
handle
tofinish
- [Luca Guidi] Official support for Ruby: MRI 3.0
- [Tim Riley] Introduced
Hanami::Action::ApplicationAction
- [Tim Riley] Introduced
Hanami::Action::Configuration
- [Tim Riley] Introduced
Hanami::Action::ApplicationConfiguration
- [Tim Riley] Auto-inject a paired view into any
Hanami::Action::ApplicationAction
instance - [Tim Riley] Auto-render
Hanami::Action::ApplicationAction
subclasses that don't implement#handle
- [Tim Riley] Enable CSRF protection automatically when HTTP sessions are enabled
- [Luca Guidi] Ensure
Hanami::Action::Response#renderable?
to returnfalse
when body is set - [Andrew Croome] Ensure
Hanami::Action.accept
to use RackCONTENT_TYPE
for the before callback check
- [Luca Guidi] Drop support for Ruby: MRI 2.5.
- [Tim Riley] Removed
Hanami::Action.handle_exception
in favor ofHanami::Action.config.handle_exception
- [Tim Riley] Rewritten
Hanami::Action::Flash
, based on Roda'sFlashHash
- [Luca Guidi]
Hanami::Action::Request#session
to access the HTTP session as it was originally sent - [Luca Guidi]
Hanami::Action::Request#cookies
to access the HTTP cookies as they were originally sent - [Luca Guidi & Tim Riley] Allow to build a deep inheritance chain for actions
- [Luca Guidi] Drop support for Ruby: MRI 2.3, and 2.4.
- [Luca Guidi]
Hanami::Action
is a superclass - [Luca Guidi]
Hanami::Action#initialize
requires aconfiguration:
keyword argument - [Luca Guidi]
Hanami::Action#initialize
returns a frozen action instance - [Tim Riley]
Hanami::Action
subclasses must implement#handle
instead of#call
- [Luca Guidi]
Hanami::Action#handle
acceptsHanami::Action::Request
andHanami::Action::Response
- [Luca Guidi]
Hanami::Action#handle
returnsHanami::Action::Response
- [Luca Guidi] Removed
Hanami::Controller.configure
,.configuration
,.duplicate
, and.load!
- [Luca Guidi] Removed
Hanami::Action.use
to mount Rack middleware at the action level - [Luca Guidi]
Hanami::Controller::Configuration
changed syntax from DSL style to setters (eg.Hanami::Controller::Configuration.new { |c| c.default_request_format = :html }
) - [Luca Guidi]
Hanami::Controller::Configuration#initialize
returns a frozen configuration instance - [Luca Guidi] Removed
Hanami::Controller::Configuration#prepare
- [Luca Guidi] Removed
Hanami::Action.configuration
- [Luca Guidi] Removed
Hanami::Action.configuration.handle_exceptions
- [Luca Guidi] Removed
Hanami::Action.configuration.default_request_format
in favor of#default_request_format
- [Luca Guidi] Removed
Hanami::Action.configuration.default_charset
in favor of#default_charset
- [Luca Guidi] Removed
Hanami::Action.configuration.format
to register a MIME Type for a single action. Please use the configuration. - [Luca Guidi] Removed
Hanami::Action.expose
in favor ofHanami::Action::Response#[]=
and#[]
- [Luca Guidi] Removed
Hanami::Action#status=
in favor ofHanami::Action::Response#status=
- [Luca Guidi] Removed
Hanami::Action#body=
in favor ofHanami::Action::Response#body=
- [Luca Guidi] Removed
Hanami::Action#headers
in favor ofHanami::Action::Response#headers
- [Luca Guidi] Removed
Hanami::Action#accept?
in favor ofHanami::Action::Request#accept?
- [Luca Guidi] Removed
Hanami::Action#format
in favor ofHanami::Action::Response#format
- [Luca Guidi] Introduced
Hanami::Action#format
as factory to assign response format:res.format = format(:json)
orres.format = format("application/json")
- [Luca Guidi] Removed
Hanami::Action#format=
in favor ofHanami::Action::Response#format=
- [Gustavo Caso]
Hanami::Action.accept
now looks at requestContent-Type
header to accept/deny a request - [Luca Guidi] Removed
Hanami::Action#request_id
in favor ofHanami::Action::Request#id
- [Gustavo Caso] Removed
Hanami::Action#parsed_request_body
in favor ofHanami::Action::Request#parsed_body
- [Luca Guidi] Removed
Hanami::Action#head?
in favor ofHanami::Action::Request#head?
- [Luca Guidi] Removed
Hanami::Action#status
in favor ofHanami::Action::Response#status=
and#body=
- [Luca Guidi] Removed
Hanami::Action#session
in favor ofHanami::Action::Response#session
- [Luca Guidi] Removed
Hanami::Action#cookies
in favor ofHanami::Action::Response#cookies
- [Luca Guidi] Removed
Hanami::Action#flash
in favor ofHanami::Action::Response#flash
- [Luca Guidi] Removed
Hanami::Action#redirect_to
in favor ofHanami::Action::Response#redirect_to
- [Luca Guidi] Removed
Hanami::Action#cache_control
,#expires
, and#fresh
in favor ofHanami::Action::Response#cache_control
,#expires
, and#fresh
, respectively - [Luca Guidi] Removed
Hanami::Action#send_file
and#unsafe_send_file
in favor ofHanami::Action::Response#send_file
and#unsafe_send_file
, respectively - [Luca Guidi] Removed
Hanami::Action#errors
- [Gustavo Caso] Removed body cleanup for
HEAD
requests - [Luca Guidi]
Hanami::Action
callback hooks now acceptHanami::Action::Request
andHanami::Action::Response
arguments - [Luca Guidi] When an exception is raised, it won't be caught, unless it's handled
- [Luca Guidi]
Hanami::Action
exception handlers now acceptHanami::Action::Request
,Hanami::Action::Response
, and exception arguments
- [Luca Guidi] Official support for Ruby: MRI 2.7
- [Luca Guidi] Support
rack
2.1 - [Luca Guidi] Support for both
hanami-validations
1 and 2
- [Ian Ker-Seymer] Ensure
Etag
to work whenIf-Modified-Since
is sent from browser and upstream proxy setsLast-Modified
automatically.
- [Luca Guidi] Official support for Ruby: MRI 2.6
- [Luca Guidi] Support
bundler
2.0+
- [Gustavo Caso] Swappable JSON backed for
Hanami::Action::Flash
based onHanami::Utils::Json
- [Luca Guidi] Official support for JRuby 9.2.0.0
- [Yuji Ueki] Ensure that if
If-None-Match
orIf-Modified-Since
response HTTP headers are missing,Etag
orLast-Modified
headers will be in response HTTP headers. - [Gustavo Caso] Don't show flash message for the request after a HTTP redirect.
- [Gustavo Caso] Ensure
Hanami::Action::Flash#each
,#map
, and#empty?
to not reference stale flash data.
- [Gustavo Caso] Deprecate
Hanami::Action#parsed_request_body
- [Gustavo Caso] Introduce
Hanami::Action::Flash#each
and#map
- [Luca Guidi] Official support for Ruby: MRI 2.5
- [Sergey Fedorov] Introduce
Hanami::Action.content_type
to accept/reject requests according to theirContent-Type
header.
- [wheresmyjetpack] Raise meaningful exception when trying to access
session
orflash
andHanami::Action::Session
wasn't included.
- [Luca Guidi] Ensure
Hanami::Action#send_file
and#unsafe_send_file
to runafter
action callbacks - [Luca Guidi] Ensure Rack env to have the
REQUEST_METHOD
key set toGET
during actions unit tests
- [Luca Guidi] Introduce
Hanami::Action::CookieJar#each
to iterate through action'scookies
- [Luca Guidi] Introduce
Hanami::Action::Params::Errors#add
to add errors not generated by params validations
- [Marcello Rocha] Ensure validation params to be symbolized in all the environments
- [Marcello Rocha] Fix regression (
1.0.0
) about MIME type priority, during the evaluation of a weightedAccept
HTTP header
- [Luca Guidi]
Action#flash
is now public API
- [Marcello Rocha] Add
Action#unsafe_send_file
to send files outside of the public directory of a project
- [Anton Davydov] Ensure HTTP Cache to not crash when
HTTP_IF_MODIFIED_SINCE
andHTTP_IF_NONE_MATCH
have blank values - [Luca Guidi] Keep flash values after a redirect
- [Craig M. Wellington & Luca Guidi] Ensure to return 404 when
Action#send_file
cannot find a file with a globbed route - [Luca Guidi] Don't mutate Rack env when sending files
- [Luca Guidi] Official support for Ruby: MRI 2.4
- [Marcello Rocha & Luca Guidi] Avoid MIME type conflicts for
Action#format
detection - [Matias H. Leidemer & Luca Guidi] Ensure
Flash
to return only fresh data - [Luca Guidi] Ensure
session
keys to be accessed as symbols in action unit tests
- [Anton Davydov & Luca Guidi] Make it work only with Rack 2.0
- [Thorbjørn Hermansen] Don't pollute Rack env's
rack.exception
key if an exception is handled - [Luca Guidi] Add
flash
to the default exposures
- [Marion Duprey] Allow
BaseParams#get
to read (nested) arrays
- [Russell Cloak] Respect custom formats when referenced by HTTP
Accept
- [Kyle Chong] Don't symbolize raw params
- [Luca Guidi] Let
BaseParams#get
to accept a list of keys (symbols) instead of string with dot notation (params.get(:customer, :address, :city)
instead ofparams.get('customer.address.city')
)
- [Kyle Chong] Introduced
parsed_request_body
for action - [Luca Guidi] Introduced
Hanami::Action::BaseParams#each
- [Ayleen McCann] Use default content type when
HTTP_ACCEPT
is*/*
- [Kyle Chong] Don't stringify uploaded files
- [Kyle Chong] Don't stringify params values when not necessary
- [akhramov & Luca Guidi] Raise
Hanami::Controller::IllegalExposureError
when try to expose reserved words:params
, andflash
.
- [Luca Guidi] Introduced
Hanami::Action::Params#error_messages
which returns a flat collection of full error messages
- [Luca Guidi] Params are deeply symbolized
- [Artem Nistratov] Send only changed cookies in HTTP response
- [Luca Guidi] Drop support for Ruby 2.0 and 2.1. Official support for JRuby 9.0.5.0+.
- [Luca Guidi] Param validations now require you to add
hanami-validations
inGemfile
. - [Luca Guidi] Removed "indifferent access" for params. Since now on, only symbols are allowed.
- [Luca Guidi] Params are immutable
- [Luca Guidi] Params validations syntax has changed
- [Luca Guidi]
Hanami::Action::Params#errors
now returns a Hash. Keys are symbols representing invalid params, while values are arrays of strings with a message of the failure. - [Vasilis Spilka] Made
Hanami::Action::Session#errors
public
- [Anatolii Didukh] Optimise memory usage by freezing MIME types constant
- [Luca Guidi] Renamed the project
- [Alfonso Uceda] Ensure
rack.session
cookie to not be sent twice when bothLotus::Action::Cookies
andRack::Session::Cookie
are used together
- [Luca Guidi] Reference a raised exception in Rack env's
rack.exception
. Compatibility with exception reporting SaaS.
- [Cainã Costa] Ensure Rack environment to be always available for sessions unit tests
- [Luca Guidi] Ensure superclass exceptions to not shadow subclasses during exception handling (eg.
CustomError
handler will take precedence overStandardError
)
- [Luca Guidi] Removed
Lotus::Controller::Configuration#default_format
- [Cainã Costa] Made
Lotus::Action#session
a public method for improved unit testing - [Karim Tarek] Introduced
Lotus::Controller::Error
and let all the framework exceptions to inherit from it.
- [Luca Guidi] Allow to force custom headers for responses that according to RFC shouldn't include them (eg 204). Override
#keep_response_header?(header)
in action
- [Theo Felippe] Added configuration entries:
#default_request_format
anddefault_response_format
. - [Wellington Santos] Error handling to take account of inherited exceptions.
- [Theo Felippe] Deprecated
#default_format
in favor of:#default_request_format
.
- [Luca Guidi] Security protection against Cross Site Request Forgery (CSRF).
- [Matthew Bellantoni] Ensure nested params to be correctly coerced to Hash.
- [Alfonso Uceda Pompa & Luca Guidi] Introduced
Lotus::Action#send_file
- [Alfonso Uceda Pompa] Set automatically
Expires
option for cookies when it's missing butMax-Age
is present. Compatibility with old browsers.
- [Luca Guidi] Ensure
Lotus::Action::Params#to_h
to return::Hash
at the top level
- [Luca Guidi] Ensure proper automatic
Content-Type
working well with Internet Explorer. - [Luca Guidi] Ensure
Lotus::Action#redirect_to
to return::String
for Rack servers compatibility.
- [Alfonso Uceda Pompa] Prevent
Content-Type
andContent-Lenght
to be sent when status code requires no body (eg.204
). This is for compatibility withRack::Lint
, not with RFC 2016. - [Luca Guidi] Ensure
Lotus::Action::Params#to_h
to return::Hash
- [Erol Fornoles]
Action.use
now accepts a block - [Alfonso Uceda Pompa] Introduced
Lotus::Controller::Configuration#cookies
as default cookie options. - [Alfonso Uceda Pompa] Introduced
Lotus::Controller::Configuration#default_headers
as default HTTP headers to return in all the responses. - [Luca Guidi] Introduced
Lotus::Action::Params#get
as a safe API to access nested params.
- [Alfonso Uceda Pompa]
redirect_to
now is a flow control method: it terminates the execution of an action, including the callbacks.
- [Alfonso Uceda Pompa] Callbacks: introduced
append_before
(alias ofbefore
),append_after
(alias ofafter
),prepend_before
andprepend_after
. - [Alfonso Uceda Pompa] Introduced
Lotus::Action::Params#raw
which returns unfiltered data as it comes from an HTTP request. - [Alfonso Uceda Pompa]
Lotus::Action::Rack.use
now fully supports Rack middleware, by mounting an internalRack::Builder
instance. - [Simone Carletti]
Lotus::Action::Throwable#halt
now accepts an optional message. If missing it falls back to the corresponding HTTP status message. - [Steve Hodgkiss] Nested params validation
- [Luca Guidi] Ensure HEAD requests will return empty body
- [Stefano Verna] Ensure HTTP status codes with empty body won't send body and non-entity headers.
- [Luca Guidi] Only dump exceptions in
rack.errors
if handling is turned off, or the raised exception is not managed. - [Luca Guidi] Ensure params will return coerced values
- [Lasse Skindstad Ebert] Introduced
Action#request
which returns an instance aRack::Request
compliant object:Lotus::Action::Request
.
- [Steve Hodgkiss] Ensure params to return coerced values
- [Luca Guidi] Introduced
Action#request_id
as unique identifier for an incoming HTTP request - [Luca Guidi] Introduced
Lotus::Controller.load!
as loading framework entry point - [Kir Shatrov] Allow to define a default charset (
default_charset
configuration) - [Kir Shatrov] Automatic content type with charset (eg
Content-Type: text/html; charset=utf-8
) - [Michał Krzyżanowski] Allow to specify custom exception handlers: procs or methods (
exception_handler
configuration) - [Karl Freeman & Lucas Souza] Introduced HTTP caching (
Cache-Control
,Last-Modified
, ETAG, Conditional GET, expires) - [Satoshi Amemiya] Introduced
Action::Params#to_h
and#to_hash
- [Luca Guidi] Added
#params
and#errors
as default exposures - [Luca Guidi] Introduced complete params validations
- [Luca Guidi & Matthew Bellantoni] Allow to whitelist params
- [Luca Guidi & Matthew Bellantoni] Allow to define custom classes for params via
Action.params
- [Krzysztof Zalewski] Introduced
Action#format
as query method to introspect the requested mime type - [Luca Guidi] Official support for Ruby 2.2
- [Trung Lê] Renamed
Configuration#modules
to#prepare
- [Luca Guidi] Update HTTP status codes to IETF RFC 7231
- [Luca Guidi] When
Lotus::Controller
is included, don't inject code - [Luca Guidi] Removed
Controller.action
as a DSL to define actions - [Krzysztof Zalewski] Removed
Action#content_type
in favor of#format=
which accepts a symbol (eg.:json
) - [Fuad Saud] Reduce method visibility where possible (Ruby
private
andprotected
)
- [Luca Guidi] Don't let exposures definition to override existing methods
- [Luca Guidi] Introduced
Controller.configure
andController.duplicate
- [Luca Guidi] Introduced
Action.use
, that let to use a Rack middleware as a before callback – [Luca Guidi] Allow to define a default mime type when the request isAccept: */*
(default_format
configuration) – [Luca Guidi] Allow to register custom mime types and associate them to a symbol (format
configuration) - [Luca Guidi] Introduced
Configuration#handle_exceptions
to associate exceptions to HTTP statuses - [Damir Zekic] Allow developers to toggle exception handling (
handle_exceptions
configuration) - [Luca Guidi] Introduced
Controller::Configuration
- [Luca Guidi] Official support for Ruby 2.1
- [Luca Guidi]
Lotus::Action::Params
doesn't inherit fromLotus::Utils::Hash
anymore - [Luca Guidi]
Lotus::Action::CookieJar
doesn't inherit fromLotus::Utils::Hash
anymore - [Luca Guidi] Make HTTP status messages compliant with IANA and Rack
- [Damir Zekic] Moved
#throw
override logic into#halt
, which keeps the same semantic
- [Krzysztof Zalewski] Reference exception in
rack.errors
- [Luca Guidi] Introduced
Action.accept
to whitelist accepted mime types - [Luca Guidi] Introduced
Action#accept?
as a query method for the current request - [Luca Guidi] Allow to whitelist handled exceptions and associate them to an HTTP status
- [Luca Guidi] Automatic
Content-Type
- [Luca Guidi] Use
throw
as a control flow which understands HTTP status - [Luca Guidi] Introduced opt-in support for HTTP/Rack cookies
- [Luca Guidi] Introduced opt-in support for HTTP/Rack sessions
- [Luca Guidi] Introduced HTTP redirect API
- [Luca Guidi] Introduced callbacks for actions: before and after
- [Luca Guidi] Introduced exceptions handling with HTTP statuses
- [Luca Guidi] Introduced exposures
- [Luca Guidi] Introduced basic actions compatible with Rack
- [Luca Guidi] Official support for Ruby 2.0