Tất cả bài viết

JSON Diff: so sánh cấu trúc khác gì so sánh văn bản

Nếu so sánh hai tài liệu JSON bằng diff văn bản thông thường (như dùng cho mã nguồn), kết quả thường gây hiểu lầm: cùng một dữ liệu có thể được viết với thứ tự khóa khác nhau, thụt lề khác nhau, hoặc số khoảng trắng khác nhau — và diff văn bản sẽ báo "khác biệt" ở nơi dữ liệu thực ra giống hệt nhau.

So sánh cấu trúc

JSON Diff dựa trên cấu trúc sẽ phân tích cả hai tài liệu thành một cây giá trị và so sánh chính dữ liệu đó: một trường có tồn tại không, nó chứa giá trị gì, kiểu dữ liệu có khớp không. Thứ tự khóa của object, khoảng trắng thừa hay kiểu thụt lề không được tính đến — chúng không phải là một phần của dữ liệu.

Diff hiển thị gì

Kết quả so sánh cấu trúc điển hình làm nổi bật ba loại thay đổi: các trường được thêm vào tài liệu thứ hai, các trường bị xóa khỏi tài liệu đầu tiên, và các trường tồn tại ở cả hai nhưng có giá trị khác nhau. Với mảng, việc so sánh phức tạp hơn — cần quyết định so sánh phần tử theo vị trí hay cố gắng khớp các object tương tự.

Vì sao cần đến điều này

  • So sánh phản hồi API trước và sau khi thay đổi ở backend để xem sự khác biệt dữ liệu thực sự.
  • Kiểm tra xem một thay đổi trong tệp cấu hình có ảnh hưởng đến điều gì ngoài dự kiến hay không.
  • Phát hiện lỗi hồi quy trong kiểm thử khi JSON mong đợi và JSON thực tế khác nhau.

Khi hai tệp dịch giống hệt nhau nhưng diff vẫn báo khác biệt

Văn bản tiếng Việt có thể được lưu ở hai dạng chuẩn hóa Unicode khác nhau nhưng hiển thị giống hệt nhau: NFC (mỗi chữ có dấu là một điểm mã duy nhất) hoặc NFD (chữ cái và dấu thanh là các điểm mã tách rời). Nếu một tệp vi.json được xuất từ macOS còn tệp kia được chỉnh sửa trên Windows, hai tệp có thể trông giống hệt nhau trên màn hình nhưng khác nhau ở cấp độ byte — một diff cấu trúc đơn giản (so sánh chuỗi bằng nhau) sẽ báo mọi khóa dịch tiếng Việt là "đã thay đổi", dù nội dung thực chất không đổi. Cần chuẩn hóa cả hai tệp về cùng một dạng Unicode trước khi so sánh để tránh hàng loạt khác biệt giả.

So sánh mảng: theo vị trí hay theo khóa

Cách đơn giản nhất là so sánh các phần tử mảng theo chỉ số tương ứng, nhưng nếu một phần tử mới được chèn vào giữa mảng, mọi vị trí sau đó sẽ "dịch chuyển" và diff sẽ hiển thị thay đổi ở mọi phần tử sau điểm chèn, dù thực tế chỉ có một phần tử thay đổi. Các công cụ thông minh hơn cố gắng khớp các phần tử theo một trường duy nhất (ví dụ id) để hiển thị đúng là chèn hay xóa, thay vì một chuỗi thay đổi giả.

Dùng thử công cụ