前言 - 碁峰資訊epaper.gotop.com.tw/pdfsample/a497.pdf · 程式範例包括 javascript...

26
前言 JavaScript Object NotationJSON)正成為 RESTful 界面的實際標準,生態系中有有標 準、工具與技術可供架構設計師與開發者建構應用程式。JSON 不只是 AJAX 呼叫時替 XML 的簡單格式,它正成為網際網路資料交換的主力。JSON 的標準與最佳做法可 用於建構優雅、實用與高效能的應用程式。 現在唯一欠缺的是整合所有東西的手冊。本書的目標是幫助開發者運用 JSON 建構企業 級應用程式與服務。我的目標是宣傳使用 JSON 工具與訊息 / 文件設計概念作為 API 發的一環。 我在 2007 年領導一個大型入口網站專案時開始接觸 JSON,當時必須產生具有數千個項 目的下拉選單,而我因閱讀了 Rebecca Riordan 所著的 Head First AJAXO’Reilly),所 以有很好的架構設計。AJAX 可以解決延遲與載入網頁的問題,但資料呢?我已經使用 XML 好幾年,但它對目前遇到的問題有點殺雞用牛刀─在 View 與後台之間傳遞資料。 Head First AJAX 提到稱為 JSON 的新資料格式,看起來不錯。我的團隊開始尋找將 Java 物件轉換成 JSON 且最簡單進行 JUnit 程式的 API─目標是最簡單且可行的東西。我們 進行了嚴格的負載測試,而 Java JSON 的轉換沒有效能問題。上線後的應用程式可放 大規模且使用者看到下拉選單即時的反應。 我開始考慮在網頁應用程式、RESTful API 與訊息中使用 JSON2009 年我還在使用 XML,因為 XML Schema 提供資料交換必要的結構檢驗。所以當時我在網頁使用者界 面使用 JSON(求速度),而服務與訊息則使用 XML(求整合)。然後我在 2010 年發現 有了 JSON Schema 就不再需要 XMLJSON Schema 規格還在開發中,但已經能夠用在 企業級的整合。

Upload: others

Post on 25-May-2020

12 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

前言

JavaScript Object Notation(JSON)正成為 RESTful界面的實際標準,生態系中有有標準、工具與技術可供架構設計師與開發者建構應用程式。JSON不只是 AJAX呼叫時替代 XML的簡單格式,它正成為網際網路資料交換的主力。JSON的標準與最佳做法可用於建構優雅、實用與高效能的應用程式。

現在唯一欠缺的是整合所有東西的手冊。本書的目標是幫助開發者運用 JSON建構企業級應用程式與服務。我的目標是宣傳使用 JSON工具與訊息 /文件設計概念作為 API開發的一環。

我在 2007年領導一個大型入口網站專案時開始接觸 JSON,當時必須產生具有數千個項目的下拉選單,而我因閱讀了 Rebecca Riordan所著的 Head First AJAX(O’Reilly),所以有很好的架構設計。AJAX可以解決延遲與載入網頁的問題,但資料呢?我已經使用XML好幾年,但它對目前遇到的問題有點殺雞用牛刀─在 View與後台之間傳遞資料。Head First AJAX提到稱為 JSON的新資料格式,看起來不錯。我的團隊開始尋找將 Java物件轉換成 JSON且最簡單進行 JUnit程式的 API─目標是最簡單且可行的東西。我們進行了嚴格的負載測試,而 Java與 JSON的轉換沒有效能問題。上線後的應用程式可放大規模且使用者看到下拉選單即時的反應。

我開始考慮在網頁應用程式、RESTful API與訊息中使用 JSON。2009年我還在使用XML,因為 XML Schema提供資料交換必要的結構檢驗。所以當時我在網頁使用者界面使用 JSON(求速度),而服務與訊息則使用 XML(求整合)。然後我在 2010年發現有了 JSON Schema就不再需要 XML。JSON Schema規格還在開發中,但已經能夠用在企業級的整合。

Page 2: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

vi | 前言

此時我開始黏上,或更精確的說是愛上 JSON。我開始搜尋網路看看 JSON還能做什麼,我發現有大量的 API、線上工具、搜尋功能等。總而言之,XML能做的事情現在JSON都能做。

