2010-01-21 35 views
6

我負責定義兩個Web應用程序之間的通信。我決定爲此使用JSON。在JSON中有一個根節點有多常見?JSON中的根節點

比方說,我們有一個汽車對象。這是「汽車」作爲根節點的JSON:

{"Car": { 
    "Make":"Mustang", 
    "YearBuilt":"1999"}} 

所以,現在讓我們說我有一個輪胎對象,因爲我們規範在具有根節點,這其中也有擁有它。

{"Tire": {"Make": "Brirdgestone", "Size":"15"}} 

將輪胎對象JSON集成到原始Car對象中顯示它可能有多笨拙。

{"Car": { "Make":"Mustang", 
"YearBuilt":"1999", 
"Tires": "[{"Tire": {"Make": "Brirdgestone", "Size":"15"}}, 
{"Tire": {"Make": "Brirdgestone", "Size":"15"}}, 
{"Tire": {"Make": "Bridgestone", "Size":"15"}}, 
{"Tire": {"Make": "Brirdgestone", "Size":"15"}} 
]}} 

所以在PHP連載,第一輪胎的品牌將是$object->Car->Tires[0]->Tire->Make。由於根節點,在那裏有額外的輪胎等級。

如果Tire沒有根節點,代碼可能會變得很苗條。

{"Car": { "Make":"Mustang", 
"YearBuilt":"1999", 
"Tires": "[{ {"Make": "Bridgestone", "Size":"15"}}, 
{"Make": "Brirdgestone", "Size":"15"}}, 
{"Make": "Brirdgestone", "Size":"15"}}, 
{"Make": "Brirdgestone", "Size":"15"}}]}} 

在PHP中,有較少的混亂,因爲有較少的冗餘:第一輪胎的品牌是由$object->Car->Tires[0]->Make

叫有什麼不好的沒有一個根節點?我喜歡擁有根節點,因爲它的行爲類似於類名,但不必要的級別會讓我感到困惑,並且會使遍歷變得更加複雜。

回答

4

我會省略兩個根節點,輪胎汽車

請記住,JSON的主要用途是以緊湊格式通過網絡傳輸對象。除此之外,沒有其他用法。您希望使用JSON編碼的數據並通過添加根節點來創建沒有真實身份和用途的空容器對象。當omiting根節點,你

$car->tires[0]->make 

和JS你會得到

car.tires[0].make 

這是更清晰,表示對象要好得多。請記住,這是你將不得不合作。當然,你可以使用某種類型的JSON映射器來映射對象應該如何被序列化,並導致上述對象,但這是很多額外的努力,不值得它imho。

如果您想在JSON中使用類名稱,請將其作爲屬性,例如,

{ 'klass': 'Car', 'make': 'Mustang', 'year':1999 } 
+0

我同意。根節點只會使消費應用代碼不必要地變得冗長。 – Steve 2010-01-21 16:33:36

+0

很酷,非常感謝。我想到了一個重要的領域。如果JSON鏡像和XML文檔,您至少應該在主對象上添加一個,因爲在XML中,您需要一個根元素。 一位同事也指出,這對於JSONP回調很重要,如果我創建一個API,結果會更好。例如,Yahoo和eBay API將所有內容都包裹在ResultSet節點周圍。這允許關心類型的解析器將ResultSet綁定到對象類型。 – 2010-01-21 16:54:08

+0

那麼,我確信你可以想到UseCases在哪裏可以派上用場,但是再次,當我在我的應用程序中使用JSON時,我有回調知道如何處理他們收到的數據,例如, example.com/cars/find/id/123會返回汽車數據,我的回調會創建它們。 – Gordon 2010-01-21 17:04:57

0

@Gordon說得很好。不過,我喜歡使用帶有AJAX消息的AOP來攔截進出服務器的消息。這些攔截器爲每條消息添加一個時間戳和從服務器發送的狀態標誌(失敗,異常,成功,無論...)的消息。正如您猜測的那樣,我爲有效負載,狀態和時間戳使用了一個根JSON節點。

從服務器發送的狀態標誌可以在前端的一個功能(方面)中檢查,所有異常都在一個地方處理。當服務器由於異常以外的原因而失敗時,aspect/advice允許將數據傳遞給AJAX啓動器。