Skip to content
Allen edited this page May 28, 2020 · 1 revision

English | 中文

json-iterator is a json library with simple api for serialization/deserialization. It is fully compatible with encoding/json, which means users can quickly and easily migrate from encoding/json to json-iterator. In addition, json-iterator also provides many other convenient functions, such as various of serialization/deserialization configuration, Extension, FieldEncoder/FieldDecoder, lazy parsing of Any objects and so on. These features allow you to customize serialization/deserialization behaviour to cover different usage scenarios and meet various complex needs.

Simple API

  • Serialization

    type Student struct{
        Name string
        Age int
        Height float32
    }
    
    b, err := jsoniter.Marshal(Student{"Allen", 18, 180.43})
  • Deserialization

    type Student struct{
        Name string
        Age int
        Height float32
    }
    
    var std Student
    err := jsoniter.Unmarshal([]byte(`{"Name":"Allen","Age":18,"Height":180.43}`), &std)

Drop-in replacement of encoding/json

encoding/json can be easily migrated to json-iterator, and the encode/decode behavior before and after migration is consistent. All of your Marshal/Unmarshal function call, or existing Encoder/Decoder, Marshaler/Unmarshaler, will work properly.

// import "encoding/json"
// 
// json.Marshal(data)

import "github.com/json-iterator/go"

jsoniter.Marshal(data)

Just replace the import package with "github.com/json-iterator/go", and replace the package name from "json" with "jsoniter" when calling the api

Configuration

json-iterator provides various of serialization/deserialization configurations for different use case

api := jsoniter.Config{SortMapKeys:true}.Froze()
b, err := api.Marshal(map[string]string{"C":"c", "A":"a", "B":"b"})

In the above example, we have enabled the SortMapKeys configuration option, so that when the map is serialized, the key/value pairs are sorted. For more options, please refer to Config

Customize encoding/decoding behaviour

json-iterator provides Extension feature, we can register different Extension to customize precisely how our data is encoded to json or parsed from json

type sampleExtension struct {
    jsoniter.DummyExtension
}

func (e *sampleExtension) UpdateStructDescriptor(structDescriptor *jsoniter.StructDescriptor) {
    if structDescriptor.Type.String() != "main.testStruct" {
        return
    }

    binding := structDescriptor.GetField("TestField")
    binding.FromNames = []string{"TestField", "Test_Field", "Test-Field"}
}

type testStruct struct {
    TestField string
}

var t testStruct
jsoniter.RegisterExtension(&sampleExtension{})
err := jsoniter.Unmarshal([]byte(`{"TestField":"aaa"}`), &t)
err = jsoniter.Unmarshal([]byte(`{"Test_Field":"bbb"}`), &t)
err = jsoniter.Unmarshal([]byte(`{"Test-Field":"ccc"}`), &t)

In the above example, we registered an Extension, which specifies to which strings the TestField field name of testStruct is binded, and all the binded strings are treated as this field during parsing. For more instructions, please refer to the Extension

Extract values from json

json-iterator provides an Any feature, which allows you to schemalessly extract interesting parts from complex nested json file

jsoniter.Get([]byte(`{"Field":{"InnerField":{"Name":"Allen"}}}`), "Field", "InnerField", "Name").ToString()

Here Get returns an Any object, we get the Any object of the Name field of the nested structure, and call ToString to get the "Allen" string we want schemalessly. For more examples, please refer to Any