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

プロダクションコードにおける encoding/json から encoding/json/v...

Avatar for SansanTech SansanTech PRO
November 09, 2026

プロダクションコードにおける encoding/json から encoding/json/v2 へのスムーズな移行

■イベント
layerx.go
https://layerx.connpass.com/event/408206/

■登壇概要
タイトル:プロダクションコードにおける encoding/json から encoding/json/v2 へのスムーズな移行
登壇者:技術本部 Data Intelligence Engineering Unit 三浦 駿

■ 技術本部 採用情報
https://media.sansan-engineering.com

Avatar for SansanTech

SansanTech PRO

November 09, 2026

More Decks by SansanTech

Other Decks in Technology

Transcript

  1. 三浦 駿 @MxShun Sansan株式会社 技術本部 Data Intelligence Engineering Unit BtoB

    通販会社でのサーバサイド Kotlin x Spring 、 広告会社での Go バックエンドエンジニアおよび EM を経て 2025年5⽉にSansan株式会社にジョイン 趣味はコーヒーとキャンプ
  2. 会社概要 社名 Sansan株式会社 設⽴ 2007年6⽉11⽇ 従業員数 上場証券取引所 拠点 2,066名(2026年8⽉31⽇時点) 東京証券取引所

    プライム市場 本社:東京都渋⾕区桜丘町1-1 渋⾕サクラステージ28F 関⻄⽀店、福岡⽀店、中部⽀店 サテライトオフィス グループ会社 Sansan神⼭ラボ、Sansan Innovation Lab、Sansan⻑岡ラボ Sansan Global Pte. Ltd. (シンガポール) Sansan Global Development Center, Inc. (フィリピン) Sansan Global (Thailand) Co., Ltd.(タイ) ナインアウト株式会社 株式会社⾔語理解研究所 Eightキャリア株式会社
  3. Sansan株式会社の働き⽅を変えるAXサービス ⽣産性を向上させ、企業のAI活⽤を最⼤化するデータベースとしても貢献できる 「働き⽅を変えるAXサービス」を提供します。 法⼈向け 個⼈向け 名刺データベースが、収益を最⼤化する 契約データベースが、利益を守る 「なくせる」をつくり、全社の働き⽅を変える 営業AXサービス 契約AXサービス

    経理AXサービス 名刺アプリ 営業 契約 請求 名刺 管理 顧客マスターマネジメント 各サービスの活⽤で変わる働き⽅ 必要な情報を 情報の管理がしやすく 情報を分析‧活⽤しやすく すぐに⾒つけられる すぐに共有できる データに基づいた判断ができる
  4. 前置き • 断りのない限り次のように表現する ◦ v1: encoding/json ◦ v2: encoding/json/v2 •

    go version 1.27.3 時点の情報 > go version go version go1.27.3 linux/arm64
  5. 私たちが扱う MDaaS (MasterData as a Service) data source 1 data

    source 2 … API DB job 2 job 1 data pipeline storage … クライアント job n data source n
  6. 私たちが扱う MDaaS は⾄るところで JSON を使う data source 1 data source

    2 … API JSON を使っている箇所 DB job 2 job 1 data pipeline storage … クライアント job n data source n
  7. Go 1.27 では既定値で v2 v1 Marshal / Unmarshal は、DefaultOptionsV1 付きで

    v2 Marshal / Unmarshal を 呼び出している。 Go 1.25, 1.26 では Experimental だったが既定値に。 func Marshal(v any) ([]byte, error) { return jsonv2.Marshal(v, DefaultOptionsV1()) } func Unmarshal(data []byte, v any) error { return jsonv2.Unmarshal(data, v, DefaultOptionsV1()) } ref: cs.opensource.google/go/go/+/refs/tags/go1.27.3:src/encoding/json/v2_encode.go
  8. 移⾏の⽬的 v2 のセマンティクスを取り⼊れて意図しないデータの流⼊と提供を防ぐ。 • フィールド名の⼤⽂字⼩⽂字を区別 • omitempty が空とゼロ値を区別 • nil

    スライス‧マップを空の配列 []‧空のオブジェクト {} とする • 無効な UTF-8 はエラーを返す • 重複したメンバー名はエラーを返す など ref: pkg.go.dev/encoding/[email protected]#hdr-Migrating_to_v2
  9. 移⾏の進め⽅は 3 通り 1. ⼀括で移⾏ 2. v1 互換オプションを 1 つずつ外す

    3. jsonsplit で差分報告 リスク許容度が⾼い場合 リスク許容度が低い場合 差分を把握したい場合 ref: go.dev/doc/jsonv2-migration#migration
  10. 2. v1 互換オプションを 1 つずつ外す リスク許容度が低い場合 import を v2 に置き換え、DefaultOptionsV1

    付きの v2 にする。 v1 互換オプションを 1 つずつ外す。 import ( - "encoding/json" + "encoding/json/v2" ) - b, err := json.Marshal(pets) + b, err := json.Marshal(pets, DefaultOptionsV1()) ref: go.dev/doc/jsonv2-migration#migration
  11. 3. jsonsplit で差分報告 差分を把握したい場合 実⾏環境で v1 と v2 の両⽅を呼び、v1 の結果を返しつつ差分を報告する。

    原因のオプションも⾃動で特定できる。 import ( - "encoding/json" + "github.com/go-json-experiment/jsonsplit" ) - b, err := json.Marshal(pets) + b, err := jsonsplit.Marshal(pets) ref: go.dev/doc/jsonv2-migration#migration
  12. 1. リスク許容度に応じた移⾏計画 data pipeline: リスク許容度が⾼い data source 1 出⼒に差分がなければ良い v2

    にしてみて差分を⾒る data source 2 … API API: リスク許容度が低い クライアントに影響がある 周知しつつ v1 互換オプ ションを 1 つずつ外す DB job 2 job 1 data pipeline storage … クライアント job n data source n
  13. 2. map の Marshal での並び順が⾮決定的 v1 は map の Marshal

    時にキーでソートするが、v2 はしない。 extension package に Deterministic 付きを定義した。 func Marshal(in any, opts ...json.Options) ([]byte, error) { return json.Marshal(in, withDeterministic(opts)...) } func withDeterministic(opts []json.Options) []json.Options { return append([]json.Options{json.Deterministic(true)}, opts...) } ref: pkg.go.dev/encoding/[email protected]#hdr-Migrating_to_v2
  14. まとめ • Go 1.27 では既定値で v2 • リスク許容度に応じた移⾏計画を 1. ⼀括で移⾏

    2. v1 互換オプションを 1 つずつ外す 3. jsonsplit で差分報告 • v1 のままという選択肢もあり