然後我開始檢查 JSON的書,很失望的發現只有在 JavaScript或 RESTful網路服務的書中有提到一點。我看到 JSON社群出現了許多工具與部落格文章,但除了 Douglas Crockford的 JSON網站(www.json.org)外沒有集中的地方。

本書適合的讀者

這本書是供設計 /實作網站與行動應用程式、RESTful API,以及訊息應用程式的建構設計師和開發者閱讀。程式範例包括 JavaScript、Node.js、Ruby on Rails與 Java。Groovy、Go、Scala、Perl、Python、Clojure 或 C# 開發者也可參考程式範例。大部分的主流 /新語言都有支援 JSON。對架構設計師,我提供指南、最佳做法與架構設計圖示。真正好的架構設計師除了提出願景外,還會以可用的程式碼提供想法。雖然我喜

歡用 JSON寫程式,但沒有實務背景下的使用案例就沒有意義。對開發者來說,這本書提供程式範例、工具與單元測試,它們都放在 GitHub程式庫中(見“範例程式碼” 一節)。

第五至第十章只有 Node.js範例程式碼,但轉換至其他平台應該不難。

“實務”是什麼意思?

我以前與 Scott Davis合著《JBoss at Work 》時的目標是寫一本開發者可在進行實務工

作時使用的書。同樣的,這本書的目的是根據我的 JSON實務經驗提供實務範例給開發者,因此我(於合適時)在每一章提供單元測試。這很簡單:若一段程式碼沒有相對應

的測試,則該程式碼並不存在。就是這樣。

準備動手並檢視程式碼。無論你是架構設計師或開發者,都會發現本書對你有幫助。

本書內容

本書內容與範例包括:

• JSON基本概念與 JSON資料模型設計

Page 3: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

前言 | vii

• 在 Node.js、Ruby on Rails與 Java中使用 JSON

• 以 JSON Schema建構 JSON文件以進行設計與 API測試

• 以 JSON搜尋工具搜尋 JSON文件內容

• 以 JSON轉換工具將 JSON文件轉換成其他格式

• 在企業架構中使用 JSON

• JSON超媒體格式的比較,包括 HAL與 json:api

• 使用 MongoDB儲存與存取 JSON文件

• 在服務間使用 Apache Kafka交換 JSON訊息

• 使用 JSON工具簡化測試

• 透過工具與函式庫從你偏好的程式設計語言呼叫 API

工具

以下是你在本書中會使用到的 JSON工具:

• JSON編輯器 /模型工具

• 單元測試工具(例如 Mocha/Chai、Minitest、JUnit)

• JSON檢驗工具

• JSON Schema產生工具

• JSON搜尋工具

• JSON轉換(模板)工具

非本書內容

這本書不適合只對 JavaScript呼叫 AJAX的 JSON感興趣的人。雖然我會討論這個主題,但那只是冰山一角。很多 JavaScript書都有你感興趣的那一章。

本書沒有 REST、Ruby on Rails、Java、JavaScript等深入的討論。這本書依靠這些技術,但專注於使用 JSON的部分。

Page 4: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

viii | 前言

本書架構

這本書分為以下幾個部分:

• 第一部 JSON 概要與平台

• 第二部 JSON 生態系

• 第三部 JSON 企業實務

• 附錄

第一部 JSON概要與平台• 第一章 JSON 概要,討論 JSON資料格式、運用 JSON的最佳做法與工具的介紹。

• 第二章 JavaScript 與 JSON,討論如何在 JavaScript、Node.js與 Mocha/Chai單元測試中使用 JSON

• 第三章 Ruby on Rails 與 JSON,討論如何轉換 Ruby物件與 JSON,以及與 Rails的 整合。

• 第四章 JAVA 與 JSON,討論如何在 Java與 Sprint Boot中使用 JSON。

第二部 JSON生態系• 第五章 JSON Schema,討論以 JSON Schema 建構 JSON 文件,以及使用它產生

JSON Schema與 API設計。

• 第六章 JSON 搜尋,討論如何使用 jq與 JSONPath搜尋 JSON文件。

• 第七章 JSON 轉換,討論將設計不良的 JSON文件轉換成更好的 JSON文件時所需的工具,還有如何轉換 JSON與 XML或 HTML等其他格式。

