JSON の新しい Go API

2026/11/05 2:52

JSON の新しい Go API

RSS: https://news.ycombinator.com/rss

要約▶

Japanese Translation:

2026 年 11 月 4 日、Google は公式に Go 1.27 をリリースし、

encoding/json/v2
および
encoding/json/jsontext
の安定版を公開しました。Michael Pratt、Joe Tsai などによるこのアップデートは、15 年以上前に初期開発から存在した元の JSON ライブラリの長年残存していた問題を解決します。主な改善点には、無効な UTF-8 を受け付けるなどの動作上の欠陥の修正(重複するメンバー名 (CVE-2017-12635)、スライサーまたはマップの nil 性をリークする問題、大文字小文字区別を気にしないマーシャリング、一貫性のないメソッド呼び出し)が含まれます。新しい
encoding/json/jsontext
パッケージは反射を用いない純粋なストリーミング構文処理を可能にし、v1 のパフォーマンス制限(必須のアロケーション、再帰呼び出しによる二次的課題など)に対処します。更新された
encoding/json/v2
は新しいインターフェース (
MarshalerTo
,
UnmarshalerFrom
) を導入し、これにより
Encoder
または
Decoder
を通じてストリーミング処理が可能になります。さらに、型定義されたメソッドよりも優先されるカスタム表現オプション (
WithMarshalers
,
WithUnmarshalers
) も提供します。v2 の主な動作変化には、無効な UTF-8 および重複する名前でエラーを報告し、nil スライサーまたはマップを空の配列/オブジェクトとしてマーシャリングし、大文字小文字区別マッチングを強制し、
omitempty
を再定義し、
time.Duration
のシリアライゼーションにオプションが必要とすることなどが含まれます。パフォーマンスの面で、マーシャリング速度は v1 と比較して最大 10 倍向上し、マーシャリング速度は同等です。移行は段階的に行うことを意図しており、v1 および v2 は互換性があり(v1 は v2 のオプションを通じて実装されているため)、既存のコードを破綻させずに大文字小文字区別パースなどの新機能を順次取り入れることができるように設計されています。これにより、データ処理パイプラインの効率的な近代化を最小限の中断で行うことが可能になります。

本文

Go の JSON パッケージ再編:
encoding/json/v2
と
jsontext
の導入と解説

マイケル・プラット、ジョー・チャイ、ダニエル・マルティ、ヨハン・ブランドホスト=ザツコーン、ロジャー・ペッペ、クリス・ハインズ、そしてダミアン・ネイルによる投稿 日付:2026 年 11 月 4 日

序論

JavaScript Object Notation(JSON)はインターネット上で最も広く利用されているデータ形式の一つです。Go プログラムでも多数が読み書きしており、標準ライブラリには JSON サポートが組み込まれています。Go 1.0 よりも以前からこの対応が存在し、執筆から15 年以上前に JSON サポートに関する記事を掲載したこともあります!

パッケージは時間の経過とともにユーザーのニーズに合わせて進化していきます。

encoding/json
パッケージも例外ではなく、昨年には待ちに待った改修と修正をもたらす新たな実験的 API の導入を発表しました。さらなるフィードバックと精査を経て、新しい
encoding/json/v2
と
encoding/json/jsontext
パッケージは安定化し、Go 1.27において一般利用が可能となりました。

本稿では、実験の導入を説明し、

encoding/json
の問題点を詳述し、新パッケージを紹介いたします。

encoding/json
の課題

全体として、

encoding/json
はよく機能してきましたが、多くのユーザーが欠陥や改善点を見出しました。

