Skip to content

Serialization: "dịch" data

Core

Data transmit qua network thế nào? Như: lời 1 người, làm sao người khác hiểu? Serialization giải "dịch data" — biến object trong memory thành format transmittable.


0. Sao cần serialization?

Scene 1: FE nhận data "đã đổi"

javascript
// BE gửi
Date birth = new Date(1990, 5, 15)

// FE nhận
{ "birth": "1990-06-15T00:00:00Z" }  // String!

FE muốn .getFullYear() → error: không phải Date object, là string.

Scene 2: Mã loạn

json
// Mong
{ "name": "Hoàng" }
// Nhận
{ "name": "Ho�ng" }

Encoding inconsistency → mã loạn.

Scene 3: Bottleneck performance

json
// Response 10000 product, 5.2MB, 3.5s

JSON redundancy → packet quá lớn, perf tệ.


Serialization = "dịch": biến memory object thành format transmittable, bên nhận dịch ngược.


1. Serialization / Deserialization

Serialization = object → format transmittable. Deserialization = format transmittable → object.

1.1 Ẩn dụ gửi hàng

Gửi hàngSerializationNote
Đóng góiSerializationĐóng hộp, dán nhãn
Vận chuyểnNetwork transmissionXe giao
Mở góiDeserializationNgười nhận mở hộp

1.2 Sao cần?

Lý doNoteVd
Network transmissionNetwork chỉ byte streamAPI, RPC
PersistenceDisk chỉ byteLưu object vào file, DB
Cross-languageData structure ngôn ngữ khác nhauJava object → Python dict
Distributed cacheRedis/Memcached lưu byteCache user info

2. Common format

🔄序列化演示
📦内存对象
const user = {
  id: 123,
  name: "张三",
  email: "zhangsan@example.com",
  age: 28
};
内存中的对象,只能在当前进程使用
序列化
{}JSON 字符串68 bytes
{
  "id": 123,
  "name": "张三",
  "email": "zhangsan@example.com",
  "age": 28
}
可在网络传输、可跨语言
传输
💻二进制52 bytes
七进制编码 (MessagePack):
§ id 7b
¤ name £ 张三
¥ email ± zhangsan@example.com
£ age 1c
Protobuf/MessagePack,更小更快
📊 格式对比
格式
大小
速度
可读性
跨语言
JSON
★★★☆☆
★★★☆☆
★★★★★
★★★★★
XML
★★☆☆☆
★★☆☆☆
★★★★★
★★★★★
Protobuf
★★★★★
★★★★★
★☆☆☆☆
★★★★☆
MessagePack
★★★★☆
★★★★☆
★★☆☆☆
★★★★★

2.1 JSON: phổ biến nhất

Ưu:

  • Readable, debug dễ
  • Mọi ngôn ngữ support
  • Browser native (JSON.parse/stringify)

Nhược:

  • Size lớn (nhiều {} "")
  • Không hỗ trợ type phong phú (Date, Map, Set convert thành string)

Hợp: public API, FE-BE comm, config file.

2.2 XML: từng mainstream

xml
<?xml version="1.0" encoding="UTF-8"?>
<user>
  <id>123</id>
  <name>Hoàng</name>
</user>

Ưu: structure rõ, hỗ trợ comment + nested phức tạp, có Schema validation. Nhược: size lớn, parse chậm, tag redundant. Hợp: config file (Spring), SOAP, complex data exchange.

2.3 Protobuf: hiệu quả nhất

protobuf
syntax = "proto3";
message User {
  int32 id = 1;
  string name = 2;
}

Ưu: size nhỏ (smaller JSON 30-50%), parse nhanh (5-10x), backward compatible. Nhược: không readable (binary), cần .proto file define, không hỗ trợ dynamic type. Hợp: microservice nội bộ, high-perf (game, realtime), mobile (tiết kiệm bandwidth).

2.4 MessagePack: cân bằng

JSON binary version. Cùng data, smaller JSON ~30%.

Ưu: smaller + faster JSON, giữ JSON model. Nhược: không readable, không bằng Protobuf. Hợp: cần perf nhưng không muốn Protobuf, Redis cache, WebSocket message.


3. Lib mỗi ngôn ngữ

LangJSONProtobufXML
JSJSON.stringify()protobuf.jsfast-xml-parser
Pythonjson.dumps()protobufxmltodict
JavaJackson/Gsonprotobuf-javaJAXB
Goencoding/jsonprotoencoding/xml
C#System.Text.JsonGoogle.ProtobufSystem.Xml

Selection

  • FE-BE comm: JSON (debug dễ)
  • Microservice nội bộ: Protobuf (perf tốt nhất)
  • Config: JSON / YAML
  • Legacy: XML (có thể bắt buộc)

4. Performance

4.1 Size (user object)

FormatSizevs JSON
JSON68 bytes100%
XML142 bytes209%
Protobuf38 bytes56%
MessagePack52 bytes76%

4.2 Speed (10000 lần)

FormatTimevs JSON
JSON45 ms100%
XML120 ms267%
Protobuf8 ms18%
MessagePack28 ms62%

5. Common issues

5.1 Date serialization

javascript
const date = new Date('2024-01-01')
JSON.stringify(date)  // "2024-01-01T00:00:00.000Z"

Solution:

javascript
// Cách 1: timestamp
{ createdAt: date.getTime() }  // 1704067200000

// Cách 2: ISO string
{ createdAt: date.toISOString() }

// Cách 3: custom serialization
JSON.stringify(obj, (key, value) => {
  if (value instanceof Date) {
    return { __type: 'Date', value: value.toISOString() }
  }
  return value
})

5.2 Circular reference

javascript
const obj = { name: 'test' }
obj.self = obj
JSON.stringify(obj)  // TypeError

Solution:

javascript
// Cách 1: filter circular
const seen = new WeakSet()
JSON.stringify(obj, (key, value) => {
  if (typeof value === 'object' && value !== null) {
    if (seen.has(value)) return
    seen.add(value)
  }
  return value
})

// Cách 2: flatted lib
import { stringify } from 'flatted'
stringify(obj)

5.3 Mã loạn tiếng Việt

Lý do: encoding inconsistent (UTF-8 vs others), BOM marker.

Solution:

python
# Python UTF-8
import json
json.dumps(data, ensure_ascii=False)
javascript
// Node.js
res.setHeader('Content-Type', 'application/json; charset=utf-8')

6. Thực chiến: e-commerce serialization

ScenarioFormatLý do
App → BE APIJSONDebug dễ, FE-BE unified
BE → BE RPCProtobufPerf tốt nhất, tiết kiệm bandwidth
Cache RedisMessagePackSmaller JSON, serialize object phức tạp
LogJSONLog analysis tool parse được

Glossary

TermFullNote
Serialization-Object → byte stream
Deserialization-Byte stream → object
JSONJavaScript Object NotationCommon text format
XMLExtensible Markup LanguageMarkup, từng mainstream
ProtobufProtocol BuffersGoogle open-source high-perf
MessagePack-JSON binary
Encoding-Char → byte
Decoding-Byte → char

2026 cho VN dev

  • Protobuf + gRPC: microservice standard internal
  • MessagePack popular cho Redis cache
  • JSON Schema / Zod: runtime validation, super useful
  • OpenAPI: API spec chuẩn, gen client SDK
  • VN context: e-commerce internal microservice nên xài gRPC; public API vẫn JSON
  • AI streaming: Server-Sent Events dùng JSON line-by-line