轉(zhuǎn)自GITHUB 原文地址
版本:0.9
英文版:https://google.github.io/styleguide/jsoncstyleguide.xml
翻譯:Darcy Liu
譯文狀態(tài):草稿
簡(jiǎn)介
該風(fēng)格指南是對(duì)在Google創(chuàng)建JSON APIs而提供的指導(dǎo)性準(zhǔn)則和建議??傮w來講,JSON APIs應(yīng)遵循JSON.org上的規(guī)范。這份風(fēng)格指南澄清和標(biāo)準(zhǔn)化了特定情況,從而使Google的JSON APIs有一種標(biāo)準(zhǔn)的外觀和感覺。這些指南適用于基于RPC和基于REST風(fēng)格的API的JSON請(qǐng)求和響應(yīng)。
定義
為了更好地實(shí)現(xiàn)這份風(fēng)格指南的目的,下面幾項(xiàng)需要說明:
- 屬性(property) - JSON對(duì)象內(nèi)的鍵值對(duì)(name/value pair)
- 屬性名(property name) - 屬性的名稱(或鍵)
- 屬性值(property value) - 分配給屬性的值
示例:
{
// 一組鍵值對(duì)稱作一個(gè) "屬性".
"propertyName": "propertyValue"
}
Javascript的數(shù)字(number)包含所有的浮點(diǎn)數(shù),這是一個(gè)寬泛的指定。在這份指南中,數(shù)字(number)指代Javascript中的數(shù)字(number)類型,而整型(integer)則指代整型。
一般準(zhǔn)則
注釋
JSON對(duì)象中不包含注釋。
JSON對(duì)象中不應(yīng)該包含注釋。該指南中的某些示例含有注釋。但這僅僅是為了說明示例。
{
// 你可能在下面的示例中看到注釋,
// 但不要在你的JSON數(shù)據(jù)中加入注釋.
"propertyName": "propertyValue"
}
雙引號(hào)
使用雙引號(hào)
如果(某個(gè))屬性需要引號(hào),則必須使用雙引號(hào)。所有的屬性名必須在雙引號(hào)內(nèi)。字符類型的屬性值必須使用雙引號(hào)。其它類型值(如布爾或數(shù)字)不應(yīng)該使用雙引號(hào)。
扁平化數(shù)據(jù) VS 結(jié)構(gòu)層次
不能為了方便而將數(shù)據(jù)任意分組
JSON中的數(shù)據(jù)元素應(yīng)以扁平化方式呈現(xiàn)。不能為了方便而將數(shù)據(jù)任意分組。
在某些情況下,比如描述單一結(jié)構(gòu)的一批屬性,因?yàn)樗挥脕肀3纸Y(jié)構(gòu)層次,因而是有意義的。但是遇到這些情況還是應(yīng)當(dāng)慎重考慮,記住只有語(yǔ)義上有意義的時(shí)候才使用它。例如,一個(gè)地址可以有表示兩種方式,但結(jié)構(gòu)化的方式對(duì)開發(fā)人員來講可能更有意義:
扁平化地址:
{
"company": "Google",
"website": "http://www.google.com/",
"addressLine1": "111 8th Ave",
"addressLine2": "4th Floor",
"state": "NY",
"city": "New York",
"zip": "10011"
}
結(jié)構(gòu)化地址:
{
"company": "Google",
"website": "http://www.google.com/",
"address": {
"line1": "111 8th Ave",
"line2": "4th Floor",
"state": "NY",
"city": "New York",
"zip": "10011"
}
}
屬性名準(zhǔn)則
屬性名格式
選擇有意義的屬性名
屬性名必須遵循以下準(zhǔn)則:
- 屬性名應(yīng)該是具有定義語(yǔ)義的有意義的名稱。
- 屬性名必須是駝峰式的,ASCII碼字符串。
- 首字符必須是字母,下劃線(_)或美元符號(hào)($)。
- 隨后的其他字符可以是字母,數(shù)字,下劃線(_)或美元符號(hào)($)。
- 應(yīng)該避免使用Javascript中的保留關(guān)鍵字(下文附有Javascript保留字清單)
這些準(zhǔn)則反映JavaScript標(biāo)識(shí)符命名的指導(dǎo)方針。使JavaScript的客戶端可以使用點(diǎn)符號(hào)來訪問屬性。(例如, result.thisIsAnInstanceVariable).
下面是一個(gè)對(duì)象的一個(gè)屬性的例子:
{
"thisPropertyIsAnIdentifier": "identifier value"
}
JSON Map中的鍵名
在JSON Map中鍵名可以使用任意Unicode字符
當(dāng)JSON對(duì)象作為Map(映射)使用時(shí),屬性的名稱命名規(guī)則并不適用。Map(也稱作關(guān)聯(lián)數(shù)組)是一個(gè)具有任意鍵/值對(duì)的數(shù)據(jù)類型,這些鍵/值對(duì)通過特定的鍵來訪問相應(yīng)的值。JSON對(duì)象和JSON Map在運(yùn)行時(shí)看起來是一樣的;這個(gè)特性與API設(shè)計(jì)相關(guān)。當(dāng)JSON對(duì)象被當(dāng)作map使用時(shí),API文件應(yīng)當(dāng)做出說明。
Map的鍵名不一定要遵循屬性名稱的命名準(zhǔn)則。鍵名可以包含任意的Unicode字符??蛻舳丝墒褂胢aps熟悉的方括號(hào)來訪問這些屬性。(例如result.thumbnails["72"])
{
// "address" 屬性是一個(gè)子對(duì)象
// 包含地址的各部分.
"address": {
"addressLine1": "123 Anystreet",
"city": "Anytown",
"state": "XX",
"zip": "00000"
},
// "address" 是一個(gè)映射
// 含有響應(yīng)規(guī)格所對(duì)應(yīng)的URL,用來映射thumbnail url的像素規(guī)格
"thumbnails": {
"72": "http://url.to.72px.thumbnail",
"144": "http://url.to.144px.thumbnail"
}
}
保留的屬性名稱
某些屬性名稱會(huì)被保留以便能在多個(gè)服務(wù)間相容使用
保留屬性名稱的詳細(xì)信息,連同完整的列表,可在本指南后面的內(nèi)容中找到。服務(wù)應(yīng)按照被定義的語(yǔ)義來使用屬性名稱。
單數(shù)屬性名 VS 復(fù)數(shù)屬性名
數(shù)組類型應(yīng)該是復(fù)數(shù)屬性名。其它屬性名都應(yīng)該是單數(shù)。
數(shù)組通常包含多個(gè)條目,復(fù)數(shù)屬性名就反映了這點(diǎn)。在下面這個(gè)保留名稱中可以看到例子。屬性名items是復(fù)數(shù)因?yàn)樗枋龅氖且唤M對(duì)象。大多數(shù)的其它字段是單數(shù)。
當(dāng)然也有例外,尤其是涉及到數(shù)字的屬性值的時(shí)候。例如,在保留屬性名中,totalItems 比 totalItem更合理。然后,從技術(shù)上講,這并不違反風(fēng)格指南,因?yàn)?totalItems 可以被看作 totalOfItems, 其中 total 是單數(shù)(依照風(fēng)格指南),OfItems 用來限定總數(shù)。字段名也可被改為 itemCount,這樣看起來更象單數(shù).
{
// 單數(shù)
"author": "lisa",
// 一組同胞, 復(fù)數(shù)
"siblings": [ "bart", "maggie"],
// "totalItem" 看起來并不對(duì)
"totalItems": 10,
// 但 "itemCount" 要好些
"itemCount": 10
}
命名沖突
通過選擇新的屬性名或?qū)PI版本化來避免命名沖突
新的屬性可在將來被添加進(jìn)保留列表中。JSON中不存在命名空間。如果存在命名沖突,可通過選擇新的屬性名或者版本化來解決這個(gè)問題。例如,假設(shè)我們由下面的JSON對(duì)象開始:
{
"apiVersion": "1.0",
"data": {
"recipeName": "pizza",
"ingredients": ["tomatoes", "cheese", "sausage"]
}
}
如果我們希望將來把ingredients列為保留字,我們可以通過下面兩件事情來達(dá)成:
1.選一個(gè)不同的名字
{
"apiVersion": "1.0",
"data": {
"recipeName": "pizza",
"ingredientsData": "Some new property",
"ingredients": ["tomatoes", "cheese", "sausage"]
}
}
2.在主版本上重新命名屬性
{
"apiVersion": "2.0",
"data": {
"recipeName": "pizza",
"ingredients": "Some new property",
"recipeIngredients": ["tomatos", "cheese", "sausage"]
}
}
屬性值準(zhǔn)則
屬性值格式
屬性值必須是Unicode 的 booleans(布爾), 數(shù)字(numbers), 字符串(strings), 對(duì)象(objects), 數(shù)組(arrays), 或 null.
JSON.org上的標(biāo)準(zhǔn)準(zhǔn)確地說明了哪些類型的數(shù)據(jù)可以作為屬性值。這包含Unicode的布爾(booleans), 數(shù)字(numbers), 字符串(strings), 對(duì)象(objects), 數(shù)組(arrays), 或 null。JavaScript表達(dá)式是不被接受的。APIs應(yīng)該支持該準(zhǔn)則,并為某個(gè)特定的屬性選擇最合適的數(shù)據(jù)類型(比如,用numbers代表numbers等)。
好的例子:
{
"canPigsFly": null, // null
"areWeThereYet": false, // boolean
"answerToLife": 42, // number
"name": "Bart", // string
"moreData": {}, // object
"things": [] // array
}
不好的例子:
{
"aVariableName": aVariableName, // Bad - JavaScript 標(biāo)識(shí)符
"functionFoo": function() { return 1; } // Bad - JavaScript 函數(shù)
}
空或Null 屬性值
考慮移除空或null值
如果一個(gè)屬性是可選的或者包含空值或null值,考慮從JSON中去掉該屬性,除非它的存在有很強(qiáng)的語(yǔ)義原因。
{
"volume": 10,
// 即使 "balance" 屬性值是零, 它也應(yīng)當(dāng)被保留,
// 因?yàn)?"0" 表示 "均衡"
// "-1" 表示左傾斜和"+1" 表示右傾斜
"balance": 0,
// "currentlyPlaying" 是null的時(shí)候可被移除
// "currentlyPlaying": null
}
枚舉值
枚舉值應(yīng)當(dāng)以字符串的形式呈現(xiàn)
隨著APIs的發(fā)展,枚舉值可能被添加,移除或者改變。將枚舉值當(dāng)作字符串可以使下游用戶幽雅地處理枚舉值的變更。
Java代碼:
public enum Color {
WHITE,
BLACK,
RED,
YELLOW,
BLUE
}
JSON對(duì)象:
{
"color": "WHITE"
}
屬性值數(shù)據(jù)類型
上面提到,屬性值必須是布爾(booleans), 數(shù)字(numbers), 字符串(strings), 對(duì)象(objects), 數(shù)組(arrays), 或 null. 然而在處理某些值時(shí),定義一組標(biāo)準(zhǔn)的數(shù)據(jù)類型是非常有用的。這些數(shù)據(jù)類型必須始終是字符串,但是為了便于解析,它們也會(huì)以特定的方式被格式化。
日期屬性值
日期應(yīng)該使用RFC3339建議的格式
日期應(yīng)該是RFC 3339所建議的字符串格式。
{
"lastUpdate": "2007-11-06T16:34:41.000Z"
}
時(shí)間間隔屬性值
時(shí)間間隔應(yīng)該使用ISO 8601建議的格式
時(shí)間間隔應(yīng)該是ISO 8601所建議的字符串格式。
{
// 三年, 6個(gè)月, 4天, 12小時(shí),
// 三十分鐘, 5秒
"duration": "P3Y6M4DT12H30M5S"
}
緯度/經(jīng)度屬性值
緯度/經(jīng)度應(yīng)該使用ISO 6709建議的格式
緯度/經(jīng)度應(yīng)該是ISO 6709所建議的字符串格式。
而且, 它應(yīng)該更偏好使用 e ?±DD.DDDD?±DDD.DDDD 角度格式.
{
// 自由女神像的緯度/經(jīng)度位置.
"statueOfLiberty": "+40.6894-074.0447"
}
JSON結(jié)構(gòu)和保留屬性名
為了使APIs保持一致的接口,JSON對(duì)象應(yīng)當(dāng)使用以下的結(jié)構(gòu)。該結(jié)構(gòu)適用于JSON的請(qǐng)求和響應(yīng)。在這個(gè)結(jié)構(gòu)中,某些屬性名將被保留用作特殊用途。這些屬性并不是必需的,也就是說,每個(gè)保留的屬性可能出現(xiàn)零次或一次。但是如果服務(wù)需要這些屬性,建議遵循該命名條約。下面是一份JSON結(jié)構(gòu)語(yǔ)義表,以O(shè)rderly格式呈現(xiàn)(現(xiàn)在已經(jīng)被納入 JSONSchema)。你可以在該指南的最后找到關(guān)于JSON結(jié)構(gòu)的例子。
object {
string apiVersion?;
string context?;
string id?;
string method?;
object {
string id?
}* params?;
object {
string kind?;
string fields?;
string etag?;
string id?;
string lang?;
string updated?; # date formatted RFC 3339
boolean deleted?;
integer currentItemCount?;
integer itemsPerPage?;
integer startIndex?;
integer totalItems?;
integer pageIndex?;
integer totalPages?;
string pageLinkTemplate /^https?:/ ?;
object {}* next?;
string nextLink?;
object {}* previous?;
string previousLink?;
object {}* self?;
string selfLink?;
object {}* edit?;
string editLink?;
array [
object {}*;
] items?;
}* data?;
object {
integer code?;
string message?;
array [
object {
string domain?;
string reason?;
string message?;
string location?;
string locationType?;
string extendedHelp?;
string sendReport?;
}*;
] errors?;
}* error?;
}*;
JSON對(duì)象有一些頂級(jí)屬性,然后是data對(duì)象或error對(duì)象,這兩者不會(huì)同時(shí)出現(xiàn)。下面是這些屬性的解釋。
頂級(jí)保留屬性名稱
頂級(jí)的JSON對(duì)象可能包含下面這些屬性
apiVersion
屬性值類型: 字符串(string)
父節(jié)點(diǎn): -
呈現(xiàn)請(qǐng)求中服務(wù)API期望的版本,以及在響應(yīng)中保存的服務(wù)API版本。應(yīng)隨時(shí)提供apiVersion。這與數(shù)據(jù)的版本無關(guān)。將數(shù)據(jù)版本化應(yīng)該通過其他的機(jī)制來處理,如etag。
示例:
{ "apiVersion": "2.1" }
context
屬性值類型: 字符串(string)
父節(jié)點(diǎn): -
客戶端設(shè)置這個(gè)值,服務(wù)器通過數(shù)據(jù)作出回應(yīng)。這在JSON-P和批處理中很有用,用戶可以使用context將響應(yīng)與請(qǐng)求關(guān)聯(lián)起來。該屬性是頂級(jí)屬性,因?yàn)椴还茼憫?yīng)是成功還是有錯(cuò)誤,context總應(yīng)當(dāng)被呈現(xiàn)出來。context不同于id在于context由用戶提供而id由服務(wù)分配。
示例:
請(qǐng)求 #1:
http://www.google.com/myapi?context=bart
請(qǐng)求 #2:
http://www.google.com/myapi?context=lisa
響應(yīng) #1:
{
"context": "bart",
"data": {
"items": []
}
}
響應(yīng) #2:
{
"context": "lisa",
"data": {
"items": []
}
}
公共的JavaScript處理器通過編碼同時(shí)處理以下兩個(gè)響應(yīng):
function handleResponse(response) {
if (response.result.context == "bart") {
// 更新頁(yè)面中的 "Bart" 部分。
} else if (response.result.context == "lisa") {
// 更新頁(yè)面中的 "Lisa" 部分。
}
}
id
屬性值類型: 字符串(string)
父節(jié)點(diǎn): -
服務(wù)提供用于識(shí)別響應(yīng)的標(biāo)識(shí)(無論請(qǐng)求是成功還是有錯(cuò)誤)。這對(duì)于將服務(wù)日志和單獨(dú)收到的響應(yīng)對(duì)應(yīng)起來很有用。
示例:
{ "id": "1" }
method
屬性值類型: 字符串(string)
父節(jié)點(diǎn): -
表示對(duì)數(shù)據(jù)即將執(zhí)行,或已被執(zhí)行的操作。在JSON請(qǐng)求的情況下,method屬性可以用來指明對(duì)數(shù)據(jù)進(jìn)行何種操作。在JSON響應(yīng)的情況下,method屬性表明對(duì)數(shù)據(jù)進(jìn)行了何種操作。
一個(gè)JSON-RPC請(qǐng)求的例子,其中method屬性表示要在params上執(zhí)行的操作:
{
"method": "people.get",
"params": {
"userId": "@me",
"groupId": "@self"
}
}
params
屬性值類型: 對(duì)象(object)
父節(jié)點(diǎn): -
這個(gè)對(duì)象作為輸入?yún)?shù)的映射發(fā)送給RPC請(qǐng)求。它可以和method屬性一起用來執(zhí)行RPC功能。若RPC方法不需要參數(shù),則可以省略該屬性。
示例:
{
"method": "people.get",
"params": {
"userId": "@me",
"groupId": "@self"
}
}
data
屬性值類型: 對(duì)象(object)
父節(jié)點(diǎn): -
包含響應(yīng)的所有數(shù)據(jù)。該屬性本身?yè)碛性S多保留屬性名,下面會(huì)有相應(yīng)的說明。服務(wù)可以自由地將自己的數(shù)據(jù)添加到這個(gè)對(duì)象。一個(gè)JSON響應(yīng)要么應(yīng)當(dāng)包含一個(gè)data對(duì)象,要么應(yīng)當(dāng)包含error對(duì)象,但不能兩者都包含。如果data和error同時(shí)出現(xiàn),則error對(duì)象優(yōu)先。
error
屬性值類型: 對(duì)象(object)
父節(jié)點(diǎn): -
表明錯(cuò)誤發(fā)生,提供錯(cuò)誤的詳細(xì)信息。錯(cuò)誤的格式支持從服務(wù)返回一個(gè)或多個(gè)錯(cuò)誤。一個(gè)JSON響應(yīng)可以有一個(gè)data對(duì)象或者一個(gè)error對(duì)象,但不能兩者都包含。如果data和error都出現(xiàn),error對(duì)象優(yōu)先。
示例:
{
"apiVersion": "2.0",
"error": {
"code": 404,
"message": "File Not Found",
"errors": [{
"domain": "Calendar",
"reason": "ResourceNotFoundException",
"message": "File Not Found
}]
}
}
data對(duì)象的保留屬性名
JSON對(duì)象的data屬性可能包含以下屬性。
data.kind
屬性值類型: 字符串(sting)
父節(jié)點(diǎn): data
kind屬性是對(duì)某個(gè)特定的對(duì)象存儲(chǔ)何種類型的信息的指南??梢园阉旁?em>data層次,或items的層次,或其它任何有助于區(qū)分各類對(duì)象的對(duì)象中。如果kind對(duì)象被提供,它應(yīng)該是對(duì)象的第一個(gè)屬性(詳見下面的屬性順序部分)。
示例:
// "Kind" indicates an "album" in the Picasa API.
{"data": {"kind": "album"}}
data.fields
屬性值類型: 字符串(string)
父節(jié)點(diǎn): data
表示做了部分GET之后響應(yīng)中出現(xiàn)的字段,或做了部分PATCH之后出現(xiàn)在請(qǐng)求中的字段。該屬性僅在做了部分GET請(qǐng)求/批處理時(shí)存在,且不能為空。
示例:
{
"data": {
"kind": "user",
"fields": "author,id",
"id": "bart",
"author": "Bart"
}
}
data.etag
屬性值類型: 字符串(string)
父節(jié)點(diǎn): data
響應(yīng)時(shí)提供etag。關(guān)于GData APIs中的ETags詳情可以在這里找到:http://code.google.com/apis/gdata/docs/2.0/reference.html#ResourceVersioning
示例:
{"data": {"etag": "W/"C0QBRXcycSp7ImA9WxRVFUk.""}}
data.id
屬性值類型: 字符串(string)
父節(jié)點(diǎn): data
一個(gè)全局唯一標(biāo)識(shí)符用于引用該對(duì)象。id屬性的具體細(xì)節(jié)都留給了服務(wù)。
示例:
{"data": {"id": "12345"}}
data.lang
屬性值類型: 字符串(string)(格式由BCP 47指定)
父節(jié)點(diǎn): data (或任何子元素)
表示該對(duì)象內(nèi)其他屬性的語(yǔ)言。該屬性模擬HTML的lang屬性和XML的xml:lang屬性。值應(yīng)該是BCP 47中定義的一種語(yǔ)言值。如果一個(gè)單一的JSON對(duì)象包含的數(shù)據(jù)有多種語(yǔ)言,服務(wù)負(fù)責(zé)制定和標(biāo)明lang屬性的適當(dāng)位置。
示例:
{"data": {
"items": [
{ "lang": "en",
"title": "Hello world!" },
{ "lang": "fr",
"title": "Bonjour monde!" }
]}
}
data.updated
屬性值類型: 字符串(string)(格式由RFC 3339指定)
父節(jié)點(diǎn): data
指明條目更新的最后日期/時(shí)間(RFC 3339),由服務(wù)規(guī)定。
示例:
{"data": {"updated": "2007-11-06T16:34:41.000Z"}}
data.deleted
屬性值類型: 布爾(boolean)
父節(jié)點(diǎn): data (或任何子元素)
一個(gè)標(biāo)記元素,當(dāng)出現(xiàn)時(shí),表示包含的條目已被刪除。如果提供了刪除屬性,它的值必須為true;為false會(huì)導(dǎo)致混亂,應(yīng)該避免。
示例:
{"data": {
"items": [
{ "title": "A deleted entry",
"deleted": true
}
]}
}
data.items
屬性值類型: 數(shù)組(array)
父節(jié)點(diǎn): data
屬性名items被保留用作表示一組條目(例如,Picasa中的圖片,YouTube中的視頻)。這種結(jié)構(gòu)的目的是給與當(dāng)前結(jié)果相關(guān)的集合提供一個(gè)標(biāo)準(zhǔn)位置。例如,知道頁(yè)面上的items是數(shù)組,JSON輸出便可能插入一個(gè)通用的分頁(yè)系統(tǒng)。如果items存在,它應(yīng)該是data對(duì)象的最后一個(gè)屬性。(詳見下面的屬性順序部分)。
示例:
{
"data": {
"items": [
{ /* Object #1 */ },
{ /* Object #2 */ },
...
]
}
}
用于分頁(yè)的保留屬性名
下面的屬性位于data對(duì)象中,用來給一列數(shù)據(jù)分頁(yè)。一些語(yǔ)言和概念是從OpenSearch規(guī)范中借鑒過來的。
下面的分頁(yè)數(shù)據(jù)允許各種風(fēng)格的分頁(yè),包括:
- 上一頁(yè)/下一頁(yè) - 允許用戶在列表中前進(jìn)和后退,一次一頁(yè)。nextLink 和previousLink屬性 (下面的"鏈接保留屬性名"部分有描述) 用于這種風(fēng)格的分頁(yè)。
- 基于索引的分頁(yè) - 允許用戶直接跳到條目列表的某個(gè)條目位置。例如,要從第200個(gè)條目開始載入10個(gè)新的條目,開發(fā)者可以給用戶提供一個(gè)URL的查詢字符串?startIndex=200。
- 基于頁(yè)面的分頁(yè) - 允許用戶直接跳到條目?jī)?nèi)的具體頁(yè)。這跟基于索引的分頁(yè)很類似,但節(jié)省了開發(fā)者額外的步驟,不需再為新一頁(yè)的條目計(jì)算條目索引。例如,開發(fā)人員可以直接跳到第20頁(yè),而不是跳到第200條條目?;陧?yè)面分頁(yè)的網(wǎng)址,可以使用查詢字符串?page=1或?page=20。pageIndex和 totalPages 屬性用作這種風(fēng)格的分頁(yè).
在這份指南的最后可以找到如何使用這些屬性來實(shí)現(xiàn)分頁(yè)的例子。
data.currentItemCount
屬性值類型: 整數(shù)(integer)
父節(jié)點(diǎn): data
結(jié)果集中的條目數(shù)目。應(yīng)該與items.length相等,并作為一個(gè)便利屬性提供。例如,假設(shè)開發(fā)者請(qǐng)求一組搜索條目,并且要求每頁(yè)10條。查詢集共有14條。第一個(gè)條目頁(yè)將會(huì)有10個(gè)條目,因此itemsPerPage和currentItemCount都應(yīng)該等于10。下一頁(yè)的條目還剩下4條;itemsPerPage仍然是10,但是currentItemCount是4.
示例:
{
"data": {
// "itemsPerPage" 不需要與 "currentItemCount" 匹配
"itemsPerPage": 10,
"currentItemCount": 4
}
}
data.itemsPerPage
屬性值類型: 整數(shù)(integer)
父節(jié)點(diǎn): data
items結(jié)果的數(shù)目。未必是data.items數(shù)組的大小;如果我們查看的是最后一頁(yè),data.items的大小可能小于itemsPerPage。但是,data.items的大小不應(yīng)超過itemsPerPage。
示例:
{
"data": {
"itemsPerPage": 10
}
}
data.startIndex
屬性值類型: 整數(shù)(integer)
父節(jié)點(diǎn): data
data.items中第一個(gè)條目的索引。為了一致,startIndex應(yīng)從1開始。例如,第一組items中第一條的startIndex應(yīng)該是1。如果用戶請(qǐng)求下一組數(shù)據(jù),startIndex可能是10。
示例:
{
"data": {
"startIndex": 1
}
}
data.totalItems
屬性值類型: 整數(shù)(integer)
父節(jié)點(diǎn): data
當(dāng)前集合中可用的總條目數(shù)。例如,如果用戶有100篇博客文章,響應(yīng)可能只包含10篇,但是totalItems應(yīng)該是100。
示例:
{
"data": {
"totalItems": 100
}
}
data.pagingLinkTemplate
屬性值類型: 字符串(string)
父節(jié)點(diǎn): data
URL模板指出用戶可以如何計(jì)算隨后的分頁(yè)鏈接。URL模板中也包含一些保留變量名:表示要載入的條目的{index},和要載入的頁(yè)面的{pageIndex}。
示例:
{
"data": {
"pagingLinkTemplate": "http://www.google.com/search/hl=en&q=chicago+style+pizza&start={index}&sa=N"
}
}
data.pageIndex
屬性值類型: 整數(shù)(integer)
父節(jié)點(diǎn): data
條目的當(dāng)前頁(yè)索引。為了一致,pageIndex應(yīng)從1開始。例如,第一頁(yè)的pageIndex是1。pageIndex也可以通過基于條目的分頁(yè)而計(jì)算出來pageIndex = floor(startIndex / itemsPerPage) + 1。
示例:
{
"data": {
"pageIndex": 1
}
}
data.totalPages
屬性值類型: 整數(shù)(integer)
父節(jié)點(diǎn): data
當(dāng)前結(jié)果集中的總頁(yè)數(shù)。totalPages也可以通過上面基于條目的分頁(yè)屬性計(jì)算出來: totalPages = ceiling(totalItems / itemsPerPage).。
示例:
{
"data": {
"totalPages": 50
}
}
用于鏈接的保留屬性名
下面的屬性位于data對(duì)象中,用來表示對(duì)其他資源的引用。有兩種形式的鏈接屬性:1)對(duì)象,它可以包含任何種類的引用(比如JSON-RPC對(duì)象),2)URL字符串,表示資源的URIs(后綴總為'Link')。
data.self / data.selfLink
屬性值類型: 對(duì)象(object)/字符串(string)
父節(jié)點(diǎn): data
自身鏈接可以用于取回條目數(shù)據(jù)。比如,在用戶的Picasa相冊(cè)中,條目中的每個(gè)相冊(cè)對(duì)象都會(huì)包含一個(gè)selfLink用于檢索這個(gè)相冊(cè)的相關(guān)數(shù)據(jù)。
示例:
{
"data": {
"self": { },
"selfLink": "http://www.google.com/feeds/album/1234"
}
}
data.edit / data.editLink
屬性值類型: 對(duì)象(object)/字符串(string)
父節(jié)點(diǎn): data
編輯鏈接表明用戶可以發(fā)送更新或刪除請(qǐng)求。這對(duì)于REST風(fēng)格的APIs很有用。該鏈接僅在用戶能夠更新和刪除該條目時(shí)提供。
示例:
{
"data": {
"edit": { },
"editLink": "http://www.google.com/feeds/album/1234/edit"
}
}
data.next / data.nextLink
屬性值類型: 對(duì)象(object)/字符串(string)
父節(jié)點(diǎn): data
該下一頁(yè)鏈接標(biāo)明如何取得更多數(shù)據(jù)。它指明載入下一組數(shù)據(jù)的位置。它可以同itemsPerPage,startIndex 和 totalItems 屬性一起使用用于分頁(yè)數(shù)據(jù)。
示例:
{
"data": {
"next": { },
"nextLink": "http://www.google.com/feeds/album/1234/next"
}
}
data.previous / data.previousLink
屬性值類型: 對(duì)象(object)/字符串(string)
父節(jié)點(diǎn): data
該上一頁(yè)鏈接標(biāo)明如何取得更多數(shù)據(jù)。它指明載入上一組數(shù)據(jù)的位置。它可以連同itemsPerPage,startIndex 和 totalItems 屬性用于分頁(yè)數(shù)據(jù)。
示例:
{
"data": {
"previous": { },
"previousLink": "http://www.google.com/feeds/album/1234/next"
}
}
錯(cuò)誤對(duì)象中的保留屬性名##
JSON對(duì)象的error屬性應(yīng)包含以下屬性。
error.code
屬性值類型: 整數(shù)(integer)
父節(jié)點(diǎn): error
表示該錯(cuò)誤的編號(hào)。這個(gè)屬性通常表示HTTP響應(yīng)碼。如果存在多個(gè)錯(cuò)誤,code應(yīng)為第一個(gè)出錯(cuò)的錯(cuò)誤碼。
示例:
{
"error":{
"code": 404
}
}
error.message
屬性值類型: 字符串(string)
父節(jié)點(diǎn): error
一個(gè)人類可讀的信息,提供有關(guān)錯(cuò)誤的詳細(xì)信息。如果存在多個(gè)錯(cuò)誤,message應(yīng)為第一個(gè)錯(cuò)誤的錯(cuò)誤信息。
示例:
{
"error":{
"message": "File Not Found"
}
}
error.errors
屬性值類型: 數(shù)組(array)
父節(jié)點(diǎn): error
包含關(guān)于錯(cuò)誤的附加信息。如果服務(wù)返回多個(gè)錯(cuò)誤。errors數(shù)組中的每個(gè)元素表示一個(gè)不同的錯(cuò)誤。
示例:
{ "error": { "errors": [] } }
error.errors[].domain
屬性值類型: 字符串(string)
父節(jié)點(diǎn): error.errors
服務(wù)拋出該錯(cuò)誤的唯一識(shí)別符。它幫助區(qū)分服務(wù)的從普通協(xié)議錯(cuò)誤(如,找不到文件)中區(qū)分出具體錯(cuò)誤(例如,給日歷插入事件的錯(cuò)誤)。
示例:
{
"error":{
"errors": [{"domain": "Calendar"}]
}
}
error.errors[].reason
屬性值類型: 字符串(string)
父節(jié)點(diǎn): error.errors
該錯(cuò)誤的唯一識(shí)別符。不同于error.code屬性,它不是HTTP響應(yīng)碼。
示例:
{
"error":{
"errors": [{"reason": "ResourceNotFoundException"}]
}
}
error.errors[].message
屬性值類型: 字符串(string)
父節(jié)點(diǎn): error.errors
一個(gè)人類可讀的信息,提供有關(guān)錯(cuò)誤的更多細(xì)節(jié)。如果只有一個(gè)錯(cuò)誤,該字段應(yīng)該與error.message匹配。
示例:
{
"error":{
"code": 404
"message": "File Not Found",
"errors": [{"message": "File Not Found"}]
}
}
error.errors[].location
屬性值類型: 字符串(string)
父節(jié)點(diǎn): error.errors
錯(cuò)誤發(fā)生的位置(根據(jù)locationType字段解釋該值)。
示例:
{
"error":{
"errors": [{"location": ""}]
}
}
error.errors[].locationType
屬性值類型: 字符串(string)
父節(jié)點(diǎn): error.errors
標(biāo)明如何解釋location屬性。
示例:
{
"error":{
"errors": [{"locationType": ""}]
}
}
error.errors[].extendedHelp
屬性值類型: 字符串(string)
父節(jié)點(diǎn): error.errors
help text的URI,使錯(cuò)誤更易于理解。
示例:(注:原示例這里有筆誤,中文版這里做了校正)
{
"error":{
"errors": [{"extendedHelp": "http://url.to.more.details.example.com/"}]
}
}
error.errors[].sendReport
屬性值類型: 字符串(string)
父節(jié)點(diǎn): error.errors
report form的URI,服務(wù)用它來收集錯(cuò)誤狀態(tài)的數(shù)據(jù)。該URL會(huì)預(yù)先載入描述請(qǐng)求的參數(shù)
示例:
{
"error":{
"errors": [{"sendReport": "http://report.example.com/"}]
}
}
屬性順序
在JSON對(duì)象中屬性可有任意順序。然而,在某些情況下,有序的屬性可以幫助分析器快速解釋數(shù)據(jù),并帶來更好的性能。在移動(dòng)環(huán)境下的解析器就是個(gè)例子,在這種情況下,性能和內(nèi)存是至關(guān)重要的,不必要的解析也應(yīng)盡量避免。
Kind屬性
Kind屬性應(yīng)為第一屬性
假設(shè)一個(gè)解析器負(fù)責(zé)將一個(gè)原始JSON流解析成一個(gè)特定的對(duì)象。kind屬性會(huì)引導(dǎo)解析器將適合的對(duì)象實(shí)例化。因而它應(yīng)該是JSON對(duì)象的第一個(gè)屬性。這僅適用于對(duì)象有一個(gè)kind屬性的情況(通??梢栽?em>data和items屬性中找到)。
Items屬性
items應(yīng)該是data對(duì)象的最后一個(gè)屬性
這使得閱讀每一個(gè)具體條目前前已讀所有的集合屬性。在有很多條目的情況下,這樣就避免了開發(fā)人員只需要從數(shù)據(jù)的字段時(shí)不必要的解析這些條目。
這讓閱讀所有集合屬性先于閱讀單個(gè)條目。如遇多個(gè)條目的情況,當(dāng)開發(fā)者僅需要數(shù)據(jù)中的字段時(shí),這就可避免解析不必要的條目。
屬性順序示例:
// "kind" 屬性區(qū)分 "album" 和 "photo".
// "Kind" 始終是它父對(duì)象的第一個(gè)屬性.
// "items" 屬性是 "data" 對(duì)象的最后一個(gè)屬性.
{
"data": {
"kind": "album",
"title": "My Photo Album",
"description": "An album in the user's account",
"items": [
{
"kind": "photo",
"title": "My First Photo"
}
]
}
}
示例
YouTube JSON API
這是YouTube JSON API響應(yīng)對(duì)象的示例。你可以從中學(xué)到更多關(guān)于YouTube JSON API的內(nèi)容:http://code.google.com/apis/youtube/2.0/developers_guide_jsonc.html
{
"apiVersion": "2.0",
"data": {
"updated": "2010-02-04T19:29:54.001Z",
"totalItems": 6741,
"startIndex": 1,
"itemsPerPage": 1,
"items": [
{
"id": "BGODurRfVv4",
"uploaded": "2009-11-17T20:10:06.000Z",
"updated": "2010-02-04T06:25:57.000Z",
"uploader": "docchat",
"category": "Animals",
"title": "From service dog to SURFice dog",
"description": "Surf dog Ricochets inspirational video ...",
"tags": [
"Surf dog",
"dog surfing",
"dog",
"golden retriever",
],
"thumbnail": {
"default": "http://i.ytimg.com/vi/BGODurRfVv4/default.jpg",
"hqDefault": "http://i.ytimg.com/vi/BGODurRfVv4/hqdefault.jpg"
},
"player": {
"default": "http://www.youtube.com/watch?v=BGODurRfVv4&feature=youtube_gdata",
"mobile": "http://m.youtube.com/details?v=BGODurRfVv4"
},
"content": {
"1": "rtsp://v5.cache6.c.youtube.com/CiILENy73wIaGQn-Vl-0uoNjBBMYDSANFEgGUgZ2aWRlb3MM/0/0/0/video.3gp",
"5": "http://www.youtube.com/v/BGODurRfVv4?f=videos&app=youtube_gdata",
"6": "rtsp://v7.cache7.c.youtube.com/CiILENy73wIaGQn-Vl-0uoNjBBMYESARFEgGUgZ2aWRlb3MM/0/0/0/video.3gp"
},
"duration": 315,
"rating": 4.96,
"ratingCount": 2043,
"viewCount": 1781691,
"favoriteCount": 3363,
"commentCount": 1007,
"commentsAllowed": true
}
]
}
}
分頁(yè)示例
如何將Google搜索條目作為JSON對(duì)象展現(xiàn)出來,對(duì)分頁(yè)變量也有特別關(guān)注。
這個(gè)示例僅用作說明。下面的API實(shí)際上并不存在。
這是Google搜索結(jié)果頁(yè)面的示例:


這是該頁(yè)面JSON形式的呈現(xiàn):
{
"apiVersion": "2.1",
"id": "1",
"data": {
"query": "chicago style pizza",
"time": "0.1",
"currentItemCount": 10,
"itemsPerPage": 10,
"startIndex": 11,
"totalItems": 2700000,
"nextLink": "http://www.google.com/search?hl=en&q=chicago+style+pizza&start=20&sa=N"
"previousLink": "http://www.google.com/search?hl=en&q=chicago+style+pizza&start=0&sa=N",
"pagingLinkTemplate": "http://www.google.com/search/hl=en&q=chicago+style+pizza&start={index}&sa=N",
"items": [
{
"title": "Pizz'a Chicago Home Page"
// More fields for the search results
}
// More search results
]
}
}
這是如何展現(xiàn)屏幕截圖中的色塊的例子(背景顏色對(duì)應(yīng)下圖中的顏色)
- Results <span style="background-color:rgb(180, 167, 214)">11</span> - 20 of about 2,700,000 = startIndex
- Results 11 - <span style="background-color:rgb(255, 217, 102)">20</span> of about 2,700,000 = startIndex + currentItemCount - 1
- Results 11 - 20 of about <span style="background-color:rgb(246, 178, 107)">2,700,000</span> = totalItems
- <span style="background-color:rgb(234, 153, 153)">Search results</span> = items (formatted appropriately)
- <span style="background-color:rgb(182, 215, 168)">Previous/Next</span> = previousLink / nextLink
- <span style="background-color:rgb(159, 197, 232)">Numbered links in "Gooooooooooogle"</span> = Derived from "pageLinkTemplate". The developer is responsible for calculating the values for {index} and substituting those values into the "pageLinkTemplate". The pageLinkTemplate's {index} variable is calculated as follows:
- Index #1 = 0 * itemsPerPage = 0
- Index #2 = 2 * itemsPerPage = 10
- Index #3 = 3 * itemsPerPage = 20
- Index #N = N * itemsPerPage
附錄
附錄A:JavaScript中的保留字
下列JavaScript保留字應(yīng)該避免在屬性名中使用
下面的清單是JavaScript中的保留字,并不能通過點(diǎn)訪問符訪問。這份清單集合了當(dāng)前最新的關(guān)鍵字,該清單可能會(huì)根據(jù)具體的執(zhí)行環(huán)境而有所變更。
abstract
boolean break byte
case catch char class const continue
debugger default delete do double
else enum export extends
false final finally float for function
goto
if implements import in instanceof int interface
let long
native new null
package private protected public
return
short static super switch synchronized
this throw throws transient true try typeof
var volatile void
while with
yield
除了特別說明,該頁(yè)面的內(nèi)容均由共同創(chuàng)作協(xié)議(CC BY 3.0)授權(quán)許可,示例代碼均由Apache 2.0許可證授權(quán)許可)
-EOF-