Always format JSON via Grape::Json.dump#2769
Conversation
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>
52d4f9d to
4d4b5d1
Compare
Danger ReportNo issues found. |
|
Test failures look legit. |
|
Closing this — I'm keeping the The premise was that
Concretely, for a 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 #2486 should be revisited with an approach that preserves |
Closes #2486.
Summary
Grape::Formatter::JsonandGrape::Formatter::SerializableHashshort-circuited toobject.to_jsonwhenever the object responded to it. Since virtually every object responds toto_json,Grape::Json.dumpwas effectively never reached during formatting — so a configuredmulti_jsonback-end (e.g.oj) was silently bypassed, inconsistent withGrape::ErrorFormatter::JsonandGrape::Parser::Json, which already go throughGrape::Json.This removes the
to_jsonshort-circuit from both formatters so JSON is always serialized throughGrape::Json.dump, honoring the configured back-end consistently.Changes
lib/grape/formatter/json.rb: dropreturn object.to_json if object.respond_to?(:to_json).lib/grape/formatter/serializable_hash.rb: drop the sameto_jsonfallback.README.md: update the:jsonformatter description.UPGRADING.md: document the behavior change (breaking).🤖 Generated with Claude Code