Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,41 +1,40 @@
---
title: Formats and MIME types
title: Formats and media types
order: 70
---

Hanami maps [over 50 of the most common MIME types][built-in-formats] to simple **format** names for you to use when configuring your actions.
Hanami maps [over 50 of the most common media types][built-in-formats] to simple **format** names for you to use when configuring your actions.

[built-in-formats]: https://github.com/hanami/controller/blob/dc5bb2a1db48b0ccf3faf52aac20eaef0fd135a3/lib/hanami/action/mime.rb#L15-L69

Configuring one or more formats for your actions will:
Accepting one or more formats from your actions will:

- Ensure the actions accept only appropriate requests based on their `Accept` or `Content-Type` headers
- Set an appropriate `Content-Type` header on responses
- For certain formats, enable automatic parsing of request bodies
- Ensure the actions accept only appropriate requests based on their `Accept` or `Content-Type` headers.
- Set an appropriate `Content-Type` header on responses.

## Configuring a format for all actions

To configure a format for all actions, use `config.actions.format` in your app class.
To accept a format for all actions, use `config.actions.format.accept` in your app class.

```ruby
# config/app.rb

module Bookshelf
class App < Hanami::App
config.actions.format :json
config.actions.formats.accept :json
end
end
```

You can also configure actions to use multiple formats:
You can also configure actions to accept multiple formats:

```ruby
config.actions.format :json, :html
config.actions.formats.accept :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.
You can also configure formats on any action class. `config.formats` in an action class is analogous to `config.actions.formats` in your app class.

```ruby
# app/actions/books/index.rb
Expand All @@ -44,7 +43,7 @@ module Bookshelf
module Actions
module Books
class Index < Bookshelf::Action
format :json # or `config.format :json`
config.formats.accept :json

def handle(request, response)
# ...
Expand All @@ -62,27 +61,27 @@ If you configure a format on a base action class, then it will be inherited by a

module Bookshelf
class Action < Hanami::Action
config.format :json
config.formats.accept :json
end
end
```

## Request acceptance

Once you've configured a format, your actions will reject certain requests that do not match the format.
Once you accept a format, your actions will reject requests that do not match the format.

The following kinds of requests will be accepted:

- No `Accept` or `Content-Type` headers
- `Accept` header that includes the format's MIME type
- No `Accept` header, but a `Content-Type` header that matches the format's MIME type
- `Accept` header that includes the format's media type
- No `Accept` header, but a `Content-Type` header that matches the format's media type

Whereas these kinds of requests will be rejected:

- `Accept` does not include the format's MIME type, rejected as `406 Not acceptable`
- No `Accept` header, but a `Content-Type` header is present and does not match the format's MIME type, rejected as `415 Unsupported media type`
- `Accept` does not include the format's media type, rejected as `406 Not acceptable`
- No `Accept` header, but a `Content-Type` header is present and does not match the format's media type, rejected as `415 Unsupported media type`

For example, if you configure `format :json`, then requests with these headers will be accepted:
For example, if you configure `formats.accept :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 `*/*`)
Expand All @@ -94,37 +93,11 @@ While requests with these headers will be rejected:
- `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.

```ruby
# 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.

```ruby
# 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.
Actions set a `Content-Type` response header based on your accepted formats along with the media 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.
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 accepts the `:html` format.

You can also assign a particular format directly on the response inside your action.

Expand Down Expand Up @@ -172,30 +145,51 @@ module Bookshelf
module Actions
module Books
class Index < Bookshelf::Action
config.default_charset "koi8-r"
config.default_charset = "koi8-r"
end
end
end
end
```

## Registering additional MIME Types
## Registering additional formats and media types

If you need your actions to work with additional MIME types, you can configure these like so:
If you need your actions to work with additional media types, you can configure these like so:

```ruby
# config/app.rb

module Bookshelf
class App < Hanami::App
config.actions.formats.add :custom, "application/custom"
config.actions.formats.register :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.
This will register the `:custom` format for the `"application/custom"` media type. Your actions can then accept this format, either at the app-level, or within specific action classes:

```ruby
# config/app.rb

module Bookshelf
class App < Hanami::App
config.actions.formats.register :custom, "application/custom"
config.actions.formats.accept :custom
end
end
```

```ruby
# app/action.rb

module Bookshelf
class Action < Hanami::Action
config.formats.accept :custom
end
end
```

You can also configure a format to map to multiple MIME types:
You can also configure a format to map to multiple media types:

```ruby
# config/app.rb
Expand All @@ -207,4 +201,4 @@ module Bookshelf
end
```

In this case, requests for both these MIME types will be accepted.
In this case, requests for both these media types will be accepted.