Độ phức tạp ẩn giấu của YAML gây tranh luận trong cộng đồng lập trình viên về các định dạng cấu hình thay thế

Nhóm Cộng đồng BigGo
Độ phức tạp ẩn giấu của YAML gây tranh luận trong cộng đồng lập trình viên về các định dạng cấu hình thay thế

Một phân tích kỹ thuật gần đây làm nổi bật nhiều lỗ hổng phân tích cú pháp của YAML đã khơi lại các cuộc thảo luận về định dạng tệp cấu hình trong cộng đồng lập trình viên. Mặc dù YAML được thiết kế để thân thiện với con người hơn JSON , nhưng độ phức tạp của nó đã tạo ra những hành vi bất ngờ khiến ngay cả những lập trình viên có kinh nghiệm cũng bị bắt gặp.

Nghịch lý về sự đơn giản

Vấn đề cốt lõi xuất phát từ mục tiêu đầy tham vọng của YAML là có thể đọc được bởi con người trong khi vẫn duy trì khả năng phân tích cú pháp bằng máy. Không giống như JSON chỉ sử dụng sáu sơ đồ railroad trong đặc tả của mình, YAML yêu cầu 10 chương với hệ thống đánh số phần có bốn cấp độ sâu và một trang errata chuyên dụng. Độ phức tạp này biểu hiện theo nhiều cách có vấn đề mà các lập trình viên thường xuyên gặp phải.

Vấn đề Norway minh họa hoàn hảo những vấn đề này. Các mã quốc gia như NO ( Norway ) tự động được chuyển đổi thành giá trị boolean false, tạo ra lỗi im lặng trong các tệp cấu hình. Tương tự, các giá trị như on, off, yes và no được hiểu là boolean thay vì chuỗi, dẫn đến hành vi bất ngờ khi những từ phổ biến này xuất hiện trong dữ liệu cấu hình.

Tóm tắt các vấn đề phân tích YAML:

  • Vấn đề Norway: Mã quốc gia như "NO" được chuyển đổi thành boolean false
  • Chuyển đổi Boolean: "on", "off", "yes", "no" tự động trở thành boolean
  • Số thập lục phân: "22:22" được phân tích như biểu thức toán học (1342) thay vì chuỗi
  • Chuỗi không có dấu ngoặc kép: Chuyển đổi kiểu tự động tạo ra các hành vi không mong muốn
  • Đặc tả phức tạp: 10 chương với các phần sâu 4 cấp so với 6 sơ đồ railroad của JSON

Số thập lục phân và những bất ngờ khác

Một trong những tính năng kỳ lạ nhất của YAML là hỗ trợ số sexagesimal (cơ số 60). Một giá trị giống như timestamp như 22:22 được phân tích như một biểu thức toán học thay vì chuỗi, tạo ra số thập phân 1342. Tính năng này, có lẽ được thêm vào để hỗ trợ giá trị thời gian, tạo ra sự nhầm lẫn trong các ngữ cảnh mà việc phân tích như vậy là không mong muốn.

Cộng đồng đã xác định thêm các bẫy phân tích cú pháp bao gồm chuyển đổi kiểu tự động của các chuỗi không có dấu ngoặc kép, hệ thống anchor và alias phức tạp, và hỗ trợ cho các khóa không phải chuỗi có thể bị lỗi theo những cách tinh vi.

Giải pháp cộng đồng và cách khắc phục

Các lập trình viên đã phát triển nhiều chiến lược khác nhau để giảm thiểu các vấn đề của YAML . Cách tiếp cận phổ biến nhất bao gồm việc đặt dấu ngoặc kép cho tất cả các giá trị chuỗi, điều này loại bỏ hầu hết các vấn đề chuyển đổi kiểu tự động. Các công cụ như yamllint có thể phát hiện nhiều vấn đề trong quá trình phát triển, mặc dù điều này thêm độ phức tạp vào những gì lẽ ra phải là một định dạng cấu hình đơn giản.

Hầu hết tất cả điều này được giải quyết bằng cách cơ bản là đặt dấu ngoặc kép xung quanh các chuỗi. YAML có các trường hợp sử dụng mà bạn muốn những thứ mà JSON không làm được như đệ quy hoặc anchors/aliases/tags.

