JSON & Marshal Unmarshal
The Point
Marshal converts an in-memory data structure into a transmittable format (like JSON). Unmarshal does the reverse – it turns JSON back into a data structure. Most APIs use JSON because it is human-readable, natively supported by JavaScript, and universally available across languages.
Explanation
Marshal / Unmarshal
1type ShippingClass struct {
2 Name string `json:"name"`
3 Lang string `json:"lang"`
4}
5
6// Unmarshal: JSON string → struct
7jsonStr := `{"name": "標準配送", "lang": "zh"}`
8var obj ShippingClass
9json.Unmarshal([]byte(jsonStr), &obj)
10// obj.Name == "標準配送"
11
12// Marshal: struct → JSON string
13data, _ := json.Marshal(obj)
14// data == {"name":"標準配送","lang":"zh"}This is not limited to JSON – serialization for XML, YAML, and protobuf is also called marshal/unmarshal. Same concept, different formats.
Why do most APIs use JSON?
- Human-readable: you can read it directly when debugging; binary formats like protobuf cannot do this
- Native JS support: browsers parse JSON at zero cost, no extra handling on the frontend
- Universal: almost every language has a mature JSON library
- Less verbose than XML: XML’s opening and closing tags add a lot of overhead
Knowledge Sugar
What are Go struct tags?
The json:"name" tag tells Go’s JSON library which key name this field maps to in JSON. Without a tag, it defaults to the field name (case-sensitive):
1type Example struct {
2 DisplayName string `json:"display_name"` // JSON key is display_name
3 Age int `json:"age,omitempty"` // omitempty: omit this key when value is zero
4 Internal string `json:"-"` // never output to JSON
5}Downsides of JSON
JSON is not without problems. In high-performance scenarios (internal microservice communication), protobuf is the usual choice:
| JSON | Protobuf | |
|---|---|---|
| Readability | Human-readable | Binary |
| Performance | Slower (string parsing) | Fast (binary decode) |
| Schema | Not enforced | Enforced (.proto definition) |
| Use case | External public APIs | Internal microservices |