Skip to content

Preserve subscription serializer round trips - #5723

Open
ydah wants to merge 1 commit into
rmosolgo:masterfrom
ydah:preserve-subscription-serializer-round-trips
Open

Preserve subscription serializer round trips#5723
ydah wants to merge 1 commit into
rmosolgo:masterfrom
ydah:preserve-subscription-serializer-round-trips

Conversation

@ydah

@ydah ydah commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

This follows up on #5722 with two additional cases where GraphQL::Subscriptions::Serialize.dump and .load don't round-trip their input.

First, arrays are treated as GlobalID arrays based only on their first element:

value = [GlobalIDUser.new("a"), 1, "two"]

GraphQL::Subscriptions::Serialize.load(
  GraphQL::Subscriptions::Serialize.dump(value)
)
# => TypeError: no implicit conversion of String into Integer

The loader attempts to read __gid__ from every remaining element. Other mixed values may produce nil IDs and cause GlobalID::Locator.locate_many to return incorrect results or fail.

Second, Symbol and String keys with the same name are collapsed when keys are converted to strings:

value = { a: 1, "a" => 2 }

dumped = GraphQL::Subscriptions::Serialize.dump(value)
# => {"a":2,"__sym_keys__":["a"]}

GraphQL::Subscriptions::Serialize.load(dumped)
# => { a: 2 }

This PR only uses the batched GlobalID::Locator.locate_many path when every array element is a GlobalID wrapper. Mixed arrays use the existing recursive loading path, while homogeneous GlobalID arrays retain batched lookup.

For Hash key collisions, Symbol-keyed values are stored separately in the existing __sym_keys__ metadata. Hashes without collisions retain their existing serialized format.

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.

1 participant