當前位置:
首頁 > 科技 > 為什麼 JSON 不適合作為配置語言?

為什麼 JSON 不適合作為配置語言?

許多項目用 JSON 作為配置文件。也許最著名的例子就是 npm 和 yarn 使用的 package.json,還有許多其他項目也用 JSON,如 CloudFormation(最初僅支持 JSON,現在還支持 YAML)和 composer(PHP)。

但是,有幾個原因表明 JSON 其實非常不適合作為配置語言。不要誤會,我很喜歡 JSON。它非常靈活,而且機器和人類讀起來都很容易,是個非常好的數據交換和存儲的格式。但作為配置語言,它有許多缺點。

為什麼 JSON 成了流行的配置語言?

JSON 被用於配置文件有好幾個原因。最大的原因就是很容易實現。許多語言的標準庫都支持 JSON,標準庫不支持 JSON 的語言也會有非常易用的 JSON 包。其次就是開發者和用戶都已經很熟悉 JSON 了,不需要再為產品學一種新的配置格式。更不用說 JSON 的各種相關工具,包括語法高亮、自動格式化、驗證工具等等。

這些都是很好的理由。可惜這種格式真的不適合作為配置文件。

JSON 的問題

沒有注釋

配置語言的一個絕對必要的功能就是注釋。注釋非常有用,它能標識出配置項的可能的值,以及選擇某個值的原因,還有最重要的一點就是臨時注釋掉某部分配置以方便測試和調試。而作為數據交換格式的 JSON 完全沒有使用注釋的必要。

