Files
zeekayandGitHub 9a5a43e8a0 feat: route all JSON through encoding/json/v2 at the edge (HIP-0106) (#3)
Introduce internal/jsonenc package as the single JSON entry point for
every code path in zip: c.JSON, c.Bind().Body (via Fiber's pluggable
JSONEncoder/JSONDecoder), the typed zip.Get/Post[In,Out] roundtrip,
the HIP-0105 module envelope, and the auto-generated OpenAPI spec.

Two build-tag-gated files swap the implementation:
- v2.go (//go:build goexperiment.jsonv2) uses encoding/json/v2
- v1.go (//go:build !goexperiment.jsonv2) falls back to encoding/json

zip.JSONVariant is a compile-time constant naming the active impl.
zip.New logs it once at startup so operators can confirm v2 in prod
CI/k8s logs (json_variant=encoding/json/v2).

Bench numbers (Apple M1 Max, Go 1.26, fiber/v3 v3.2.0):

| Bench | json v1 ns/op | v2 ns/op | v1 allocs | v2 allocs | Δ |
|---|---|---|---|---|---|
| Edge POST roundtrip | 14972 | 13631 | 73 | 56 | -9% time, -23% allocs |
| Marshal-only | 10798 | 7924 | 34 | 34 | -27% time |
| Unmarshal-only | 13803 | 12729 | 67 | 50 | -8% time, -25% allocs |

Brand policy enforced: no third-party JSON library (no goccy/go-json,
no sonic, no jsoniter). Stdlib only per HIP-0106 canonical Hanzo Go
stack. RawMessage stays in encoding/json (v1) since the type only
lives there; both v1 and v2 honor its MarshalJSON/UnmarshalJSON so
the moduleEnvelope serializes identically under either build.
2026-05-19 11:14:06 -07:00

21 lines
704 B
Go

//go:build !goexperiment.jsonv2
package jsonenc
import (
"encoding/json"
)
// Variant reports which JSON implementation backs this build. v2 is
// reachable only under `GOEXPERIMENT=jsonv2`; without that flag the
// stdlib encoding/json/v2 import does not resolve at compile time and
// zip falls back to encoding/json v1. zip.New() logs Variant once at
// startup so operators can spot a missing GOEXPERIMENT in CI.
const Variant = "encoding/json"
// Marshal encodes v as JSON via encoding/json (v1).
func Marshal(v any) ([]byte, error) { return json.Marshal(v) }
// Unmarshal decodes data into v via encoding/json (v1).
func Unmarshal(data []byte, v any) error { return json.Unmarshal(data, v) }