Summary
When building applications that support multiple file formats (e.g., .json and .md with frontmatter), enabling "Strict Mode" for JSON introduces a type inconsistency that forces consumer code to handle disparate numeric types depending on the data source.
Context
I am using Loam v0.10.3 in a project (Trellis) that loads state from both JSON and Markdown files.
To prevent large integers (IDs, timestamps) from being corrupted by float64 conversion in encoding/json, I enabled the strict JSON serializer:
loam.WithSerializer(".json", fs.NewJSONSerializer(true))
The Problem
This setting successfully preserves integers in JSON files by returning json.Number. However, the YAML parser (used for Markdown frontmatter) continues to return native Go types (int, float64).
This results in a situation where the same logical data field has different runtime types based on the file extension:
-
Source data.json:
Loaded Type: json.Number ("123")
-
Source data.md:
Loaded Type: int (123)
Consequence
Consumer code dealing with map[string]any (via TypedRepository or untyped Get) must implement defensive type assertions for all possibilities, leading to brittle boilerplate:
val := doc.Data["count"]
switch v := val.(type) {
case json.Number:
// handle JSON strict
case int:
// handle YAML/MD
case float64:
// handle JSON default / YAML float
}
Proposal
Loam should consider offering a Type Normalization strategy or middleware.
Ideas:
- Unified Numeric Type: An option to force all adapters to return a specific numeric type (e.g.,
json.Number or int64 where possible).
- Smart Accessors: A helper (maybe in
TypedDocument or something that abstracts this retrieval, e.g., node.GetInt64("field"), similar to how viper or other config libs handle it.
This would allow "Polyglot" repositories (supporting multiple formats) to offer a consistent API to the domain layer.
Summary
When building applications that support multiple file formats (e.g., .json and .md with frontmatter), enabling "Strict Mode" for JSON introduces a type inconsistency that forces consumer code to handle disparate numeric types depending on the data source.
Context
I am using Loam v0.10.3 in a project (Trellis) that loads state from both JSON and Markdown files.
To prevent large integers (IDs, timestamps) from being corrupted by
float64conversion inencoding/json, I enabled the strict JSON serializer:The Problem
This setting successfully preserves integers in JSON files by returning
json.Number. However, the YAML parser (used for Markdown frontmatter) continues to return native Go types (int,float64).This results in a situation where the same logical data field has different runtime types based on the file extension:
Source
data.json:{ "count": 123 }Loaded Type:
json.Number("123")Source
data.md:Loaded Type: int (123)
Consequence
Consumer code dealing with
map[string]any(viaTypedRepositoryor untyped Get) must implement defensive type assertions for all possibilities, leading to brittle boilerplate:Proposal
Loam should consider offering a Type Normalization strategy or middleware.
Ideas:
json.Numberorint64where possible).TypedDocumentor something that abstracts this retrieval, e.g.,node.GetInt64("field"), similar to howviperor other config libs handle it.This would allow "Polyglot" repositories (supporting multiple formats) to offer a consistent API to the domain layer.