動作上の不具合

  • JSON SYNTAX の不十分な扱い
    • 最新インターネット標準(RFC 8259)では、有効な UTF-8 を要求し、重複名は未定義とされます。
    • encoding/json
      は現在無効な UTF-8 や重複したメンバー名を受け付けており、データ破損や**セキュリティ脆弱性(CVE-2017-12635)**を引き起こす可能性があります。
    • これらの行為はデフォルトでエラーを報告するべきです。
  • スライスとマップの
    nil
    性のリーク
    • encoding/json
      は
      nil
      スライスまたはマップを JSON の
      null
      として marshal しますが、他方の実装との通信で unmarshal に際してエラーを引き起こします。
    • 多くのユーザーがデフォルトで
      nil
      スライスとマップを空の JSON アレイやオブジェクトとして marshal することを好みます。
  • 大文字小文字不感応な unmarshal
    • メンバー名の照合がケース不感応であり、予期せぬデフォルト挙動および潜在的なセキュリティ脆弱性となります。また、パフォーマンス上の制約にもなります。
  • メソッド呼び出しの一貫性の欠如
    • ポインタ受容器に宣言された
      MarshalJSON
      メソッドが一貫性なく呼び出されることがあります。これはバグですが、既存の依存関係のため修正は困難です。

API の欠陥

  • io.Reader
    から正しく unmarshal することが困難です(入力末尾の不要なデータを拒否できません)。
  • オプションは
    Encoder
    および
    Decoder
    タイプには設定可能ですが、
    Marshal
    と
    Unmarshal
    関数やインターフェースでは利用できません。
    • 例えば、
      Custom UnmarshalJSON
      メソッドを呼び出す際に、
      Decoder.DisallowUnknownFields
      の効果が失われます。
  • Compact
    、
    Indent
    、および
    HTMLEscape
    関数は
    bytes.Buffer
    に書き出されるため、柔軟性に欠けます。

パフォーマンスの制限

  • MarshalJSON: 戻り値の
    []byte
    を割り当てることが強制され、有効性検証やフォーマット化も内部で行う必要があります。
  • UnmarshalJSON: 完全な JSON 値全体をパースして終了位置を特定してから呼び出す必要があり、二度のパースが発生します。
  • ストリーミング機能の欠如:
    Encoder
    および
    Decoder
    は完全に JSON 値をメモリにバッファリングします。個別トークン処理用の API も不足しており、再帰的に呼び出された場合パフォーマンスが劣化します。

encoding/json/v2
の導入方針

パッケージの新しい互換性のないメジャーバージョンを導入することは大きな決断です。原則として既存の API を修正すべきですが、这些问题は既存の API に本質的に起因するため、Go 1 の互換性を保証する枠組み内で実質的に解決不可能でした。

そこで、

encoding/json/v2
(以下「v2」)へと至りました。これにより、
encoding/json
(以下「v1」)とは独立した v2 の名前空間内で変更を行うことができました。

encoding/json/jsontext
を基盤として

Go における JSON シリアライゼーションは以下の 2 つの要素に分解できます:

  1. 文法的機能: JSON の文法に基づいて処理を行う機能(「encode」「decode」)。
  2. セマンティックス機能: JSON 値と Go 値との関係を定義する機能(「marshal」「unmarshal」)。

この分離により、

encoding/json/jsontext
パッケージを新設します。これは純粋にエンコードに関する機能を扱い、Go の反射には依存せず、真にストリーミング方式で動作します。

jsontext
の基本 API

package jsontext

type Encoder struct { ... }
func NewEncoder(io.Writer, ...Options) *Encoder
func (*Encoder) WriteValue(Value) error
func (*Encoder) WriteToken(Token) error

type Decoder struct { ... }
func NewDecoder(io.Reader, ...Options) *Decoder
func (*Decoder) ReadValue() (Value, error)
func (*Decoder) ReadToken() (Token, error)

type Kind byte
type Value []byte // jsontext.Value への型エイリアス
func (Value) Kind() Kind

type Token struct { ... }
func (Token) Kind() Kind
  • JSON 値: 名前付き
    []byte
    で表され、文法的に一つ以上の JSON トークンから構成されます。
  • JSON トークン: 不透明な
    Token
    タイプで表され、割り当てなしで任意のトークンを表現できます。

これにより、

MarshalJSON
および
UnmarshalJSON
のパフォーマンス問題を解決し、検証や境界決定の責任をライブラリ側に移すことができました。

encoding/json/v2
の導入

v1 の問題点を修正しつつ、v1 パッケージの利用者に馴染みを持たせるように設計されています。移行時の利用方法はほとんど変わりません。