當然也有方法解決這個問題。最常見的方法就是在對象中使用特殊的鍵作為注釋,如"//"或"__comment"。但是,這種語法並不是很易讀,而且如果要想在同一個對象中使用多個注釋,就得給每個注釋使用唯一的鍵。David Crockford(JSON的發明人)建議使用預處理器去掉注釋(https://plus.google.com/+DouglasCrockfordEsq/posts/RK8qyGVaGSr)。如果你的應用程序要求 JSON 作為配置文件,那麼我建議使用這種方法,特別是如果有某種構建過程的話。當然,這會給編輯配置帶來一些額外的工作,因此如果你正在創建的應用程序需要解析配置文件的話,不要依賴用戶去做這項工作。

一些 JSON 庫允許使用注釋。例如,Ruby 的 JSON 模塊,以及 Java 的 Jackson 庫加上啟用 JsonParser.Feature.ALLOW_COMMENTS 功能,就能支持在 JSON 中使用 JavaScript 風格的注釋。然而這並不是標準,許多編輯器也不能正常支持 JSON 文件中的注釋,使得編輯配置文件比較困難。

過分嚴格

JSON 的標準非常嚴格。嚴格的目的是為了方便 JSON 解析器的實現,但我認為,它也影響了易讀性,而且或多或少地使得人類書寫 JSON 更困難。

低信噪比

與許多其他配置語言相比,JSON 的雜訊很大。許多標點符號儘管使得機器很容易實現,但完全不能幫助人類閱讀。具體來說,對於配置文件而言,對象中的鍵幾乎必然是標識符,因此鍵的引號是完全不必要的。

而且 JSON 要求在整個文檔外面使用大括弧,這樣做的目的是使之(幾乎)成為 JavaScript 的子集,並且在發送多個 JSON 對象時易於分隔各個對象。但作為配置文件,最外層的大括弧是完全無用的。鍵值對之間的逗號大部分情況下也沒有用。通常,每一行就是一個鍵值對,所以完全可以把換行符作為分隔符。

說起逗號,JSON 還不支持末尾逗號。如果要求每個鍵值對都以逗號結尾,那麼至少應該接受末尾逗號吧,因為末尾逗號使得在末尾添加新項目很容易,而且能更容易地比較不同版本的差異。

過長的字元串

JSON 作為配置文件的另一個問題是它不支持多行字元串。如果要在字元串中使用換行,就得轉義成「
」,而且更糟糕的是,如果想在文件中寫一個跨行的字元串,那是完全沒辦法的。若是配置文件里沒有特別長的字元串的話還好。但如果配置文件里包含長字元串,比如某個項目的描述,或者 GPG 秘鑰,你肯定不希望把所有行都放在同一行里並用「
」連接起來。

數字

此外,JSON對於數字的定義在某些場合下很有問題。根據JSON標準,數字是任意精度的有限浮點數,以十進位表示。大多數情況下這沒什麼問題。但如果你需要十六進位表示,或者需要無窮大、NaN等值,那麼TOML或YAML能更好地處理這些輸入。

那應該用什麼?

配置語言的選擇取決於應用程序。每種語言都有自己的長處和短處。下面這些語言都可以考慮。這些都是專用於配置文件的語言,都比原本用於數據的 JSON 要好。

TOML

TOML(https://github.com/toml-lang/toml)作為配置語言日漸流行。它的使用者包括Cargo(Rust的編譯工具)、pip(Python包管理器)和dep(golang 依賴管理器)。TOML 有點像 INI 格式,但與 INI 不同的是,它有自己的標準,而且對於嵌套結構有很好的支持。它要比 YAML 簡單得多,所以當配置文件很簡單時,TOML就很合適。但如果配置文件有大量嵌套結構,那麼 TOML 可能會顯得有點啰嗦,此時其他語言如 YAML、HOCON 可能是更好的選擇。

HJSON

HJSON(https://hjson.org/)是個基於 JSON 的語言,但更靈活,因此更容易閱讀。它支持注釋、多行字元串、不帶引號的鍵和字元串,以及可選的逗號。如果你喜歡 JSON 的簡單結構,但希望更適合配置文件的話,可以試試HJSON。它還提供命令行工具將 HJSON 轉換成 JSON,因此如果你的工具要求 JSON 的話,你可以用 HJSON 寫配置文件,並在構建過程中轉換成 JSON。與 HJSON 相似的另一個選擇是 JSON5(https://json5.org/)。

HOCON

HOCON(https://github.com/lightbend/config/blob/master/HOCON.md)是為Play框架(https://www.playframework.com/)設計的配置語言,但在Scala項目中非常流行。它是JSON的超集,所以可以兼容JSON文件。除了注釋、可選逗號、多行字元串等標準功能之外,HOCON還支持從其他文家中導入,引用其他值的鍵以避免重複代碼,以及使用點分隔的鍵指定到某個值的路徑,這樣用戶就不需要把所有值直接放在大括弧對象里了。

YAML

YAML(YAML Ain"t Markup Language,「YAM不是標記語言」,http://yaml.org/)是個非常靈活的格式,它幾乎是JSON的超集,許多著名的項目都使用YAML,如Travis CI、Circle CI和AWS CloudFormation。YAML的庫幾乎和JSON一樣流行。除了支持注釋、換行符分隔、多行字元串、不帶引號的字元串和更靈活的類型系統之外,YAML還可以引用之前定義過的結構,從而避免代碼重複。

YAML的主要缺點就是它的標準太複雜,導致不同實現之間的不一致。它的縮進層次還有重要的語法意義(類似於Python),這也是褒貶不一的地方。複製粘貼YAML也比較困難。關於YAML的缺點可以參考「也許不是那麼好的YAML」(https://arp242.net/weblog/yaml_probably_not_so_great_after_all.html)一文。

腳本語言

如果你的應用程序是用某種腳本語言寫的,如 Python 或 Ruby,而且配置文件的來源可信,那麼最好的選擇就是用那種語言本身編寫配置文件。對於編譯語言,如果需要真正靈活的配置選項,也可以嵌入類似 Lua 這種腳本語言。這樣可以享受到腳本語言的靈活性,而且比使用另一種配置文件更容易。但使用腳本語言的缺點就是它可能過於強大,而且如果配置語言的來源不可信,這樣做會引入很嚴重的安全問題。

編寫自己的配置語言

如果出於某種原因,鍵值配置格式不符合你的要求,並且由於性能或大小限制不能使用腳本語言,那麼可能自己寫一個配置格式更合適。但在這樣做之前,務必要認真考慮,因為這樣做不僅需要自行維護解析器,還需要讓你的用戶熟悉一種新的配置格式才行。

結論

有了這麼多配置語言的選擇,使用JSON並不是個好注意。如果你要創建新的應用、框架或庫,需要一個配置文件,那麼選擇JSON之外的格式吧。

原文:https://www.lucidchart.com/techblog/2018/07/16/why-json-isnt-a-good-configuration-language/

作者:Thayne McCombs Lucidchart。

譯者:彎月,責編:屠敏

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 CSDN 的精彩文章:

Firefox 居然連 IE 都不如!
為什麼微型晶元是機器學習的命門?

TAG:CSDN |