對比yaml,toml,json三種格式的優缺點及三種格式的支持特性,以及講述了nginx.conf轉化成yaml,toml格式的樣式 ...
wmproxy
wmproxy
將用Rust
實現http/https
代理, socks5
代理, 反向代理, 靜態文件伺服器,後續將實現websocket
代理, 內外網穿透等, 會將實現過程分享出來, 感興趣的可以一起造個輪子法
項目 ++wmproxy++
gite: https://gitee.com/tickbh/wmproxy
github: https://github.com/tickbh/wmproxy
瞭解三種格式
Json
- JSON是一種輕量級的數據交換格式,被廣泛使用在Web應用程式之間傳輸數據。
- JSON使用大括弧{}來表示數據結構,使用冒號:來連接鍵和值。
- JSON支持字元串、數字、布爾值、null、數組和對象等多種數據類型。
- JSON文件通常用於數據交換、存儲等場景,也可以用作配置文件。
JSON簡單易讀存儲通用,但JSON原生不支持註釋用來做配置文件比較硬傷。
它流行度極高,基本上每個程式員都和他打過交道。
多層級時,對齊和縮進不好控制,容易出錯
Yaml
- YAML被設計為一種可讀性極強的數據序列化標準,可以用來表達層次化數據。
- YAML使用空格縮進來表示數據層次結構。
- YAML支持浮點數、布爾值、字元串、數組、映射等多種數據類型。
- YAML文件通常用於配置文件、數據交換等場景。
與JSON及TOML相比,結構比較緊湊
但相對用空格縮近,編寫及拷貝時出錯的機率比JSON及TOML高許多
Toml
TOML 旨在成為一個語義明顯且易於閱讀的最小化配置文件格式。
TOML 應該能很容易地被解析成各種語言中的數據結構。
- TOML是一種簡潔明瞭的鍵值對格式,被設計成可以很容易地映射為哈希表。
- TOML使用等號(=)來連接鍵和值,使用縮進來表示數據層次結構。
- TOML支持整數、浮點數、字元串、布爾值、數組、字典等多種數據類型。
- TOML文件通常用於配置文件、數據交換等場景。
它
易於閱讀和編寫
,語法靈活
與JSON配置相比,TOML在簡潔性方面遠遠勝出;
與YAML配置相比,TOML在簡潔性以及語法靈活性方面遠遠勝出。
三種格式測試數據的對比
我們用Rust的項目配置文件來做對比,為了展示所有的類型,格式有所變更。它以Toml來做配置文件,我們首先先展示toml的格式
內容包含創建者,創建時間,項目名稱,項目依賴等信息,如果我們將其轉化成可配置的JSON格式時
toml
create="tickbh"
create_time=2023-09-08T10:30:00Z
[project]
# 項目名稱
name="wmproxy"
version="1.1"
editor=2022
# 項目依賴
[project.dependencies]
wenmeng={version = "0.1.21", default-features = false, features = ["std", "tokio"]}
webparse={version = "0.1", default-features = false}
行數12行,註釋兩行,全部頂格開頭,原生支持時間格式
json
{
"create": "tickbh",
"create_time": "2023-09-08T10:30:00.000Z",
"project": {
"name": "wmproxy",
"version": "1.1",
"editor": 2022,
"dependencies": {
"wenmeng": {
"version": "0.1.21",
"default-features": false,
"features": [
"std",
"tokio"
]
},
"webparse": {
"version": "0.1",
"default-features": false
}
}
}
}
行數23行,層次的遞進比較多,不容易對齊,無法註釋,不支持時間格式
yaml
create: tickbh
create_time: 2023-09-08T10:30:00.000Z
project:
# 項目名稱
name: wmproxy
version: "1.1"
editor: 2022
# 項目依賴
dependencies:
wenmeng:
version: 0.1.21
default-features: false
features:
- std
- tokio
webparse:
version: "0.1"
default-features: false
行數18行,註釋兩行,原生支持時間格式,到features
這級行,深度相對較高,但是一眼看上去比json
清晰
相對來說JSON比較不適合做比較複雜的配置文件,但
VSCODE
使用的拓展的JSON以支持註釋功能。
接下來嘗試將nginx.conf格式做轉換
以下嘗試的將
http {
gzip on;
server {
listen 80; #監聽80的服務埠
server_name wm-proxy.com; #監聽的功能變數名稱
location /products {
proxy_pass http://127.0.0.1:8090/proxy;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Origin' '*';
}
location / {
root wmproxy;
index index.html index.htm;
}
}
}
我們也模仿類似的結構,但是對於toml
,yaml
,json
來說,都沒有一個key兩個值的,要麼我們只能用對應的數組,此時我來先來初步重構類似的結構。以下我們以toml結構為例,我們分析table的級數有三級,最外層為http
,中間層為server
為數組,最內層為location
也為數組,headers
我們用之前提到過的mappings
,用proxy
開頭來表示重寫Reqeust
,其它的來表示重寫Response
,文件系統我們用上節提到的file_server
。
我們先定義http
的table,他只有一個屬性gzip為on
[http]
gzip="on"
其次server
為一個數組,那麼我們可以如下定義,有綁定地址和server_name
[[http.server]]
bind_addr="127.0.0.1:80"
server_name="wm-proxy.com"
再然後location
也為一個數組,定義如下
[[http.server.location]]
rule = "/products"
reverse_proxy = "http://127.0.0.1:8090/proxy"
headers = [
["+", "Access-Control-Allow-Credentials", "true"],
["+", "Access-Control-Allow-Origin", "*"]
]
[[http.server.location]]
rule = "/"
file_server = { root="wmproxy", browse = true, index=["index.html", "index.htm"] }
那麼,最終的結構為如下:
[http]
gzip="on"
[[http.server]]
bind_addr="127.0.0.1:80"
server_name="wm-proxy.com"
[[http.server.location]]
rule = "/products"
reverse_proxy = "http://127.0.0.1:8090/proxy"
headers = [
["+", "Access-Control-Allow-Credentials", "true"],
["+", "Access-Control-Allow-Origin", "*"]
]
[[http.server.location]]
rule = "/"
file_server = { root="wmproxy", browse = true, index=["index.html", "index.htm"] }
而yaml的格式結構如下:
http:
gzip: on
server:
- bind_addr: 127.0.0.1:80
server_name: wm-proxy.com
location:
- rule: /products
reverse_proxy: http://127.0.0.1:8090/proxy
headers:
- - +
- Access-Control-Allow-Credentials
- "true"
- - +
- Access-Control-Allow-Origin
- "*"
- rule: /
file_server:
root: wmproxy
browse: true
index:
- index.html
- index.htm
而json的格式結構如下:
{
"http": {
"gzip": "on",
"server": [
{
"bind_addr": "127.0.0.1:80",
"server_name": "wm-proxy.com",
"location": [
{
"rule": "/products",
"reverse_proxy": "http://127.0.0.1:8090/proxy",
"headers": [
[
"+",
"Access-Control-Allow-Credentials",
"true"
],
[
"+",
"Access-Control-Allow-Origin",
"*"
]
]
},
{
"rule": "/",
"file_server": {
"root": "wmproxy",
"browse": true,
"index": [
"index.html",
"index.htm"
]
}
}
]
}
]
}
}
- 自建的好處是比較清晰,可以自定義自己合適的結構,但是編寫者需要重新開始學習,而用能用的配置文件需要遵循它的格式定義
- 像toml文件,如果層級很深,他的key值配置會很長,因為他一旦定義一個table,就是從最頂級來解析,但是編寫者只要熟悉過這配置文件很快就能寫出滿意的配置文件
- 而yaml的層級結構相對會需要去看對齊與否,編寫的時候需要額外註意,因為弄錯了縮進,層級就會發生錯誤
- 而json最後結尾的會有相當多的花括弧,相對比較容易弄錯。JSON總體來說不太適合做比較複雜的配置文件
結語
在不考慮自建格式的情況下,如nginx的nginx.conf
,如caddy的Caddyfile
,將會同時相容toml
及yaml
格式的配置文件。