Skip to content
Closed
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#### Fixes

* [#2769](https://github.com/ruby-grape/grape/pull/2769): Always format JSON via `Grape::Json.dump` so a configured `multi_json` back-end is honored - [@ericproulx](https://github.com/ericproulx).
* Your contribution here.

### 3.3.0 (2026-06-20)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3160,7 +3160,7 @@ end

Built-in formatters are the following.

* `:json`: use object's `to_json` when available, otherwise call `MultiJson.dump`
* `:json`: serializes the object via Grape's JSON back-end (`JSON` by default, or `multi_json` when available)
* `:xml`: use object's `to_xml` when available, usually via `MultiXml`
* `:txt`: use object's `to_txt` when available, otherwise `to_s`
* `:serializable_hash`: use object's `serializable_hash` when available, otherwise fallback to `:json`
Expand Down
8 changes: 8 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
Upgrading Grape
===============

### Upgrading to >= 4.0

#### The `:json` and `:serializable_hash` formatters no longer call `to_json`

`Grape::Formatter::Json` and `Grape::Formatter::SerializableHash` previously short-circuited to `object.to_json` whenever the object responded to it. Since virtually every object responds to `to_json`, this meant `Grape::Json.dump` was effectively never reached and a configured `multi_json` back-end (e.g. `oj`) was bypassed during formatting. Both formatters now always serialize through `Grape::Json.dump`, so the JSON back-end is honored consistently (matching `Grape::ErrorFormatter::Json` and `Grape::Parser::Json`).

If you relied on a custom `to_json` for response formatting, either register your own formatter or make `Oj.mimic_JSON` (or your serializer of choice) the active back-end.

### Upgrading to >= 3.3

#### Minimum required Ruby is now 3.3
Expand Down
2 changes: 0 additions & 2 deletions lib/grape/formatter/json.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ module Grape
module Formatter
class Json < Base
def self.call(object, _env)
return object.to_json if object.respond_to?(:to_json)

::Grape::Json.dump(object)
end
end
Expand Down
1 change: 0 additions & 1 deletion lib/grape/formatter/serializable_hash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ class << self
def call(object, _env)
return object if object.is_a?(String)
return ::Grape::Json.dump(serialize(object)) if serializable?(object)
return object.to_json if object.respond_to?(:to_json)

::Grape::Json.dump(object)
end
Expand Down
Loading