Một số nhóm đã áp dụng StrictYAML , một tập con loại bỏ các tính năng có vấn đề bằng cách chỉ hỗ trợ chuỗi, danh sách và từ điển. Những nhóm khác tạo JSON từ các ngôn ngữ phù hợp hơn thay vì viết tay YAML , điều này cung cấp khả năng trừu tượng hóa và tái sử dụng tốt hơn.

Các Chiến lược Giảm thiểu YAML:

  • Đặt Tất cả Chuỗi trong Dấu Ngoặc Kép: Loại bỏ hầu hết các vấn đề chuyển đổi kiểu tự động
  • Sử dụng yamllint: Phát hiện các vấn đề phổ biến trong quá trình phát triển
  • Tránh các Key Có Vấn đề: Không sử dụng "on", "off", "yes", "no" làm key không có dấu ngoặc kép
  • Tạo JSON: Sử dụng các ngôn ngữ lập trình để tạo JSON thay vì viết tay YAML
  • Áp dụng StrictYAML: Sử dụng tập con loại bỏ các tính năng có vấn đề

Tìm kiếm các lựa chọn thay thế tốt hơn

Cuộc thảo luận đã làm nổi bật một số định dạng cấu hình thay thế đang thu hút sự chú ý. TOML cung cấp sự đơn giản mà không có những lỗ hổng của YAML nhưng thiếu tính biểu đạt cho các cấu hình phức tạp. HashiCorp Configuration Language ( HCL ) cung cấp khả năng xác thực tăng độ tin cậy trong các thiết lập lớn hơn. Các tùy chọn thử nghiệm hơn như CUE , Dhall và KDL cố gắng giải quyết các thiếu sót của YAML với các cách tiếp cận khác nhau đối với quản lý cấu hình.

JSON5 và JSONC ( JSON với comments) đã nổi lên như các giải pháp trung gian, thêm hỗ trợ comment làm cho YAML hấp dẫn trong khi duy trì hành vi phân tích cú pháp có thể dự đoán được của JSON . Tuy nhiên, các định dạng này thiếu sự chấp nhận rộng rãi khiến YAML trở nên phổ biến trong các quy trình phát triển hiện đại.

Các Định Dạng Cấu Hình Thay Thế:

  • TOML: Định dạng đơn giản không có những lỗ hổng của YAML , khả năng biểu đạt hạn chế
  • HCL (HashiCorp): Khả năng xác thực, tốt cho infrastructure as code
  • JSON5/JSONC: JSON với comments và dấu phẩy cuối
  • StrictYAML: Tập con của YAML chỉ với strings, lists và dictionaries
  • CUE/Dhall/KDL: Các định dạng thử nghiệm giải quyết những thiếu sót của YAML
  • Jsonnet: Ngôn ngữ templating tạo ra JSON

Vấn đề tồn tại lâu dài

Bất chấp các vấn đề được ghi nhận rõ ràng, YAML vẫn được nhúng sâu trong các công cụ phổ biến như Kubernetes , Ansible và vô số hệ thống CI/CD . Điều này tạo ra hiệu ứng mạng lưới nơi các lập trình viên phải làm việc với YAML bất kể sở thích của họ. Sức hấp dẫn trực quan của định dạng thông qua cấu trúc dựa trên thụt lề tiếp tục thu hút người dùng, ngay cả khi họ gặp phải những phức tạp trong phân tích cú pháp.

Cuộc tranh luận phản ánh một thách thức rộng lớn hơn trong phát triển phần mềm: cân bằng giữa khả năng đọc của con người với khả năng phân tích cú pháp của máy. Trong khi YAML thành công trong việc tạo ra một định dạng trông sạch sẽ và có thể đọc được, độ phức tạp ẩn giấu của nó thường làm suy yếu những lợi ích về năng suất mà nó được cho là mang lại.

Khi cộng đồng tiếp tục khám phá các lựa chọn thay thế, sự đồng thuận dường như là nhận thức thay vì từ bỏ. Hiểu được các lỗ hổng của YAML , sử dụng công cụ phù hợp và biết khi nào nên chọn các lựa chọn thay thế dường như là con đường thực dụng phía trước cho hầu hết các nhóm phát triển.

Tham khảo: The yaml document from hell