پکیج encoding/json/v2 تو Go 1.27 پایدار شد
خلاصهٔ کاملتر
پکیجهای encoding/json/v2 و encoding/json/jsontext تو Go 1.27 پایدار شدن و همه میتونن ازشون استفاده کنن. تیم Go تو این پست توضیح داده که چرا لازم بود یه نسخهٔ جدید بسازن. خلاصهش اینه که مشکلات encoding/json قدیمی جزو خود API بودن و بدون شکستن Go 1 compatibility promise (یعنی تعهد Go به اینکه کد قدیمی همیشه کار کنه) درستشدنی نبودن.
مشکلات رفتاری نسخهٔ قدیمی کم نبود: UTF-8 نامعتبر رو قبول میکرد، کلید تکراری تو یه object رو رد نمیکرد (که قبلاً تو CVE-2017-12635 ازش سوءاستفاده شده بود)، slice و map خالی (nil) رو به null تبدیل میکرد و اسم فیلدها رو بدون حساسیت به حروف بزرگ و کوچیک تطبیق میداد. از نظر سرعت هم MarshalJSON و UnmarshalJSON مجبور بودن داده رو چند بار parse یا کپی کنن و streaming واقعی هم نداشت.
پایهٔ کار پکیج jsontextه که فقط با syntax یعنی ساختار متنی JSON کار میکنه و به reflection وابسته نیست. Encoder و Decoder این پکیج واقعاً streaming کار میکنن. خود v2 روی همین ساخته شده و توابعش option رو مستقیم ورودی میگیرن:
func Marshal(in any, opts ...Options) (out []byte, err error)
func MarshalWrite(out io.Writer, in any, opts ...Options) error
func Unmarshal(in []byte, out any, opts ...Options) error
func UnmarshalRead(in io.Reader, out any, opts ...Options) errorاینترفیسهای جدید MarshalerTo و UnmarshalerFrom مستقیم با Encoder و Decoder کار میکنن و optionها رو هم تو کل call stack پاس میدن. caller هم میتونه با WithMarshalers برای هر نوعی یه تبدیل دلخواه تعریف کنه. تو رفتار پیشفرض، v2 جلوی UTF-8 نامعتبر و کلید تکراری خطا میده، nil رو به [] و {} تبدیل میکنه، تطبیق اسم فیلد حساس به حروفه و برای time.Duration هم خطا میده تا خودت فرمتشو انتخاب کنی.
سرعت Marshal تقریباً مثل قبله ولی Unmarshal تا ۱۰ برابر سریعتر شده. مثلاً تو یه سرویس Kubernetes، رفتن از UnmarshalJSON به UnmarshalJSONFrom سرعت رو چند مرتبهٔ بزرگی بهتر کرد. نکتهٔ مهم سازگاریه: v1 حالا از داخل روی v2 پیاده شده، پس دو نسخه کنار هم کار میکنن و لازم نیست هیچوقت مهاجرت کنی. اگه هم بخوای مهاجرت کنی، میتونی فقط رفتارهایی که بهشون وابستهای رو با option نگه داری:
json.Marshal(..., json.DefaultOptionsV2(), jsontext.AllowDuplicateName(true))نکات کلیدی:
- پکیجهای encoding/json/v2 و encoding/json/jsontext از Go 1.27 پایدار هستن.
- v2 بهصورت پیشفرض UTF-8 نامعتبر و کلید تکراری رو رد میکنه.
- slice و map از نوع nil تو v2 به آرایه و object خالی تبدیل میشن، نه null.
- سرعت Unmarshal تو benchmarkها تا ۱۰ برابر بهتر شده و برای Go 1.28 هم بهینهسازی بیشتری در راهه.
- v1 روی v2 پیاده شده و تا همیشه پشتیبانی میشه، پس مهاجرت اجباری نیست.
- این پروژه حدود ۶ سال طول کشید و تو Go 1.25 بهصورت experiment عرضه شده بود.




