Skip to content

Always format JSON via Grape::Json.dump#2769

Closed
ericproulx wants to merge 1 commit into
masterfrom
fix/2486-json-formatter-dump
Closed

Always format JSON via Grape::Json.dump#2769
ericproulx wants to merge 1 commit into
masterfrom
fix/2486-json-formatter-dump

Conversation

@ericproulx

Copy link
Copy Markdown
Contributor

Closes #2486.

Summary

Grape::Formatter::Json and Grape::Formatter::SerializableHash short-circuited to object.to_json whenever the object responded to it. Since virtually every object responds to to_json, Grape::Json.dump was effectively never reached during formatting — so a configured multi_json back-end (e.g. oj) was silently bypassed, inconsistent with Grape::ErrorFormatter::Json and Grape::Parser::Json, which already go through Grape::Json.

This removes the to_json short-circuit from both formatters so JSON is always serialized through Grape::Json.dump, honoring the configured back-end consistently.

Changes

  • lib/grape/formatter/json.rb: drop return object.to_json if object.respond_to?(:to_json).
  • lib/grape/formatter/serializable_hash.rb: drop the same to_json fallback.
  • README.md: update the :json formatter description.
  • UPGRADING.md: document the behavior change (breaking).

🤖 Generated with Claude Code

Grape::Formatter::Json and Grape::Formatter::SerializableHash
short-circuited to object.to_json whenever the object responded to it.
Since nearly every object responds to to_json, Grape::Json.dump was
effectively never reached and a configured multi_json back-end (e.g. oj)
was bypassed during formatting.

Remove the to_json short-circuit so both formatters always serialize
through Grape::Json.dump, honoring the JSON back-end consistently with
Grape::ErrorFormatter::Json and Grape::Parser::Json.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ericproulx ericproulx force-pushed the fix/2486-json-formatter-dump branch from 52d4f9d to 4d4b5d1 Compare June 21, 2026 06:03
@github-actions

github-actions Bot commented Jun 21, 2026

Copy link
Copy Markdown

Danger Report

No issues found.

View run

@dblock

dblock commented Jun 21, 2026

Copy link
Copy Markdown
Member

Test failures look legit.

@ericproulx

Copy link
Copy Markdown
Contributor Author

Closing this — I'm keeping the to_json short-circuit.

The premise was that object.to_json and Grape::Json.dump(object) are equivalent and the short-circuit only had the side effect of bypassing the configured multi_json back-end. That's not the case: they produce different output, so this isn't a no-op consistency fix — it's a silent serialization change.

to_json routes through each object's own JSON representation (ActiveSupport's as_json), while Grape::Json.dump (→ JSON.generate) only handles JSON primitives natively and falls back to to_s for everything else. Removing the short-circuit would change the output for Time, Date, BigDecimal, symbols, and any object defining as_json/to_json — and can even flip the string encoding.

Concretely, for a Time:

t = Time.at(0).getlocal("+00:00")

t.to_json            # => "1970-01-01T00:00:00.000+00:00"  (ISO 8601, honors as_json)
Grape::Json.dump(t)  # => "1970-01-01 00:00:00 +0000"      (Time#to_s fallback)

That's a behavior regression for anyone relying on as_json/ISO 8601 output (which is the common case with ActiveSupport loaded), and a far wider contract break than "honor the configured back-end." The consistency gain with ErrorFormatter::Json / Parser::Json doesn't justify regressing established serialization semantics, so I'd rather leave the formatters as-is.

#2486 should be revisited with an approach that preserves as_json semantics if we still want the back-end to apply in the formatter path.

@ericproulx ericproulx closed this Jun 21, 2026
@ericproulx ericproulx deleted the fix/2486-json-formatter-dump branch June 21, 2026 21:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Formatting with multi_json ?

2 participants