v2 の基本 API

package json

// Marshal / Unmarshal 関数に Options を受け取ります
func Marshal(in any, opts ...Options) (out []byte, err error)
func Unmarshal(in []byte, out any, opts ...Options) error

// io.Writer / io.Reader を直接操作
func MarshalWrite(out io.Writer, in any, opts ...Options) error
func UnmarshalRead(in io.Reader, out any, opts ...Options) error

// Encoder / Decoder を直接操作(内部実装)
func MarshalEncode(out *jsontext.Encoder, in any, opts ...Options) error
func UnmarshalDecode(in *jsontext.Decoder, out any, opts ...Options) error

v1 と異なり、オプションは marshal/unmarshal 関数の一次引数として扱われ、柔軟性と設定可能性が大幅に向上しました。

タイプ指定のカスタマイズ

v2 でも特定のインターフェースを満たすことでタイプが独自の JSON 表現を定義できます。

type Marshaler interface {
    MarshalJSON() ([]byte, error) // v1 と同一
}

type MarshalerTo interface {
    MarshalJSONTo(*jsontext.Encoder) error // 新規:オプションチェーンとの連携が可能に
}

type Unmarshaler interface {
    UnmarshalJSON([]byte) error // v1 と同一
}

type UnmarshalerFrom interface {
    UnmarshalJSONFrom(*jsontext.Decoder) error // 新規:Decoder オプションの利用可能に
}

呼出者指定のカスタマイズ

v2 では、

Marshal
および
Unmarshal
の呼出者が任意のタイプのためのカスタム JSON 表現も指定できます。呼出者指定関数は優先されます。

func WithMarshalers(*Marshalers) Options
type MarshalFunc[T any](fn func(T) ([]byte, error)) *Marshalers
type MarshalToFunc[T any](fn func(*jsontext.Encoder, T) error) *Marshalers

func WithUnmarshalers(*Unmarshalers) Options
type UnmarshalFunc[T any](fn func([]byte, T) error) *Unmarshalers
type UnmarshalFromFunc[T any](fn func(*jsontext.Decoder, T) error) *Unmarshalers

動作の違い

v1 の問題を解決するために一部の動作が変更されています:

  • 無効な UTF-8: エラーを報告します。
  • 重複名: JSON オブジェクトに重複名が含まれている場合にエラーを報告します。
  • nil
    スライス/マップ:
    空の JSON アレイまたはオブジェクトとして marshal します。
  • ケース感応な照合: JSON メンバー名から Go フィールド名への照合をケース感応に行います。
  • omitempty
    :
    再定義され、
    null
    、
    ""
    、
    []
    、
    {}
    としてエンコードされる場合フィールドを省略するように機能します。
  • time.Duration
    :
    シリアライゼーションを試みたらエラー(デフォルト表現未実装)。

パフォーマンス最適化

  • Marshal
    : v1 と同等です(場合によりわずかに高速・遅いこともあります)。
  • Unmarshal
    : v1 よりも著しく高速で、ベンチマークでは最大10 倍の向上が示されています。

より大きなパフォーマンス向上には、既存の実装を

MarshalerTo
および
UnmarshalerFrom
も実装する方向に移行する必要があります。これにより純粋にストリーミング方式での処理が可能になります(例:Kubernetes の OpenAPI パースで桁違いの改善)。

詳細は

go-json-experiment/jsonbench
リポジトリをご覧ください。

互換性

Go 1 の互換性は核心的な保証です。v1 と v2 はともに Go 1 の互換性を保証の対象としています。

  • 移行の是非: v1 を使用しているアプリケーションは長期的にサポートされ、必ずしも v2 への移行を行う必要はありません。
  • エコシステムのスムーズな移行: v1 と v2 が互換性を持ち、異なるバージョンを使用するパッケージが共同で動作します。
    • v2 パッケージが v1 の
      MarshalJSON
      を使用する場合でも機能します。
    • v1 パッケージが v2 の
      MarshalJSONTo
      をサポートする場合でも機能します。

