假設你打開天氣 App,畫面上出現「台北 28°C,降雨機率 40%」。這幾個數字不一定是 App 自己算出來的,它可能只是向天氣服務發出一個請求,幾秒後收到一份資料。那份資料不能只寫成「今天有點熱,可能會下雨」,因為程式需要知道哪個數字是溫度、哪個數字是降雨機率,也需要一套穩定的方式把它們拆開。於是服務可能回傳下面這種東西:
{
"city": "Taipei",
"temperature": 28,
"rain_probability": 40
}
這就是 JSON。全名是 JavaScript Object Notation,但它現在早就不是 JavaScript 專用的東西。Python、Java、Go、Rust、Swift 幾乎都有成熟的方法讀寫 JSON;Web API 也大量使用它交換資料。JSON 本質上是一種文字格式,用固定的語法把結構化資料寫出來,讓不同程式可以傳送、保存,再重新解析。
先記一句:JSON 不是資料庫,也不是程式語言。它只是描述資料的一種格式。
大括號裡真正放的是 key 和 value
上面的例子最外層是一個 object,也就是物件。每一筆資料都有一個名稱和一個值,例如 "city" 是 key,"Taipei" 是它的 value;"temperature" 是另一個 key,對應的值是數字 28。不同欄位之間用逗號分開,key 和 value 中間用冒號連接。
這種形式很適合描述一個「東西有哪些屬性」。一個使用者可以有名字、年齡和登入狀態;一篇文章可以有標題、作者和發布日期;一筆訂單可以有金額、商品和付款狀態。只要雙方先講好每個 key 代表什麼,程式就能穩定地把資料取出來。
如果有很多筆資料,就會看到中括號
JSON 不只有 object,還有 array,也就是陣列。假設一個 API 要一次回傳三篇文章,它可能長這樣:
[
{ "title": "API 是什麼?", "category": "Software" },
{ "title": "LLM 到底是什麼?", "category": "AI" },
{ "title": "JSON 是什麼?", "category": "Software" }
]
最外面的 [ ] 表示這是一組有順序的值,而裡面每一筆又可以是 object。Object 裡也能再放 array,array 裡也能再放 object,所以 JSON 可以層層巢狀下去。真實 API 回傳的資料常常就是這樣:一個使用者物件裡有多筆訂單,每筆訂單裡又有商品陣列。
JSON 能放的型別,其實比 JavaScript 少
標準 JSON 的值只有幾種:object、array、number、string、true、false 和 null。字串必須用雙引號,布林值是小寫的 true 或 false,而 null 通常表示這個位置目前沒有值。
也因為規則刻意保持簡單,很多 JavaScript 裡存在的東西不能直接放進 JSON。undefined 不行,函式不行,NaN 也不是合法 JSON 值;標準 JSON 也不能隨手插入註解。這些限制不是缺陷,而是讓不同程式語言在交換資料時比較不容易各自解讀成不同意思。
合法 JSON:{ "active": true, "nickname": null }
不是合法 JSON:{ name: 'Norelyn', value: undefined }
JSON 看起來像 JavaScript object,但兩者不是同一件事
這是最容易搞混的地方。JavaScript object 是程式執行時真正存在記憶體裡的資料結構,可以有方法、原型,也遵守 JavaScript 自己的語法;JSON 則是一段文字。你把 object 傳到網路另一端之前,通常要先把它轉成 JSON 字串;收到 JSON 之後,再把那段文字解析回程式能操作的資料結構。
這兩個動作常被叫做 serialization 和 parsing。JavaScript 裡常見的是 JSON.stringify() 和 JSON.parse();其他語言也有自己的 JSON 函式庫。重點不是背函式名稱,而是理解:網路上傳遞的那一刻,通常傳的是一串符合 JSON 規則的文字,不是把某個程式語言裡的物件整顆搬過去。
這就是 API 為什麼經常跟 JSON 綁在一起
在 API 裡,兩個系統需要先約定「怎麼送資料」和「資料長什麼樣」。JSON 很適合做這件事:格式簡單、文字可讀、幾乎所有主流程式語言都能處理,而且 object 和 array 已經足以表示大量常見資料結構。
例如前端登入後,後端可能回傳:
{
"user": {
"id": 502,
"name": "Chia-Jui"
},
"authenticated": true
}
前端不需要知道後端是 Node.js、Python 還是 Go,也不需要知道資料最早存在 PostgreSQL 還是其他系統裡。只要 API 合約規定這個欄位叫 user、裡面有 id 和 name,雙方就能合作。JSON 在這裡扮演的不是業務邏輯,而是資料搬運時共同使用的語法。
JSON 和 Database 也不是同一層東西
Database 負責長期保存、查詢、更新與管理資料;JSON 則只是其中一種資料表示方式。資料庫的一列資料可以被 API 取出後轉成 JSON 傳給前端,前端送來的 JSON 也可以被後端驗證,再寫進資料庫。
有些資料庫確實能直接儲存 JSON 或 JSON-like document,但那不代表「用了 JSON 就等於用了資料庫」。一個存在硬碟裡的 data.json 檔案可以保存資料,卻沒有自動得到完整資料庫會提供的索引、交易、併發控制、權限與查詢能力。格式和資料管理系統,仍然是兩回事。
JSON 也不保證資料是對的
一段 JSON 只要語法合法,解析器就能讀;但這不代表內容符合你的系統需求。{ "age": -900 } 是合法 JSON,卻很可能是錯誤資料;{ "temperature": "banana" } 也可以合法解析,只是欄位型別明顯不符合原本約定。
所以真正的 API 系統通常還會做 validation,也就是驗證。它會檢查必要欄位有沒有出現、型別對不對、數值範圍是否合理,甚至使用 JSON Schema 或應用程式自己的型別定義描述資料結構。JSON 負責的是「這段資料怎麼寫」,不是「這段資料在商業規則上合不合理」。
為什麼不是所有東西都用 JSON?
JSON 很常見,但它不是任何情況下都最好的格式。大型圖片、影片和音訊本來就不適合硬塞成 JSON;大量數值資料可能更適合二進位格式;需要串流、極高效率或嚴格 schema 的系統,也可能使用 Protocol Buffers、MessagePack 或其他格式。甚至同樣是文字資料,設定檔也常看到 YAML、TOML。
所以 JSON 的位置其實很普通:它沒有負責儲存全世界的資料,也沒有執行任何程式。它只是剛好找到了一個很好用的平衡點——人還看得懂,程式也很容易解析,跨語言交換資料時不需要帶太多額外規則。
下次在 API 回應裡看到一大片大括號,不需要先把它當成程式碼。先找最外層是 object 還是 array,再看每個 key 對應什麼 value,資料的結構通常就會慢慢浮出來。
JSON 做的事情只有一件:把結構化資料寫成一套大家同意的文字格式,讓它可以從一個系統走到另一個系統。