Skip to content

Dropping MultiJson in 1.0.3 broke Time serialization for apps using ActiveSupport #403

@Morxander

Description

@Morxander

Description

After upgrading from grape-entity 1.0.1 to 1.0.3, all Time fields in API responses changed format for apps using ActiveSupport:

  • Before (1.0.1): "2026-04-16T10:55:10.597Z" (ISO 8601)
  • After (1.0.3): "2026-04-16 10:55:10 UTC"

This is a silent breaking change for API consumers expecting ISO 8601 timestamps.

Root cause

PR #385 replaced MultiJson.dump with JSON.dump in Entity#to_json: https://github.com/ruby-grape/grape-entity/pull/385/changes#diff-dede7a9b2a44333c10da3b7b006d011d8fddfc23ebaa64b415b5686c7798d296R561

MultiJson.dump internally calls Hash#to_json, which ActiveSupport intercepts to run as_json on all values — converting Time to ISO 8601. JSON.dump bypasses ActiveSupport entirely and serializes Time via its C extension using Time#to_s.

Reproduction

require 'json'
require 'active_support'
require 'active_support/core_ext/object/json'
require 'active_support/core_ext/time'
require 'grape_entity'

class TestEntity < Grape::Entity
  expose :published_at
end

t = Time.utc(2026, 4, 16, 10, 55, 10, 597000)
obj = OpenStruct.new(published_at: t)

TestEntity.represent(obj).to_json
# grape-entity 1.0.1  => {"published_at":"2026-04-16T10:55:10.597Z"}  ✅
# grape-entity 1.0.3 => {"published_at":"2026-04-16 10:55:10 UTC"}   ❌

Environment

  • Ruby 4.0.0
  • Rails 8.0.5
  • grape-entity 1.0.3

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions