feat: implement the URL search params serialization standard - #553
Merged
Conversation
Port @seamapi/url-search-params-serializer to Ruby: a UrlSearchParams pair collection with WHATWG form encoding and UTF-16 code unit sort, a serializer with ECMAScript number formatting and JavaScript toISOString date formatting, and the Seam::NULL sentinel distinguishing an explicit JSON null from an omitted parameter. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017p9TwdqYv9ccnv7nGvpfsp
Query params are built by a Faraday params encoder that applies the serializer, so requests carry the exact encoding, ordering, and number formatting the Seam API parses; Faraday's default encoder dropped the '=' from empty-array params, silently turning an empty filter into no filter. Request bodies replace the Seam::NULL sentinel with nil before JSON encoding, and generated methods now document nullable parameters with Seam::Null in their types, consuming the blueprint isNullable flag. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017p9TwdqYv9ccnv7nGvpfsp
Verify the Ruby serializer byte for byte against the TypeScript reference implementation over hand-built, structural-fuzz, and float-fuzz fixtures, and round-trip the output through @seamapi/url-search-params-parser in strict mode. The harness needs Node and the reference implementation, so it lives in dev/conformance outside the shipped gem. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017p9TwdqYv9ccnv7nGvpfsp
The serializer standard is stable, so the Node-based comparison against the TypeScript reference and its devDependencies are not worth carrying. The RSpec suite covers the spec directly, including the exact ECMAScript exponent formatting and multi-byte encoding cases the harness verified. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017p9TwdqYv9ccnv7nGvpfsp
razor-x
marked this pull request as ready for review
August 13, 2026 23:46
Match seamapi/python#617: the SDK serializes query params with strict mode enabled, appending _strict=true after the sorted pairs of any non-empty query so the Seam API uses strict, schema-aware parsing. The strict entry points live in strict_url_search_params_serializer so the base serializer stays a faithful port of the standard, and a query built entirely by the caller still passes through without it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017p9TwdqYv9ccnv7nGvpfsp
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017p9TwdqYv9ccnv7nGvpfsp
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017p9TwdqYv9ccnv7nGvpfsp
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017p9TwdqYv9ccnv7nGvpfsp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a complete implementation of URL search params serialization that matches the @seamapi/url-search-params-serializer TypeScript reference implementation byte-for-byte, enabling proper encoding of query parameters in API requests.
Key Changes
New
Seam::NULLsentinel: Distinguishes three parameter states (omitted, null, value) since Ruby'snilmeans omitted.Seam::NULLserializes as JSONnullin request bodies and empty values in query strings.UrlSearchParamsclass: Implements WHATWG URLSearchParams interface with:UrlSearchParamsSerializermodule: Serializes Ruby hashes to query strings with:UnserializableParamErrorUrlSearchParamsEncoder: Faraday integration that applies the serializer to query params while preserving caller-built query strings verbatim.Conformance testing: Added comprehensive test infrastructure:
generate_fixture.rb: Creates 200+ test cases covering edge cases, special characters, UTF-8, dates, and error conditionsrun_reference.mjs: Runs TypeScript reference implementationrun_ruby.rb: Runs Ruby implementationroundtrip.mjs: Validates Ruby output round-trips through the parserrunbash harness: Orchestrates full conformance suiteDocumentation: Updated README with
Seam::NULLusage examples and URL search params serialization details.Notable Implementation Details
Seam::NULLserializes as emptyhttps://claude.ai/code/session_017p9TwdqYv9ccnv7nGvpfsp