JSON lộn xộn đến từ đâu
Phần lớn JSON bạn gặp trong thực tế được một chương trình viết ra cho một chương trình khác, nên nó đến dưới dạng một dòng dài: phản hồi API sao chép từ tab mạng của trình duyệt, payload webhook trong tệp log, giá trị cấu hình lưu trong một cột cơ sở dữ liệu. Đọc một dòng đơn 4.000 ký tự để tìm một trường lồng sâu vừa chậm vừa dễ sai. Làm đẹp (pretty-print) đặt mỗi khóa trên một dòng riêng và thụt lề từng cấp, nên cấu trúc hiện ra chỉ trong một cái nhìn.
Chiều ngược lại cũng phổ biến không kém. Trước khi dán JSON vào biến môi trường, chuỗi truy vấn, dữ liệu kiểm thử hay tin nhắn chat, bạn thường muốn nó gọn nhất có thể. Rút gọn (minify) xóa mọi dấu cách và ký tự xuống dòng nằm ngoài giá trị chuỗi; một tệp cấu hình có thụt lề điển hình giảm 20 đến 40 phần trăm, tùy độ sâu lồng nhau.
Công cụ làm gì với dữ liệu của bạn
Đầu vào được phân tích bằng bộ phân tích JSON gốc của trình duyệt và ghi ra lại với mức thụt lề bạn chọn: 2 dấu cách, 4 dấu cách hoặc tab. Rút gọn dùng cùng con đường đó nhưng không có thụt lề. Vì tài liệu được dựng lại từ giá trị đã phân tích thay vì chỉnh sửa như văn bản, một vài chi tiết có thể thay đổi, và nên biết đó là những gì:
- Cách ghi số được chuẩn hóa.
1.0trở thành1,1e3trở thành1000, và-0trở thành0. Giá trị giữ nguyên, cách viết thì không. - Số nguyên rất lớn mất độ chính xác. JavaScript lưu số dưới dạng số thực 64 bit, chỉ chính xác đến 9.007.199.254.740.991. Một ID 19 chữ số như
12345678901234567890sẽ trở lại thành12345678901234567000. Nếu dữ liệu của bạn có ID kiểu Snowflake, bigint của cơ sở dữ liệu hoặc số tiền tính theo đơn vị nhỏ ở mức đó, hãy so sánh đầu ra trước khi dùng. - Chuỗi thoát Unicode được giải mã.
"caf\u00e9"được ghi lại thành"café". Cả hai đều là JSON hợp lệ và mang cùng một chuỗi. - Khóa trùng lặp bị gộp. Nếu một object chứa cùng một khóa hai lần, chỉ giá trị cuối cùng được giữ. Tiêu chuẩn JSON không định nghĩa khóa trùng lặp, và phần lớn bộ phân tích hành xử theo cách này.
- Khóa dạng số nguyên được đưa lên đầu. Các khóa trông giống số nguyên không âm, như
"2"hay"10", được đặt trước tiên theo thứ tự tăng dần, trước mọi khóa khác. Đây là quy tắc của object JavaScript, không phải của JSON. Các khóa văn bản thông thường giữ nguyên thứ tự gốc.
Không điều nào trong số này quan trọng với payload API thông thường, nhưng chúng quan trọng nếu bạn sắp commit một tệp đã định dạng và muốn diff tối thiểu.
Đọc vị trí lỗi
Khi phân tích thất bại, công cụ chạy một bộ quét nhỏ của riêng nó để tìm ký tự đầu tiên không thể tiếp nối một tài liệu hợp lệ, và báo vị trí đó theo dòng và cột.
Vị trí được báo là nơi bộ phân tích bỏ cuộc, không phải lúc nào cũng là nơi lỗi xảy ra:
- Dấu phẩy thừa ở cuối trong
[1, 2, ]được báo ở dấu ngoặc đóng, vì ở đó cần một giá trị. - Thiếu dấu phẩy giữa hai thuộc tính được báo ở đầu khóa thứ hai.
- Thiếu dấu ngoặc nhọn hoặc ngoặc vuông đóng được báo ở tận cuối đầu vào, đôi khi cách vấn đề thật hàng trăm dòng. Hãy tìm object hoặc mảng cuối cùng đã được mở.
- Chuỗi thiếu dấu nháy đóng được báo ở cuối dòng của nó, vì ký tự xuống dòng thô không được phép trong chuỗi JSON. Vị trí tương tự xuất hiện khi văn bản nhiều dòng được dán vào một giá trị; xuống dòng ở đó phải viết thành
\n.
Nếu đầu vào thực ra không phải JSON mà là object literal JavaScript, YAML hay dict Python in ra với dấu nháy đơn, lỗi sẽ xuất hiện ở một hai dòng đầu. Những định dạng đó trông giống nhau nhưng không thay thế được cho nhau.
Chọn mức thụt lề
- 2 dấu cách là mặc định trong phần lớn công cụ JavaScript, các tệp
package.jsonvà nhiều bộ quy tắc trình bày mã. Nó giữ cho dữ liệu lồng sâu không trôi khỏi mép phải màn hình. - 4 dấu cách khớp với những gì
json.dumps(indent=4)của Python tạo ra và dễ đọc hơn với tài liệu nông. - Tab cho phép mỗi người đọc tự chọn độ rộng hiển thị trong trình soạn thảo và tạo ra tệp hơi nhỏ hơn so với 4 dấu cách.
Với tệp nằm trong repository, hãy theo đúng kiểu dự án đang dùng; trộn nhiều kiểu khiến mọi diff đều nhiễu.
Bước tiếp theo với dữ liệu đã định dạng
Khi cấu trúc đã dễ đọc, các việc khác trở nên dễ hơn. Để trải một mảng bản ghi ra bảng tính, hãy chuyển nó bằng chuyển JSON sang CSV. Để thấy chính xác điều gì thay đổi giữa hai phiên bản của một payload, hãy định dạng cả hai với cùng mức thụt lề và so sánh trong so sánh văn bản; định dạng giống nhau nghĩa là diff chỉ hiển thị những thay đổi thật. Mọi thứ diễn ra trong trang, nên token và dữ liệu cá nhân trong payload ở lại trên thiết bị của bạn.