この互換性は、v2 を基盤として実装する新しいパッケージを設計することで達成されました。v1 の互換性オプションをすべて渡すことで、v2 を用いて v1 を実装可能です。

移行

段階的な移行が可能なため、呼び出し場所をゆっくりと移行できます。

  • 可視的な動作変更なし: 多くのアプリケーションは直接 v2 に移行できます。
  • 必要な挙動のみ変更: v1 挙動に依存する場合は、オプションで制御可能です。

例:重複名を受け付ける v2 の挙動を除くすべての v2 挙動を選択する場合:

json.Marshal(..., json.DefaultOptionsV2(), jsontext.AllowDuplicateName(true))

詳細については**「v2 への移行」ガイド**を参照してください。

さらに情報

  • 「Working with JSON」チュートリアル
  • encoding/json/v2
    および
    encoding/json/jsontext
    パッケージのドキュメント
  • encoding/json
    パッケージの v2 比較ドキュメント
  • 「v2 への移行」ガイド

長年の課題

この計画は約 6 年かかりました。Go プロジェクトは、Google に雇用されていない人々によって行われた協力努力であり、活発なグローバルコミュニティによるものです。

  • 起源: 2020 年末、既存パッケージの問題を修正できない事情からダニエル・マルティ氏が仮想的な v2 の草案を開始しました。
  • 動機: ジョー・チャイ氏は
    protojson
    パッケージのカスタム実装への失望から、厳格な JSON 標準とストリーミング処理の必要性を痛感し、v2 との融合を推進しました。
  • 貢献者: マイケル・プラット、ロジャー・ペッペ、クリス・ハインズ、ヨハン・ブランドホスト=ザツコーン、ダミアン・ネイルら多くの開発者が設計レビュー、コードレビュー、回帰テストを提供しました。

2023 年末の GopherCon で発表され、2025 年初めの正式な提案を経て、Go 1.25 で

encoding/json/v2
を Go 実験として採用し、現在では一般利用(Go 1.27)に至りました。

同じ日のほかのニュース

一覧に戻る →

2026/11/05 5:45

ホワイトハウスのネットワークで住宅用プロキシが検出

## Japanese Translation: 当社の Residential Proxy Observatory を率いた最近のセキュリティ調査により、大統領執行局(ホワイトハウスのネットワーク)に登録されている AS2650 は、2026 年 10 月 5 日から 11 月 3 日まで、住宅用プロキシのエグレス活動ホストしていることが確認されました。エニュメレーションパイプラインでは、30 日のうち 26 日にわたり 6 つのアドレスから発せられた 236 の別個のエグレスが特定され、28 の異なる住宅用プロキシサービスが観測されました。Spur および Synthient という検知サービスとのクロスチェックにより、これらのアドレスが公共 IP コンテキストページを通じて住宅用プロキシエグレスであることがそれぞれ独立して確認されました。 活動は東部標準時の午後 5 時から真夜中にかけてピークに達しており、これは感染した個人端末がプロキシ SDK を使用していることを示唆しており、公共の Wi-Fi の使用とは異なります。セキュリティが不十分なプロキシ SDK は、ネットワーク内でのラテラルムーブメントを可能にします。この事件は、以前の類似した住宅用プロキシネットワークを通じて数百万台の Android 機器を感染させた Kimwolf ボットネットによって参照されたようなリスクの巨大な規模を浮き彫りにしています。 ホワイトハウスのネットワーク以外にも、セントヘレナ・アセンションおよびトリスタンダクーニャ(スターリンクおよびSure セントヘレナを介した 32,000 回以上の観測を持つ 413 のアドレス)、南極大陸(クラウドフレア WARP を通じたマクマード基地への 3 つの観測)、ピトケアン、ノーフォーク島、スバルバル、フォークランド諸島、チャゴス諸島、トケラウ、サウスジョージアなど、遠隔地でも住宅用プロキシが観測されました。Layer3 Intel はこの世界的な住宅用プロキシおよび匿名化インフラストラクチャを追跡しており、脅威アクターは遠隔または孤立したネットワーク上にあっても隠れる場所がないことを示しています。 侵入を記録するログは当局のために確保されており、関連する機関からの要請により当社の連絡先ページを通じて入手可能です。これらのログは、責任あるアクターの特定と感染の全範囲の評価を可能にします。究極的には、この事件は、個々のエンドポイントが適切にセキュリティ対策されていな場合に、高プロファイルな政府ネットワークも侵入に脆弱であることが示され、全世界でのトラフィックの再方向付けを通じて機密通信のプライバシーとセキュリティに対して直接的な脅威をもたらしていることを実証しています。

