Upgrade to Pro — share decks privately, control downloads, hide ads and more …

json/v2 の新機能を 10 分で俯瞰

json/v2 の新機能を 10 分で俯瞰

Avatar for Douglas Shuhei Takeuchi

Douglas Shuhei Takeuchi

August 24, 2025
Tweet

Transcript

  1. アジェンダ 1. 導入 & OLTA の技術スタック 2. JSON v1 の復習と課題

    3. JSON v2 の紹介 4. 主要機能と改善点 5. 破壊的変更 6. パフォーマンス比較 7. 移行の考慮事項 8. まとめ
  2. JSON v1 の復習 コアインターフェースとユースケース // 基本的な操作 b := `{"name": "John",

    "age": 20}` var user *User if err := json.Unmarshal([]byte(b), &user); err != nil { return err } // ストリーミング操作 reader := strings.NewReader(b) decoder := json.NewDecoder(reader) if err := decoder.Decode(&user); err != nil { return err }
  3. JSON v1 の復習 構造体タグで Marshal/Unmarshal を制御 type User struct {

    ID int `json:"id"` // 'id' キーに読み書き Name string `json:"name,omitempty"` // ゼロ値なら省略 Address string `json:"address,omitzero"` // ゼロ値なら省略 (omitzero) BirthDay time.Time `json:"-"` // Marshal/Unmarshal の対象外 }
  4. JSON v2 の紹介 何が新しいか オプション指定: Marshal/Unmarshal を細かく制御 カスタムインターフェース: Marshaler/Unmarshaler が拡張

    新しいタグ: 値の整形に使う "format" タグ 性能改善: Unmarshal が 2x〜10x 高速 破壊的変更: 既定動作が一部変更
  5. オプション指定での制御 data, err := json.Marshal( User{ID: 100, Name: "Brian", Age:

    0}, json.OmitZeroStructFields(true), // omitzero 相当 json.StringifyNumbers(true), // 数値を文字列として出力 jsontext.WithIndent(" "), // インデント指定 ) /* 出力: { "id": "100", "name": "Brian", } */
  6. カスタム Marshaler marshaler := json.MarshalFunc( func(v bool) ([]byte, error) {

    if v { return []byte(`"OK"`), nil } return []byte(`"NG"`), nil }, ) data := true b, _ := json.Marshal(data, json.WithMarshalers(marshaler)) fmt.Println(string(b)) // "OK"
  7. 新しい "format" タグ type User struct { BirthDay time.Time `json:"birthDay,format:DateOnly"`

    } u := User{BirthDay: time.Date(2000, 12, 31, 0, 0, 0, 0, time.UTC)} b, _ := json.Marshal(u, jsontext.WithIndent(" ")) fmt.Println(string(b)) /* { "birthDay": "2000-12-31" } */
  8. パフォーマンス改善 アンマーシャリングの性能 v2 が速い理由 アルゴリズム改善: O(n²) → O(n) の場面が減少 例:

    Kubernetes OpenAPI spec で 40x 高速化 メモリ効率: 割り当て最適化 最適化されたパース: JSON トークン処理の改善 マーシャリングの性能 改善は小さめ: v2 の Marshal は v1 と同程度 重点: v2 は Unmarshal 最適化を優先
  9. 破壊的変更: 既定動作 注意すべき変更 マップ/スライスの扱い // v1 の挙動 var m map[string]int

    json.Marshal(m) // → "null" // v2 の挙動 var m map[string]int json.Marshal(m) // → "{}" (空オブジェクト) nil と空値 v1: nil の map/slice は null v2: nil の map/slice は 空オブジェクト/空配列
  10. JSON v2 の有効化方法 環境設定 # JSON v2 を有効化 export GOEXPERIMENT=jsonv2

    # コマンド単位で有効化 GOEXPERIMENT=jsonv2 go run main.go 必要なコード変更 // v1(v2 を有効にしていても動作) import "encoding/json" // v2(新しいパッケージ) import "encoding/json/v2"
  11. 比較サマリー 項目 JSON v1 JSON v2 パフォーマンス ベースライン アンマーシャリング 2x〜10x

    高速 メモリ使用量 全体をバッファ 真のストリーミング フォーマット 限定的 Options とタグで細かく制御 デフォルト動作 nil → null nil → 空値 本番準備 安定 実験的
  12. まとめ キーとなるポイント 1. JSON v2 は大幅な性能向上をもたらす 2. 真のストリーミング が可能に 3.

    破壊的変更 への備えが必要 4. 実験的 のため本番投入は時期尚早 5. 将来に向けた準備 を進める