V2.0: Formats and MIME types
Hanami maps over 50 of the most common MIME types to simple format names for you to use when configuring your actions.
Configuring one or more formats for your actions will:
- Ensure the actions accept only appropriate requests based on their
Accept
orContent-Type
headers - Set an appropriate
Content-Type
header on responses - For certain formats, enable automatic parsing of request bodies
Configuring a format for all actions
To configure a format for all actions, use config.actions.format
in your app class.
# config/app.rb
module Bookshelf
class App < Hanami::App
config.actions.format :json
end
end
You can also configure actions to use multiple formats:
config.actions.format :json, :html
Configuring a format for particular actions
You can also configure a format on any action class. format
in an action class is analogous to config.actions.format
in your app class, just as config
in an action is analogous to config.actions
in your app.
# app/actions/books/index.rb
module Bookshelf
module Actions
module Books
class Index < Bookshelf::Action
format :json # or `config.format :json`
def handle(request, response)
# ...
end
end
end
end
end
If you configure a format on a base action class, then it will be inherited by all its subclasses.
# app/action.rb
module Bookshelf
class Action < Hanami::Action
config.format :json
end
end
Request acceptance
Once you’ve configured a format, your actions will reject certain requests that do not match the format.
The following kinds of requests will be accepted:
- No
Accept
orContent-Type
headers Accept
header that includes the format’s MIME type- No
Accept
header, but aContent-Type
header that matches the format’s MIME type
Whereas these kinds of requests will be rejected:
Accept
does not include the format’s MIME type, rejected as406 Not acceptable
- No
Accept
header, but aContent-Type
header is present and does not match the format’s MIME type, rejected as415 Unsupported media type
For example, if you configure format :json
, then requests with these headers will be accepted:
Accept: application/json
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
(courtesy of the*/*
)Content-Type: application/json
While requests with these headers will be rejected:
Accept: text/html
Accept: text/html,application/xhtml+xml,application/xml;q=0.9
Content-Type: application/x-www-form-urlencoded
Parsing JSON request bodies
If you configure :json
as your action format in the app, then any requests with Content-Type: application/json
will have their request bodies parsed and made available as request params.
# config/app.rb
module Bookshelf
class App < Hanami::App
config.actions.format :json
end
end
You can also enable the body parser manually if required.
# config/app.rb
module Bookshelf
class App < Hanami::App
config.middleware.use :body_parser, :json
end
end
Response format
Actions set a Content-Type
response header based on your configured formats along with the MIME type and charset of the incoming request.
For example, if a request’s Accept
header is "text/html,application/xhtml+xml,application/xml;q=0.9"
, the action will return a content type of "text/html; charset=utf-8"
, assuming that the action is configured with the :html
format.
You can also assign a particular format directly on the response inside your action.
# app/actions/books/index.rb
module Bookshelf
module Actions
module Books
class Index < Bookshelf::Action
def handle(request, response)
response.format = :json # or response.format = "application/json"
response.body = {result: "OK"}.to_json
end
end
end
end
end
Default character set
The default character set for actions is utf-8
. This is included in your response’s Content-Type
header:
Content-Type: application/json; charset=utf-8
You can configure this app-wide or on a per-action basis.
# config/app.rb
module Bookshelf
class App < Hanami::App
config.actions.default_charset = "koi8-r"
end
end
# app/actions/books/index.rb
module Bookshelf
module Actions
module Books
class Index < Bookshelf::Action
config.default_charset "koi8-r"
end
end
end
end
Registering additional MIME Types
If you need your actions to work with additional MIME types, you can configure these like so:
# config/app.rb
module Bookshelf
class App < Hanami::App
config.actions.formats.add :custom, "application/custom"
end
end
This will add the :custom
format for the "application/custom"
MIME type and also configure your actions to use this format.
You can also configure a format to map to multiple MIME types:
# config/app.rb
module Bookshelf
class App < Hanami::App
config.actions.formats.add :json, ["application/json+scim", "application/json"]
end
end
In this case, requests for both these MIME types will be accepted.