2026/11/05 4:50

昆虫はLEDの光に集まってくるわけではない

## Japanese Translation: 白熱灯からLED照明への切り替えは昆虫の引き寄せを劇的に減少させ、昆虫個体数の減少に対する新たな希望を提供しています。昆虫は月光(紫外線(UV)および赤外線波長を含む太陽光の反射光)を利用して航行しますが、人工的な光で紫外線を透過するものには混乱し、上空に向いた姿勢から円を描く飛行や逆さまになるような行動を示します。白熱灯はこの紫外線豊富な光を放出しますが、LED は電気エネルギーのほとんどを可視光(400–700 nm)に変換するため、コバチやヤブカメムシといった飛翔種に対してははるかに魅力的ではありません。 この移行を支える証拠として、2016 年のブリストル大学の研究では白熱灯、省エネ蛍光灯(CFL)、寒色系LED、暖色系LEDを比較し、LED全体が昆虫を引き寄せる数が著しく少ないこと、かつ寒色系と暖色系のLEDの間には有意差がないことを発見しました。具体的には、ハエ目(Diptera)のコバチやクレンカメムシ属(Culicoides)のヤブカメムシがLEDに引き寄せられる個体数が少ないことが確認されました。実例としては、ガイドのロランド・ルム氏によるWINGS バラクロスの旅行で報告された事例があり、家庭では屋外用ダイニング照明を白熱灯からLED に切り替えた後、トカゲの個体群が消失することに気づいたとあります。これは、爬虫類が昆虫という食物源を失ったためです。 夜間の紫外線豊富な人工光は、昆虫個体数の減少の主要な要因の一つと考えられています。このUV曝露を最小限に抑えることで、野生動物の航行への擾乱を軽減し、昆虫媒介疾患に関連するリスクを低減させ、人間の開発と自然の野生生物循環の安全な共存を促進することができます。(記事掲載日:2026 年 11 月 3 日;写真は 2006 年 7 月に撮影されたガソリンスタンド照明に群がる昆虫の様子)

2026/11/05 3:53

Ripple-65B Preview:米国で開示されたオープンウェイトモデルによるエージェント型コーディングにおける最上位性能

## Japanese Translation: このテキストは、先進的な AI モデルの構築において、段階的にトレーニング手法を最適化する方が、強力で生僻な計算資源に依存する蛮力アプローチよりもはるかに効率的であると論じています。この戦略では、単純な規模化よりも反復的な改良を優先することで、TerminalBench 2.1 でトップティアの性能スコア 80.5 を達成しました。これには「ロールアウト」と呼ばれる試行錯誤のステップがわずか 140 万回しか必要であり、先導的だった前技術(Reflection Beam)が要していたものの約 70 分の 1です。この効率性の源は、高価な外部データの購入を排除し、品質フィルタリングとカバレッジ指標を活用した高品質な内部環境に焦点を当てるカスタム synthetic データパイプラインにあります。 技術的には、このアプローチは堅牢な有教師学習用微調整(SFT)チェックポイントから始まり、高品質な長期間視野を持つ合成環境内において、切り捨て重要性サンプリング、スコア中心化、および線形長罰則を含む混合 RL レシピを採用しています。主要な利点はその適応的な性質であり、モデルが改良につれてトレーニング担当者が自動的により困難なタスクを追加することで進捗を維持しつつ資源の浪費を防ぎます。究極的には、この手法は先進的なモデルのトレーニングにおける財務的および計算機的障壁を大幅に低減させ、巨大量のデータクラスターや過剰な計算力への投資を少なくしてでも優越的な結果を得ることを可能にします。