第三部 JSON企業實務• 第八章 JSON 與超媒體,討論如何使用 JSON與常見的超媒體格式(例如 HAL與

jsonapi)。

• 第九章 JSON 與 MongoDB,討論如何利用 MongoDB儲存與存取 JSON文件。

• 第十章 JSON 與 Kafka,討論如何使用 Apache Kafka在服務間交換 JSON訊息。

Page 5: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

第一章

JSON概要

JavaScript Object Notation(JSON)資料格式讓應用程式透過通常為 RESTful API的網路通訊。JSON無關技術、非專利,且可攜。所有新式語言(例如 Java、JavaScript、Ruby、C#、PHP、Python與 Groovy)以及平台都有提供非常好的 JSON資料生產(序列化)與消耗(解序列化)支援。JSON很簡單:它由物件、陣列與名稱 /值對等開發者友善的結構組成。JSON不只是用於具象狀態傳輸(Representational State Transfer,REST);它還可用於:

• Node.js(將專案元資料儲存在 package.json中)

• MongoDB等 NoSQL資料庫(見第九章)

• Kafka等訊息平台(見第十章)

JSON是一種標準在早期,REST 的 RESTful Web Services 並非標準,但(如同 HTTP)JSON 實際上是一個標準。Internet Engineering Task Force(IETF)與 Ecma Internationa(前身為European Computer Manufacturers Association 或 稱 ECMA) 已 經 視 JSON 為 標 準。Douglas Crockford 於 2001 年創造了 JSON 並於 2006 年透過 IETF 的 RFC 4627 首次標 準 化; 見 JSON 規 格(http://tools.ietf.org/html/rfc4627)。Ecma International 於 2013年秋季也透過 ECMA 404 將 JSON 標準化;詳見 JSON 規格(http://bit.ly/2skDdEV)。

因 Ecma 的認可(根據 Douglas Crockford 的說法;詳見他的 Google+ 頁,http://bit.

ly/2thZmkj),JSON現在被視為正規的國際資料處理標準。

Page 6: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

4 | 第一章

Tim Bray 於 2014 年三月以 IETF 的 RFC 7158(http://tools.ietf.org/html/rfc7158)發佈

Douglas Crockford原案的更新版本與 RFC 7159(http://tools.ietf.org/html/rfc7159)對原

版 IETF 4627標準的勘誤(因此原版已過時)。

範例

在更進一步之前,讓我們看個簡短的 JSON範例。範例 1-1顯示一個簡短的 JSON文件。

範例 1-1 firstValidObject.json

{ "thisIs": "My first JSON document" }

一個合法的 JSON文件可為下列之一:

• 以大括號 {與 }包圍的物件。

• 以方括號 [與 ]包圍的陣列。

前面的範例有個帶單一鍵 / 值對的物件,鍵為 "thisIs",值為 "My first JSON document"。

讓我們以 JSONLint(https://jsonlint.com/)檢驗這一份文件。將文件內容貼到文字區域

中,點擊 Validate按鈕,你應該會看到如圖 1-1所示的網頁。

Page 7: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

JSON概要 | 5

圖 1-1 以 JSONLint檢驗 JSON文件

範例 1-2是一個簡單的 JSON陣列。

範例 1-2 firstValidArray.json

[ "also", "a", "valid", "JSON", "doc"]

將 JSON陣列貼到 JSONLint的文字區域,點擊 Validate按鈕,你應該會看到圖 1-2所示的結果。

Page 8: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

6 | 第一章

圖 1-2 JSONLint檢驗通過的陣列

現在已經超前進度了。我們會在“JSON核心”一節完整的討論 JSON語法。

為何用 JSON?雖然 Ecma International與 IETF的標準化對業界接受 JSON產生了幫助,但廣泛採用JSON還有其他因素:

• 基於 JSON的 RESTful API大量的出現

• JSON基本資料結構的簡單化

• JavaScript的廣泛使用

Page 9: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

JSON概要 | 7

JavaScript的復興推動了 JSON的採用。過去幾年間,我們看到 JavaScript興起為第一等開發語言與環境。此生態系包括 Node.js 等平台與 AngularJS、React、Backbone 和Ember等 Mode/View/Controller(MVC)框架,還有大量的書籍與網站討論 JavaScript物件與模式的最佳做法。據 Douglas Crockford所述,JSON是 JavaScript的物件實字記號法的子集並與 JavaScript開發緊密的結合。

許多 RESTful API使用 JSON。下列是一些常見的 JSON的 RESTful API:

• LinkedIn

• Twitter

• Facebook

• Salesforce

• GitHub

• DropBox

• Tumblr

• Amazon Web Services(AWS)

Programmableweb(http://www.programmableweb.com/)列出了數千個使用 JSON的 RESTful API,搜尋 REST與 JSON會有非常多的結果供檢視。

JSON很簡單且最終會取代 XML成為網路上的主要資料交換格式。JSON容易閱讀且結構容易讓軟體開發者理解─陣列、物件與名稱 /值對,我們無須傷腦筋或爭論何為元素或屬性。物件與其資料成員更適合物件導向(OO)設計與開發。JSON格式的文件通常較相同內容的 XML更小,因為 JSON的基本成本較小且更緊湊。這是因為不需要前後標籤包圍每個資料元素。因此在企業等級中,JSON的處理比 XML更有效率,因為JSON文件可透過網路傳輸且處理比相對應的 XML更快。

雖然 Douglas Crockford一開始是打算讓 JSON作為資料交換格式(通常用於 REST),但 JSON 現在被用於 Node.js 與 Sublime Text 等許多產品的組態檔案。Node.js 的package.json檔案定義其標準 npm套件結構;見第二章。Sublime Text這個網頁開發社群中常見的 IDE使用 JSON設定外觀與套件管理。

Page 10: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

8 | 第一章

JSON核心JSON核心資料格式包括 JSON資料與值型別。我們還會討論版本、註解與 File/MIME型別。

JSON資料型別JSON有下列核心資料型別:

名稱(或鍵)/值對

由鍵(資料屬性)與值組成。

物件

無排序的名稱 /值對集合。

陣列

有排序的值集合。

現在已經看過了基本定義,讓我們深入每個資料型別。

名稱 /值對

範例 1-3顯示名稱 /值對的範例。

範例 1-3  nameValue.json

{ "conference": "OSCON", "speechTitle": "JSON at Work", "track": "Web APIs"}

名稱 /值對有下列特質:

• 每個名稱(例如 "conference")

─ 在冒號的左邊

─ 是個字串,且必須以雙引號包圍

• 值(例如 "OSCON")在冒號右邊。在前面的範例中,值型別為字串,但還有其他的值型別。

Page 11: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

JSON概要 | 9

我們會在“JSON值型別”一節討論字串與其他合法值型別。

物件

物件由名稱 /值對組成。範例 1-4顯示一個代表地址的物件。

範例 1-4 simpleJsonObject.json

{ "address" : { "line1" : "555 Any Street", "city" : "Denver", "stateOrProvince" : "CO", "zipOrPostalCode" : "80202", "country" : "USA" }}

範例 1-5顯示有套疊陣列的物件。

範例 1-5 jsonObjectNestedArray.json

{ "speaker" : { "firstName": "Larson", "lastName": "Richard", "topics": [ "JSON", "REST", "SOA" ] }}

範例 1-6顯示由其他物件組成的物件。

範例 1-6 jsonObjectNestedObject.json

{ "speaker" : { "firstName": "Larson", "lastName": "Richard", "topics": [ "JSON", "REST", "SOA" ], "address" : { "line1" : "555 Any Street", "city" : "Denver", "stateOrProvince" : "CO", "zipOrPostalCode" : "80202", "country" : "USA" }

Page 12: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

10 | 第一章

}}

物件具有下列特質:

• 以大括號 {}包圍

• 由逗號分隔的無排序名稱 /值對組成

• 可為空,{ }

• 可套疊在物件或陣列中

陣列

範例 1-7顯示一個描述展示的名稱、時間長度與大綱等資訊的陣列(帶有套疊的物件與陣列)。

範例 1-7 jsonArray.json

{ "presentations": [ { "title": "JSON at Work: Overview and Ecosystem", "length": "90 minutes", "abstract": [ "JSON is more than just a simple replacement for XML when", "you make an AJAX call." ], "track": "Web APIs" }, { "title": "RESTful Security at Work", "length": "90 minutes", "abstract": [ "You've been working with RESTful Web Services for a few years", "now, and you'd like to know if your services are secure." ], "track": "Web APIs" } ]}

陣列具有下列特質:

• 以方括號 []包圍

• 由逗號分隔的有排序值組成(見下一節)

Page 13: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

JSON概要 | 11

• 可為空,[ ]

• 可套疊在物件或陣列中

• 索引從 0或 1開始

JSON值型別JSON值型別代表名稱 /值對中冒號(:)右邊的資料型別。JSON值型別包括:

• 物件

• 陣列

• 字串

• 數字

• 布林

• 空

我們看過了物件與陣列;接下來討論其餘型別:字串、數字、布林與空。

字串

範例 1-8顯示合法的 JSON字串。

範例 1-8 jsonStrings.json

[ "fred", "fred\t", "\b", "", "\t", "\u004A"]

字串具有下列屬性:

• 字串由零或更多的 Unicode字元包含在雙引號(" ")中組成。其他合法字元見下列項目。

• 以單引號(')包圍的字串不合法。

Page 14: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

12 | 第一章

此外,JSON字串可包含下列反斜線跳脫的字元:

\"

雙引號

\\

反斜線

\/

斜線

\b

後退

\f

饋頁

\n

換行

\r

回車

\t

Tab

\u

後面四個十六進位數字

數字

範例 1-9顯示合法的 JSON數字。

範例 1-9 jsonNumbers.json

{ "age": 29, "cost": 299.99, "temperature": -10.5, "unitCost": 0.2,

Page 15: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

JSON概要 | 13

"speedOfLight": 1.23e11, "speedOfLight2": 1.23e+11, "avogadro": 6.023E23, "avogadro2": 6.023E+23, "oneHundredth": 10e-3, "oneTenth": 10E-2}

數字依循 JavaScript的雙精度浮點數格式且具有下列屬性:

• 數字為十進位(只容許 0-9)且無前綴零。

• 小數部分從小數點(.)開始。

• 數字可帶 10指數,以 e或 E記號法與加減號表示正負指數。

• 不支援八或十六進位格式。

• 與 JavaScript不同,數字不能有 NaN(非數字)或 Infinity值。

布林

範例 1-10顯示 JSON布林值。

範例 1-10 jsonBoolearn.json

{ "isRegistered": true, "emailValidated": false}

布林具有下列屬性:

• 布林只能為 true或 false。

• 冒號(:)右邊的 true或 false值沒有引號包圍。

雖然空在技術上並非值型別,但 null在 JSON 中是個特殊值。範例 1-11顯示空值的line2。

範例 1-11 jsonNull.json

{ "address": {

Page 16: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

14 | 第一章

"line1": "555 Any Street", "line2": null, "city": "Denver", "stateOrProvince": "CO", "zipOrPostalCode": "80202", "country": "USA" }}

空值具有下列特質:

• 沒有引號包圍

• 表示鍵 /屬性沒有值

• 作為佔位符

JSON版本據 Douglas Crockford所述,JSON核心標準絕對不會有其他版本。但這並非表示 JSON是完美的;沒有什麼是完美的。JSON只有一個版本的目的是避免向後相容支援的問題。Crockford相信開發社群在有需要時會以新的資料格式取代 JSON。

但在接下來的章節中你會發現“沒有其他版本”只適用於 JSON核心資料格式。舉例來說,第五章討論的規格是目前的 0.5版。請注意,這些 JSON相關的規格是 JSON社群中的其他人所創造的。

JSON註解JSON文件中沒有註解。就是這樣。

根 據 Crockford 在 Yahoo! JSON group(https://yhoo.it/2sp7za1) 與 Google+(http://bit.

ly/2sp83gw)的說法,他一開始是允許註解的,但因為下列原因很早就拿掉了:

• 他認為註解不實用。

• JSON解析程序對於註解的支援有困難。

• 人們濫用註解。舉例來說,他注意到註解被用於解析指示,這會毀掉相互操作性。

• 拿掉註解可簡化 JSON跨平台支援。

Page 17: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

JSON概要 | 15

JSON的檔案與 MIME型別根據 JSON核心規格所述,.json是儲存 JSON資料到檔案系統時標準的 JSON檔案型別。JSON的 Internet Assigned Numbers Authority(IANA)媒體(或稱 MIME)型別為application/json,見 IANA媒體型別網站(http://bit.ly/1cogNWM)。RESTful網路服務的生產與消耗方使用稱為內容協商的技術(利用 HTTP標頭中的 JSON MIME型別)表示交換的是 JSON資料。

JSON樣式準則JSON的目的是相互操作性,提供消耗方預期中的 JSON資料很重要。Google發佈了一份 JSON Style Guide(https://google.github.io/styleguide/jsoncstyleguide.xml)以支援可維

護性與最佳做法。

Google JSON Style Guide內容很多,以下列出對 API設計者與開發者最重要的部分:

• 屬性名稱

• 日期屬性值

• 列舉值

屬性名稱

屬性名稱(Google的說法)在名稱 /值對冒號的左邊(屬性值在右邊)。JSON屬性名稱主要有兩種樣式:

• lowerCamelCase

• snake_case

採用 lowerCamelCase時,名稱是看起來像是一個字詞的相連或多個字詞,(除了第一個字詞外)每個字詞的第一個字母大寫。Java與 JavaScript社群都採用 lowerCamelCase。採用 snake_case時,所有字母都小寫,字詞以底線(_)分隔。Ruby on Rails社群偏好snake_case。

Google與大部分 RESTful API均對屬性名稱如範例 1-12所示採用 lowerCamelCase。

Page 18: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

16 | 第一章

範例 1-12  jsonPropertyName.json

{ "firstName": "John Smith"}

日期屬性值

你或許覺得日期格式不太重要,但其實非常重要。想像一下不同國家的生產方與消耗方

交換日期資訊。就算在同一家企業,兩個開發者都有可能使用不同的格式。思考如何解

析時間戳記以一致的處理不同時區的日期時間很重要。Google JSON Style Guide偏好如範例 1-13所示 RFC 3339(http://www.ietf.org/rfc/rfc3339.txt)格式。

範例 1-13 jsonDateFormat.json

{ "dateRegistered": "2014-03-01T23:46:11-05:00"}

上面的日期是世界協調時間(UTC)加(相對於 UTC/GMT─格林威治時間)─ 5小時,也就是美東標準時間。請注意,RFC 3339 是 ISO 8601 的原型。主要的差別是International Standards Organization 的 ISO 8601(http://www.iso.org/iso/home/standards/

iso8601.htm)容許以空白替換 T(分隔日期與時間),而 RFC 3339不容許。

經緯值

地理 API(例如 Google Maps)以及地理資訊系統(GIS)相關的 API使用經緯度資料。Google JSON Style Guide建議經緯資料依循 ISO 6709標準(http://en.wikipedia.org/wiki/

ISO_6709)。根據 Google Maps,紐約帝國大廈的經緯為 40.748747° N, 73.985547° W,在 JSON中的表示方式如範例 1-14所示。

範例 1-14 jsonLatLon.json

{ "empireStateBuilding": "40.748747-73.985547"}

此範例依循 ±DD.DDDD±DDD.DDDD格式,慣例上:

• 緯度在前。

• (赤道)北為正。

Page 19: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

JSON概要 | 17

• (本初子午線)東為正。

• 經緯度以字串表示。由於有負號所以不是數字。

縮排

雖然 Google JSON Style Guide對此未表示意見,但還是有些規則:

• JSON是序列化格式而非展示格式,因此縮排對 API的生產方或消耗方無意義。

• 許多 JSON格式工具讓使用者在美化 JSON文件時選擇二至四個空白的縮排。

• JSON源自 JavaScript(ECMA 262標準的一部分),但不幸的是 JavaScript社群中沒有共識。許多人以及設計樣式指南偏好兩個空白,本書採用這種慣例。如果你偏好

其他樣式也沒關係,但要保持一致。

範例─MyConference本書以研討會資料作為範例,包括:

• 主講人

• 議程

技術架構

我們會從簡單的主講人 JSON資料儲存體開始,並以下列步驟發佈到一個 RESTful API:

1. 以線上 JSON編輯器設計 JSON資料

2. 以 JSON產生程序製作 JSON資料

3. 設計模擬 API(供測試用)

架構風格—noBackend我們採用基於 noBackend(http://nobackend.org/)的架構風格。noBackend的開發者在開發階段前期無須擔心應用程式伺服器或資料庫的細節。

本書前七章採用 noBackend架構以專注於商業角度(服務與資料優先),因此我們不只可以支援 UI用戶端(例如行動、平板與網頁),還能顧及 API與非網頁用戶端應用程式。我們會使用 json-server等工具模擬 RESTful API以部署 JSON資料。

Page 20: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

18 | 第一章

透過這種方法,我們以界面優先的方式設計與建構 API,它具有:

• 更敏捷、快速、迭代的前端開發,因為與後端解耦。

• 更快從 API本身獲得回饋。快速取得前端資料與 URI供快速檢視。

• API與消耗者間更清楚的界面。

• 分割 API顯露的資源(例如 JSON資料表示的主講人)與內部(最終)實作(例如應用程式伺服器、商業邏輯與資料儲存體)。如此能讓後續的實作改變更容易。若一

開始就以 Node.js/Rails/Java(或其他框架)建構與部署了 API,前期做出的設計決定會在開始進行 API消耗者時變得難以修改。

模擬 API的功能是:

• 免去一開始就要碰到伺服器與資料庫

• 讓 API生產者(撰寫 API的開發者)專注於 API設計、將資料呈現給消耗方的最好方式、與初始測試

• 讓 API消耗方(例如 UI開發者)提前使用 API並提供意見給 API開發團隊

使用本書的輕量化工具能讓你在執行程式與部署至伺服器前就有收穫。當然,你最終還

是得實作出 API,第二至第四章討論 JavaScript、Ruby on Rails與 Java時會示範如何進行。

以線上 JSON編輯器設計 JSON資料模型建構實際大小或複雜的 JSON 文件是繁瑣與容易出錯的工作。 JSON Editor Online(http://www.jsoneditoronline.org)是提供下列功能的網頁工具:

• 讓你以物件、陣列與名稱 /值對設計 JSON文件模型

• 以迭代的方式快速方便的產生 JSON文件的內容

JSONmate(http://jsonmate.com)是另一個線上編輯器,但本書不會討論。

Page 21: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

JSON概要 | 19

JSON Editor Online功能

除了設計 JSON模型與產生內容外,JSON Editor Online還提供下列功能:

JSON檢驗

檢驗會在你輸入 JSON資料到網頁左邊的 JSON文件區域內時進行。若你忘記加上值後面的雙引號(例如 "firstName":"Ester),下一行 JSON文字會顯示一個 X並有浮出的檢驗錯誤說明。

JSON排版美化

點擊 JSON文字區域左上角的 Indent按鈕。

模型設計與 JSON文字間完整的工程循環

(以 Append(+)按鈕)從網頁右邊的 JSON模型產生一些物件與鍵 /值對後,點擊向左箭頭(網頁中間上方)產生 JSON文字。你應該會看到網頁左邊的 JSON文字區域反映變化。

在 JSON文字區域做一些修改並點擊向右箭頭應該會看到網頁右邊的 JSON模型 改變。

儲存 JSON文件到磁碟

你可以從 Save選單選擇 Save to Disk選項將 JSON文件儲存在你的機器上。

匯入 JSON文件

你可以從 Open選單選擇 Open from Disk選項以從你的電腦匯入 JSON文件。

請記得 JSON Editor Online是個公開的工具,這表示他人也能看到你貼上的資料,因此不要操作敏感資料(隱私、機密等)。

JSON Editor Online上的主講人資料

設計好主講人資料模型後,點擊向右箭頭按鈕以產生排版(縮排)過代表該模型的

JSON文件。圖 1-3顯示 JSON Editor Online上的主講人模型。

Page 22: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

20 | 第一章

圖 1-3 JSON Editor Online上的主講人模型

這是模型的草稿,但是個不錯的開始。使用草稿模型將 JSON資料視覺化、取得前期回饋,並快速的迭代設計。這種方式讓你能在開發過程中改善 JSON資料結構,而無須投入大量的實作與基礎建設。

以 JSON Generator產生假資料JSON Editor Online提供基礎,但我們需要快速產生大量測試資料。測試資料因為資料的敏感性而可能會有問題,且有意義的測試需要大量資料。就算是使用 JSON Editor Online,產生大量測試資料也要一番功夫。我們需要其他工具來產生第一版 API 所需的資料,而 JSON Generator(http://www.json-generator.com)正是我們所需要的。

我們使用這個工具產生 spearkers.json 測試資料檔案(https://github.com/tmarrs/json-at-

work-examples/blob/master/chapter-1/speakers.json)。產生 spearkers.json 檔案的模板可

從 GitHub 下 載(https://github.com/tmarrs/json-at-work-examples/blob/master/chapter-1/

jsonGeneratorTem)。第五章會更深入討論 JSON Generator。

Page 23: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

JSON概要 | 21

建構與部署模擬 API為建構模擬 API,我們會使用剛剛建構的主講人資料並部署成 RESTful API。我們會利用 json-server這個 Node.js模組將 speaker.json檔案作為 Web API;如此能快速製作原型。更多 json-server資訊見 GitHub網頁(https://github.com/typicode/json-server)。

繼續之前還要設置開發環境。參考附錄 A執行下列動作:

1. 安裝 Node.js。json-server是個 Node.js模組,因此需要先安裝 Node.js。請見“安裝 Node.js”一節。

2. 安裝 json-server。請見“安裝 npm模組”一節。

3. 安裝 JSONView 與 Postman。請見“安裝 JSON 瀏覽器工具”一節。JSONView 是Chrome與 Firefox中的 JSON排版美化工具,而 Postman可在大部分作業系統中獨立作為 GUI應用程式運行。

從命令列開啟終端機並在埠 5000執行 json-server:

cd chapter-1

json-server -p 5000 ./speakers.json

你應該會看到如下畫面:

從瀏覽器開啟 http://localhost:5000/speakers,你應該會看到如圖 1-4所示模擬 API的所有主講人(JSONView產生的 JSON美化排版)。

Page 24: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

22 | 第一章

圖 1-4 以瀏覽器檢視透過 JSONView排版後的 json-server上的主講人

你還可以在 URI加上 id以取得單一主講人:http://localhost:5000/speakers/0。

這是個起點,但瀏覽器對測試有限制;它只能發出 HTTP的 GET請求。Postman提供完整的 RESTful API測試能力,它可以發出 HTTP的 GET、POST、PUT與 DELETE請求,並設置 HTTP的標頭。

讓我們使用 Postman刪除 API中的第一個主講人:

1. 輸入 http://localhost:5000/speakers/0。

2. HTTP verb選擇 DELETE。

3. 點擊 Send按鈕。

你應該會看到 DELETE在 Postman中收到 HTTP回應 200(OK),如圖 1-5所示。

Page 25: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

JSON概要 | 23

圖 1-5 Postman:刪除第一個主講人的結果

接下來,從瀏覽器檢視 http://localhost:5000/speakers/0以確定第一個主講人真的被刪除

了。你應該看到如圖 1-6所示的空白回應。

圖 1-6 檢查刪除第一個主講人的結果

你可以在命令列按下 Ctrl-C停止 json-server。

有了模擬 API,我們就可以從任何 HTTP用戶端(例如 JavaScript、Ruby 或 Java)呼叫它以從外部應用程式消耗資料。雖然後續內容的大部分範例都使用 HTTP的 GET,但json-server確實可以處理所有 HTTP的核心指令(GET、POST、PUT與 DELETE)。本書不準備討論的 Mountebank(http://www.mbtest.org)是提供更好功能及模擬 API與協定的另一個伺服器。

重點是 API生產方可使用 JSON工具製作可供測試的 RESTful API原型,而無須撰寫任何程式。同時間,API開發團隊可迭代改善設計與原型。

Page 26: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A497.pdf · 程式範例包括 JavaScript 、Node.js 、Ruby on Rails與Java。 ... Node.js 的. package.json 檔案定義其標準npm

24 | 第一章

摘要

我們討論了 JSON的基本資訊、以 JSON Editor Online設計 JSON資料模型,與部署模擬 API。

下一步

接下來的三章將討論如何在下列平台使用 JSON:

• JavaScript

• Ruby on Rails

• Java

第二章討論如何在 JavaScript中使用 JSON與 json-server建構的模擬 API。