JSON Serialization System
Relevant source files
The following files were used as context for generating this wiki page:
The JSON Serialization System in the Anthropic Go SDK is a robust infrastructure designed to handle the conversion between Go data structures and JSON representations required by the Anthropic API. It encompasses custom encoding logic, schema transformation utilities, and specialized handling for API-specific patterns like discriminated unions and optional fields.
The system is built upon a vendored and modified version of the Go standard library's JSON package, allowing for specialized behaviors such as custom time formatting and non-escaped HTML by default. It ensures that complex request parameters, such as tool schemas and structured output formats, are correctly transformed to meet the API's strict requirements.
Core Encoding Engine
The core of the system is located in internal/encoding/json, which provides the Marshal and MarshalIndent functions. This engine uses reflection to traverse Go values and produce JSON output.
Specialized Encoder Logic
The encoder includes several modifications to standard Go JSON behavior:
- HTML Escaping: By default, the encoder does not escape HTML characters like
<,>, and&, unlike the standard library. Sources: internal/encoding/json/encode.go:189-193 - Custom Time Encoding: Includes specialized logic for handling time formats specified in struct tags. Sources: internal/encoding/json/encode.go:303-305, internal/encoding/json/encode.go:876-880
- Zero Value Omission: Supports an
omitzerotag option which omits fields if they are the zero value for their type or if they implement anIsZero() boolmethod that returns true. Sources: internal/encoding/json/encode.go:121-131
The diagram shows the recursive flow of the JSON encoding process, highlighting the decision points for field omission and specialized type handling.
Sources: internal/encoding/json/encode.go:174-270
Schema Transformation and Utilities
The SDK provides utilities in schemautil.go to transform standard JSON schemas into formats compatible with the Anthropic API. This is particularly critical for features like Tool Use and Structured Outputs.
Transformation Rules
The transformSchema function applies several constraints:
- Strict Objects: Automatically sets
additionalProperties: falsefor all object types. Sources: schemautil.go:146 - Format Filtering: Only allows a specific subset of string formats (e.g.,
date-time,uuid,email). Sources: schemautil.go:48-59 - Array Limits: Restricts
minItemsto values of 0 or 1. Sources: schemautil.go:167-172 - Description Mapping: Any schema properties not explicitly supported by Anthropic are serialized into a string and appended to the
descriptionfield. Sources: schemautil.go:181-205
Supported Schema Keys
| Key Category | Supported Keys |
|---|---|
| Top-level | $ref, $defs, type, anyOf, oneOf, description, title |
| Object | properties, additionalProperties, required |
| Array | items, minItems |
| String | format |
Sources: schemautil.go:60-78
Discriminated Unions and Polymorphism
The system handles polymorphic API responses through discriminated unions. This allows the SDK to unmarshal a JSON object into the correct concrete Go type based on a specific field (the "discriminator").
Registration and Resolution
Unions are registered using a RegisterUnion or RegisterDiscriminatedUnion mechanism. During unmarshalling, the system inspects the discriminator field (often named type) to determine which struct variant to instantiate. Sources: internal/apijson/json_test.go:138-155, internal/apijson/decodeparam_test.go:343-348
This sequence diagram illustrates how the system resolves polymorphic JSON objects into concrete Go structs using a discriminator.
Sources: internal/apijson/decodeparam_test.go:343-370
Constant Handling and Marshaling
The SDK uses specialized types for API constants (enums). These types implement MarshalJSON to ensure they default to their defined constant value if not explicitly set.
Constant Marshaling Logic
The marshalString helper function checks if a constant value is the "zero" value of its underlying string type. If so, it retrieves the defined Default() value before serializing to JSON. Sources: shared/constant/constants.go:453-459
| Feature | Description |
|---|---|
| Default Value | Constants implement a Default() T method. |
| Automatic Marshalling | Ensures that mandatory string constants are sent even if not manually initialized. |
| Standardized Types | Uses custom types like Model, Role, and ContentType to wrap strings. |
Sources: shared/constant/constants.go:19-35
Optional Fields and Nullability
The system distinguishes between a field being "missing," "null," or "present" using the param.Opt and param.Null wrappers.
param.Opt[T]: Represents a field that may be omitted from the JSON request.param.Null[T]: Explicitly sends a JSONnullvalue for the field.- Decoding Status: During unmarshalling, the
Fieldstruct tracks the status of a field (missing, null, or valid) and retains therawJSON fragment.
Sources: internal/apijson/decodeparam_test.go:18-39, internal/apijson/json_test.go:281-306
Summary
The JSON Serialization System provides the necessary bridge between Go's type system and Anthropic's JSON-based API. By customizing the core encoding engine and providing sophisticated schema transformation tools, it allows developers to use native Go structures while ensuring strict compliance with API specifications, including complex behaviors like tool-calling schemas and polymorphic message blocks.