├── CONTRIBUTING.md ├── CONTRIBUTORS.md ├── LICENSE.md ├── README.md ├── SUMMARY.md ├── artifacts ├── README.md ├── describe-stability.md ├── provide-executable-examples.md ├── provide-human-readable-docs.md └── provide-machine-readable-json-schema.md ├── book.json ├── cover.jpg ├── cover_small.jpg ├── foundations ├── README.md ├── divide-large-responses-across-requests-with-ranges.md ├── provide-request-ids-for-introspection.md ├── require-secure-connections.md ├── require-versioning-in-the-accepts-header.md ├── separate-concerns.md └── support-etags-for-caching.md ├── requests ├── README.md ├── accept-serialized-json-in-request-bodies.md ├── downcase-paths-and-attributes.md ├── minimize-path-nesting.md ├── provide-full-resources-where-available.md ├── return-appropriate-status-codes.md ├── support-non-id-dereferencing-for-convenience.md └── use-consistent-path-formats.md └── responses ├── README.md ├── generate-structured-errors.md ├── keep-json-minified-in-all-responses.md ├── nest-foreign-key-relations.md ├── provide-resource-uuids.md ├── provide-standard-timestamps.md ├── show-rate-limit-status.md └── use-utc-times-formatted-in-iso8601.md /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## 貢獻心力 2 | 3 | 歡迎對這份指南貢獻心力及對內容提出指教。如需改動請開 4 | [issue](https://github.com/kcyeu/http-api-design/issues) 或提出 5 | [pull request](https://github.com/kcyeu/http-api-design/pulls)。 6 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | ## 貢獻者 2 | 3 | * [Wesley Beary](mailto:geemus+github@gmail.com) 4 | * [Mark McGranaghan](mailto:mmcgrana@gmail.com) 5 | * [Jamu Kakar](mailto:jkakar@kakar.ca) 6 | * [Jonathan Roes](mailto:jroes@jroes.net) 7 | * [Kuo-Cheng Yeu](https://github.com/kcyeu) 8 | 9 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | ## 授權 2 | 3 | 版權歸[貢獻者](CONTRIBUTORS.md)所有。 4 | 5 | 本著作係採用 [Creative Commons Attribution 4.0 International License](http://creativecommons.org/licenses/by/4.0/) (CC BY 4.0) 授權條款授權. 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HTTP API 設計指南 2 | 3 | ## 簡介 4 | 5 | 這份指南講述出自於 [Heroku Platform API](https://devcenter.heroku.com/articles/platform-api-reference) 6 | 的 HTTP + JSON API 設計方式,原本的點子來自 [Wesley Beary](https://github.com/geemus) 等人的 7 | [HTTP API Design Guide](https://github.com/interagent/http-api-design)。 8 | 9 | 除了提到 API 本身之外,也介紹了 Heroku 內部 API,希望 Heroku 以外的 10 | API 設計者也會感到興趣。 11 | 12 | 我們的目標是一致性並專注在商務邏輯,避免被瑣事耽擱。尋求的雖未必是 13 | API 設計的**終極之道**,但卻是**健全、一致,且有完整文件的方法**。 14 | 15 | 我們假設您已熟悉基本的 HTTP + JSON API,因此本指南不會涵蓋所有的基本知識。 16 | 17 | 歡迎一同為這份指南[貢獻心力](https://github.com/kcyeu/http-api-design/blob/master/CONTRIBUTING.md),本書的[貢獻者見此](https://github.com/kcyeu/http-api-design/blob/master/CONTRIBUTORS.md)。 18 | 19 | ## 版本 20 | 21 | * 15.02.0 22 | * 新增章節: 基礎/少些顧慮 23 | * 潤飾部分章節文句 24 | * 對應[版本](https://github.com/interagent/http-api-design/commit/232f8dc6a941d0b25136bf64998242dae5575f66) (232f8dc) 25 | * 14.12.0 26 | * 初版,對應[版本](https://github.com/interagent/http-api-design/commit/c3a69b530274e2f776b2030f9ed790af0f6cbf3d) (c3a69b5) 27 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | ## Summary 2 | 3 | * [簡介](README.md) 4 | * [基礎](foundations/README.md) 5 | * [重心分離](foundations/separate-concerns.md) 6 | * [要求使用安全連線](foundations/require-secure-connections.md) 7 | * [要求以 Accept 標頭註明版本](foundations/require-versioning-in-the-accepts-header.md) 8 | * [以 ETag 支援快取](foundations/support-etags-for-caching.md) 9 | * [提供 Request-Id 以便追溯](foundations/provide-request-ids-for-introspection.md) 10 | * [以 Range 分割資料量大的回應](foundations/divide-large-responses-across-requests-with-ranges.md) 11 | * [需求](requests/README.md) 12 | * [回傳適當的狀態碼](requests/return-appropriate-status-codes.md) 13 | * [情況許可時提供全部資源](requests/provide-full-resources-where-available.md) 14 | * [接受需求本體的序列化 JSON](requests/accept-serialized-json-in-request-bodies.md) 15 | * [使用一致的路徑格式](requests/use-consistent-path-formats.md) 16 | * [小寫路徑與屬性](requests/downcase-paths-and-attributes.md) 17 | * [支援非 ID 的便利存取](requests/support-non-id-dereferencing-for-convenience.md) 18 | * [減少巢狀路徑](requests/minimize-path-nesting.md) 19 | * [回應](responses/README.md) 20 | * [提供資源的 UUID](responses/provide-resource-uuids.md) 21 | * [提供標準時間戳記](responses/provide-standard-timestamps.md) 22 | * [使用 UTC 時間並以 ISO 8601 格式表達](responses/use-utc-times-formatted-in-iso8601.md) 23 | * [巢狀表示外來鍵關係](responses/nest-foreign-key-relations.md) 24 | * [產生結構化的錯誤訊息](responses/generate-structured-errors.md) 25 | * [顯示次數限制狀態](responses/show-rate-limit-status.md) 26 | * [保持所有回應中的 JSON 最小化](responses/keep-json-minified-in-all-responses.md) 27 | * [產出](artifacts/README.md) 28 | * [提供機器可讀的 JSON 大綱](artifacts/provide-machine-readable-json-schema.md) 29 | * [提供一般人可讀的文件](artifacts/provide-human-readable-docs.md) 30 | * [提供執行範例](artifacts/provide-executable-examples.md) 31 | * [描述穩定性](artifacts/describe-stability.md) 32 | 33 | -------------------------------------------------------------------------------- /artifacts/README.md: -------------------------------------------------------------------------------- 1 | ### 產出 2 | 3 | * [提供機器可讀的 JSON 大綱](provide-machine-readable-json-schema.md) 4 | * [提供一般人可讀的文件](provide-human-readable-docs.md) 5 | * [提供執行範例](provide-executable-examples.md) 6 | * [描述穩定性](describe-stability.md) 7 | -------------------------------------------------------------------------------- /artifacts/describe-stability.md: -------------------------------------------------------------------------------- 1 | #### 描述穩定性 2 | 3 | 描述您的 API 的穩定性或依成熟度及穩定性描述這些端點,例如:prototype/development/production 旗標。 4 | 5 | 穩定性與變更管理方法參見 [Heroku API compatibility policy](https://devcenter.heroku.com/articles/api-compatibility-policy)。 6 | 7 | 一旦您的 API 宣告穩定版已上線 (production-ready and stable),不要在該版本做向後不相容的變更。若非得如此,請建立新的 API 版號。 8 | 9 | -------------------------------------------------------------------------------- /artifacts/provide-executable-examples.md: -------------------------------------------------------------------------------- 1 | #### 提供執行範例 2 | 3 | 提供執行範例讓使用者直接在終端機鍵入並觀看有效的 API 呼叫。這些範例應盡可能減少使用者嘗試的工夫,例如: 4 | 5 | ```bash 6 | $ export TOKEN=... # acquire from dashboard 7 | $ curl -is https://$TOKEN@service.com/users 8 | ``` 9 | 10 | 若您使用 [prmd](https://github.com/interagent/prmd) 建立 Markdown 文件,您可以直接取得各端點的範例。 11 | -------------------------------------------------------------------------------- /artifacts/provide-human-readable-docs.md: -------------------------------------------------------------------------------- 1 | #### 提供一般人可讀的文件 2 | 3 | 提供一般人可讀的文件,讓開發者理解您的 API。 4 | 5 | 若您以前述 prmd 建立大綱,您可以用 `prmd doc` 輕鬆的產生所有端點的 Markdown 文件。 6 | 7 | 除了端點的詳細內容,也應提供含以下資訊的 API 概觀: 8 | 9 | * 認證方法,包含取得與使用 token。 10 | * API 穩定性與版本,包含如何選擇想要的 API 版本。 11 | * 一般性的需求與回應標頭。 12 | * 錯誤序列化 (serialization) 格式。 13 | * 不同語言的客戶端 API 使用範例 14 | -------------------------------------------------------------------------------- /artifacts/provide-machine-readable-json-schema.md: -------------------------------------------------------------------------------- 1 | #### 提供機器可讀的 JSON 大綱 2 | 3 | 提供機器可讀的 JSON 大綱清楚說明您的 API。使用 [prmd](https://github.com/interagent/prmd) 管理您的大綱,並確認它通過 `prmd verify` 指令的驗證。 4 | 5 | -------------------------------------------------------------------------------- /book.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "disqus" 4 | ], 5 | "pluginsConfig": { 6 | "disqus": { 7 | "shortName": "http-api-design-guide" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kcyeu/http-api-design/569b209055b766da9c95854923a1909857a8c7d3/cover.jpg -------------------------------------------------------------------------------- /cover_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kcyeu/http-api-design/569b209055b766da9c95854923a1909857a8c7d3/cover_small.jpg -------------------------------------------------------------------------------- /foundations/README.md: -------------------------------------------------------------------------------- 1 | ### 基礎 2 | 3 | * [重心分離](separate-concerns.md) 4 | * [要求使用安全連線](require-secure-connections.md) 5 | * [要求以 Accept 標頭註明版本](require-versioning-in-the-accepts-header.md) 6 | * [以 ETag 支援快取](support-etags-for-caching.md) 7 | * [提供 Request-Id 以便追溯](provide-request-ids-for-introspection.md) 8 | * [以 Range 分割資料量大的回應](divide-large-responses-across-requests-with-ranges.md) 9 | 10 | -------------------------------------------------------------------------------- /foundations/divide-large-responses-across-requests-with-ranges.md: -------------------------------------------------------------------------------- 1 | #### 以 Range 分割資料量大的回應 2 | 3 | 以 `Range` 分割資料量大的回應,使其對應多個需求,並註明當有更多資料時如何取得。 4 | 5 | 需求與回應標頭、狀態碼、限制、順序及迭代方式等詳情, 6 | 可參考 [Heroku Platform API discussion of Ranges](https://devcenter.heroku.com/articles/platform-api-reference#ranges)。 7 | 8 | -------------------------------------------------------------------------------- /foundations/provide-request-ids-for-introspection.md: -------------------------------------------------------------------------------- 1 | #### 提供 Request-Id 以便追溯 2 | 於每個 API 回應中加入含 UUID 的 `Request-Id` 標頭。於伺服器、客戶端或其他後端服務記錄這些值,便於日後追蹤、分析與除錯。 3 | -------------------------------------------------------------------------------- /foundations/require-secure-connections.md: -------------------------------------------------------------------------------- 1 | #### 要求使用安全連線 2 | 3 | 無例外地要求使用 TLS 安全連線存取 API。與其費工夫探討或解釋何時該使用或不該使用 TLS,全部使用 TLS 就對了。 4 | 5 | 可以的話,拒絕任何非 TLS 需求,即不回應 HTTP 或 80 port 的需求,藉此避免不安全的資料交換。若環境不許可,則回應 `403 Forbidden`. 6 | 7 | 重導是不鼓勵的,因為這允許非正規的客戶端行為卻無任何好處。仰賴重導的客戶端使伺服器流量加倍,且因機敏資料已於第一次呼叫時曝光,導致 TLS 沒有意義。 8 | -------------------------------------------------------------------------------- /foundations/require-versioning-in-the-accepts-header.md: -------------------------------------------------------------------------------- 1 | #### 要求以 Accept 標頭註明版本 2 | 3 | 對於設計與營運 API 來說,版本控管與切換可謂諸多重大考量之一。因此,最好於一開始即採取一些機制,以避免日後衝擊。 4 | 5 | 為了避免意外或不相容的變更,最好要求每個需求都註明版本。應避免使用預設版本,因為後續將非常難變更。 6 | 7 | 建議於標頭裡註明版本及其他中繼資料。將其與自定內容形態 (content type) 一起擺在 `Accept` 標頭中,例如: 8 | 9 | ``` 10 | Accept: application/vnd.heroku+json; version=3 11 | ``` 12 | 13 | -------------------------------------------------------------------------------- /foundations/separate-concerns.md: -------------------------------------------------------------------------------- 1 | #### 少些顧慮 2 | 3 | 於設計時暫不考慮需求與回應流程的不同之處,如此可簡化事情,此原則讓您可以專注於更艱深的問題。 4 | 5 | 需求與回應的目的在於處理特定資源或資料集。 使用路徑 (path) 標明來源、以本體 (body) 傳輸內容 、以標頭 (header) 協調中繼資料。 在某些極端的例子,查詢字串可作為傳入資訊的方法,但一般建議使用標頭,因為它較具彈性且能傳達更多元的資訊。 6 | 7 | -------------------------------------------------------------------------------- /foundations/support-etags-for-caching.md: -------------------------------------------------------------------------------- 1 | #### 以 Etag 支援快取 2 | 3 | 於所有回應加入 `ETag` 標頭,辨別特定版本的回傳資源。這讓使用者得以將資源存入快取,並於需求的 `If-None-Match` 標頭加入原 `ETag` 值判別快取是否須更新。 4 | -------------------------------------------------------------------------------- /requests/README.md: -------------------------------------------------------------------------------- 1 | ### 需求 2 | 3 | * [回傳適當的狀態碼](return-appropriate-status-codes.md) 4 | * [情況許可時提供全部資源](provide-full-resources-where-available.md) 5 | * [接受需求本體的序列化 JSON](accept-serialized-json-in-request-bodies.md) 6 | * [使用一致的路徑格式](use-consistent-path-formats.md) 7 | * [小寫路徑與屬性](downcase-paths-and-attributes.md) 8 | * [支援非 ID 的便利存取](support-non-id-dereferencing-for-convenience.md) 9 | * [減少巢狀路徑](minimize-path-nesting.md) 10 | -------------------------------------------------------------------------------- /requests/accept-serialized-json-in-request-bodies.md: -------------------------------------------------------------------------------- 1 | #### 接受需求本體的序列化 JSON 2 | 3 | 接受於 `PUT`、`PATCH`、`POST` 需求本體中的序列化 JSON,使其可與表單資料並存,或取代它。這與回應本體的序列化 JSON 相呼應,例如: 4 | ```bash 5 | $ curl -X POST https://service.com/apps \ 6 | -H "Content-Type: application/json" \ 7 | -d '{"name": "demoapp"}' 8 | 9 | { 10 | "id": "01234567-89ab-cdef-0123-456789abcdef", 11 | "name": "demoapp", 12 | "owner": { 13 | "email": "username@example.com", 14 | "id": "01234567-89ab-cdef-0123-456789abcdef" 15 | }, 16 | ... 17 | } 18 | ``` 19 | -------------------------------------------------------------------------------- /requests/downcase-paths-and-attributes.md: -------------------------------------------------------------------------------- 1 | #### 小寫路徑與屬性 2 | 3 | 使用小寫及橫線 ('-')分隔的路徑名,跟主機名稱格式一致,例如: 4 | 5 | ``` 6 | service-api.com/users 7 | service-api.com/app-setups 8 | ``` 9 | 10 | 且使用小寫屬性,以底線 ('_') 分隔,如此使用 JavaScript 時可以不用引號,例如 11 | 12 | ``` 13 | service_class: "first" 14 | ``` 15 | -------------------------------------------------------------------------------- /requests/minimize-path-nesting.md: -------------------------------------------------------------------------------- 1 | #### 減少巢狀路徑 2 | 3 | 當資料模型有著多重的從屬關係,路徑可能會長成巢狀的樣子: 4 | 5 | ``` 6 | /orgs/{org_id}/apps/{app_id}/dynos/{dyno_id} 7 | ``` 8 | 9 | 為了限制巢狀深度,此時可於根路徑訂定資源。使用巢狀結構標明資料範圍。 10 | 舉例而言,上述的例子中 org 所屬 app 的 dyno 可以如此標示: 11 | 12 | ``` 13 | /orgs/{org_id} 14 | /orgs/{org_id}/apps 15 | /apps/{app_id} 16 | /apps/{app_id}/dynos 17 | /dynos/{dyno_id} 18 | ``` 19 | -------------------------------------------------------------------------------- /requests/provide-full-resources-where-available.md: -------------------------------------------------------------------------------- 1 | #### 情況許可時提供全部資源 2 | 3 | 盡可能於回應裡呈現全部資源 (意即物件的所有屬性)。永遠於 200 與 201 回應提供全部資源,其中包含 `PUT`、`PATCH` 和 `DELETE` 4 | 需求,例如: 5 | 6 | ```bash 7 | $ curl -X DELETE \ 8 | https://service.com/apps/1f9b/domains/0fd4 9 | 10 | HTTP/1.1 200 OK 11 | Content-Type: application/json;charset=utf-8 12 | ... 13 | { 14 | "created_at": "2012-01-01T12:00:00Z", 15 | "hostname": "subdomain.example.com", 16 | "id": "01234567-89ab-cdef-0123-456789abcdef", 17 | "updated_at": "2012-01-01T12:00:00Z" 18 | } 19 | ``` 20 | 21 | `202` 回應不會完整呈現全部資源,例如: 22 | 23 | ```bash 24 | $ curl -X DELETE \ 25 | https://service.com/apps/1f9b/dynos/05bd 26 | 27 | HTTP/1.1 202 Accepted 28 | Content-Type: application/json;charset=utf-8 29 | ... 30 | {} 31 | ``` 32 | -------------------------------------------------------------------------------- /requests/return-appropriate-status-codes.md: -------------------------------------------------------------------------------- 1 | #### 回傳適當的狀態碼 2 | 3 | 於每個回應回傳適當的狀態碼。成功地回應應該根據以下原則編碼: 4 | 5 | * `200`: 同步需求執行成功,包含 `GET` 呼叫、`DELETE` 或 `PATCH` 呼叫、`PUT` 更新資源呼叫。 6 | * `201`: 同步需求執行成功,包含 `POST` 呼叫,及 `PUT` 建立資源呼叫。 7 | * `202`: 非同步需求已接受,包含 `POST`、`PUT`、`DELETE` 及 `PATCH`。 8 | * `206`: `GET` 需求成功,但只回傳部分回應。詳見前一章[以 Range 分頁](/foundations/divide-large-responses-across-requests-with-ranges.md)。 9 | 10 | 謹慎使用認證與授權的錯誤碼: 11 | 12 | * `401 Unauthorized`: 需求失敗,因為使用者未經認證。 13 | * `403 Forbidden`: 需求失敗,由於使用者未經授權即存取特定資源。 14 | 15 | 回傳適合的狀態碼以提供錯誤資訊: 16 | 17 | * `422 Unprocessable Entity`: 需求可被理解,但含有無效的參數。 18 | * `429 Too Many Requests`: 超過次數限制,等下再試。 19 | * `500 Internal Server Error`: 伺服器端出錯,應檢查站台狀態或回報問題。 20 | 21 | 參考 [HTTP response code spec](https://tools.ietf.org/html/rfc7231#section-6) 規範來對應使用者錯誤及伺服器錯誤的案例。 22 | -------------------------------------------------------------------------------- /requests/support-non-id-dereferencing-for-convenience.md: -------------------------------------------------------------------------------- 1 | #### 支援非 ID 的便利存取 2 | 3 | 以 ID 來辨別資源對使用者來說有時很不方便。舉個例子,使用者會以 Heroku app 名稱來思考,但那個 app 可用 UUID 辨識。這種情況您會希望同時接受 ID 與名稱,例如: 4 | 5 | ```bash 6 | $ curl https://service.com/apps/{app_id_or_name} 7 | $ curl https://service.com/apps/97addcf0-c182 8 | $ curl https://service.com/apps/www-prod 9 | ``` 10 | 11 | 不要只接受名稱而不採用 ID。 12 | -------------------------------------------------------------------------------- /requests/use-consistent-path-formats.md: -------------------------------------------------------------------------------- 1 | #### 使用一致的路徑格式 2 | 3 | ##### 資源名稱 4 | 5 | 使用複數版本的資源名稱,除非查詢的資源確定是單數。(舉例而言,多數系統裡使用者只會有一個帳號)。這使你參考其他特定資源時保持行為一致。 6 | 7 | ##### 動作 8 | 9 | 存取一般個別資源時,端點毋需特殊的動作。當需採取特殊動作時,將它擺在標準 `actions` 前綴之後,格式就像: 10 | 11 | ``` 12 | /resources/:resource/actions/:action 13 | ``` 14 | 15 | 實際例子如: 16 | 17 | ``` 18 | /runs/{run_id}/actions/stop 19 | ``` 20 | -------------------------------------------------------------------------------- /responses/README.md: -------------------------------------------------------------------------------- 1 | ### Responses 2 | 3 | * [提供資源的 UUID](provide-resource-uuids.md) 4 | * [提供標準時間戳記](provide-standard-timestamps.md) 5 | * [使用 UTC 時間並以 ISO 8601 格式表達](use-utc-times-formatted-in-iso8601.md) 6 | * [巢狀表示外來鍵關係](nest-foreign-key-relations.md) 7 | * [產生結構化的錯誤訊息](generate-structured-errors.md) 8 | * [顯示次數限制狀態](show-rate-limit-status.md) 9 | * [記得最小化所有回應中的 JSON](keep-json-minified-in-all-responses.md) 10 | -------------------------------------------------------------------------------- /responses/generate-structured-errors.md: -------------------------------------------------------------------------------- 1 | #### 產生結構化的錯誤訊息 2 | 3 | 於回應本體產生一致、結構化的錯誤訊息。包含機器可讀的錯誤 `id`、一般人可讀的錯誤 `message`,還有額外的 `url` 用以指引客戶端更多有關此錯誤的訊息,及如何解決它,例如: 4 | 5 | ``` 6 | HTTP/1.1 429 Too Many Requests 7 | ``` 8 | 9 | ```json 10 | { 11 | "id": "rate_limit", 12 | "message": "Account reached its API rate limit.", 13 | "url": "https://docs.service.com/rate-limits" 14 | } 15 | ``` 16 | 17 | 將錯誤訊息格式及使用者可能碰到的錯誤 `id` 寫成文件。 18 | -------------------------------------------------------------------------------- /responses/keep-json-minified-in-all-responses.md: -------------------------------------------------------------------------------- 1 | #### 保持所有回應中的 JSON 最小化 2 | 3 | 額外的空白增加了無用的回應大小,而許多人用的客戶端會將 JSON 輸出自動排版。所以最好讓 JSON 回應最小化,例如: 4 | 5 | ```json 6 | {"beta":false,"email":"alice@heroku.com","id":"01234567-89ab-cdef-0123-456789abcdef","last_login":"2012-01-01T12:00:00Z","created_at":"2012-01-01T12:00:00Z","updated_at":"2012-01-01T12:00:00Z"} 7 | ``` 8 | 9 | 而非: 10 | 11 | ```json 12 | { 13 | "beta": false, 14 | "email": "alice@heroku.com", 15 | "id": "01234567-89ab-cdef-0123-456789abcdef", 16 | "last_login": "2012-01-01T12:00:00Z", 17 | "created_at": "2012-01-01T12:00:00Z", 18 | "updated_at": "2012-01-01T12:00:00Z" 19 | } 20 | ``` 21 | 22 | 您可考慮讓客戶端額外取得更詳細的回應,透過查詢參數 (如 `?pretty=true`) 或 `Accept` 標頭參數 (如 23 | `Accept: application/vnd.heroku+json; version=3; indent=4;`)。 24 | -------------------------------------------------------------------------------- /responses/nest-foreign-key-relations.md: -------------------------------------------------------------------------------- 1 | #### 巢狀表示外來鍵關係 2 | 3 | 以巢狀結構物件序列化外來鍵,例如: 4 | 5 | ```javascript 6 | { 7 | "name": "service-production", 8 | "owner": { 9 | "id": "5d8201b0..." 10 | }, 11 | // ... 12 | } 13 | ``` 14 | 15 | 而非如此: 16 | 17 | ```javascript 18 | { 19 | "name": "service-production", 20 | "owner_id": "5d8201b0...", 21 | // ... 22 | } 23 | ``` 24 | 25 | 這種方法可記錄更多有關資源關係的訊息,而不用改變回應的結構或帶來更多上層的回應欄位,例如: 26 | 27 | ```javascript 28 | { 29 | "name": "service-production", 30 | "owner": { 31 | "id": "5d8201b0...", 32 | "name": "Alice", 33 | "email": "alice@heroku.com" 34 | }, 35 | // ... 36 | } 37 | ``` 38 | 39 | 而非如此: 40 | 41 | ```javascript 42 | { 43 | "name": "service-production", 44 | "owner_id": "5d8201b0...", 45 | "owner_name": "Alice", 46 | "owner_email": "alice@heroku.com" 47 | // ... 48 | } 49 | ``` -------------------------------------------------------------------------------- /responses/provide-resource-uuids.md: -------------------------------------------------------------------------------- 1 | #### 提供資源的 UUID 2 | 3 | 預設給每個資源 `id` 屬性。若無其他理由,則 UUID。不要使用非全域唯一的 ID, 4 | 且不與其他服務實體或該服務的其他資源衝突,尤其是自動遞增的 ID。 5 | 6 | 以小寫的 `8-4-4-4-12` 格式表示 UUID,例如: 7 | ``` 8 | "id": "01234567-89ab-cdef-0123-456789abcdef" 9 | ``` 10 | -------------------------------------------------------------------------------- /responses/provide-standard-timestamps.md: -------------------------------------------------------------------------------- 1 | #### 提供標準時間戳記 2 | 3 | 預設提供 `created_at` 與 `updated_at` 時間戳記,例如: 4 | 5 | ```javascript 6 | { 7 | // ... 8 | "created_at": "2012-01-01T12:00:00Z", 9 | "updated_at": "2012-01-01T13:00:00Z", 10 | // ... 11 | } 12 | ``` 13 | 14 | 這些時間戳記對某些資源或許無意義,此時可忽略。 15 | 16 | -------------------------------------------------------------------------------- /responses/show-rate-limit-status.md: -------------------------------------------------------------------------------- 1 | #### 顯示次數限制狀態 2 | 3 | 對客戶端限制需求次數可保障服務的健康並維持對其他客戶端好的服務品質。您可採用 [token bucket algorithm](http://en.wikipedia.org/wiki/Token_bucket) 來量化需求限制。 4 | 5 | 於每次 `RateLimit-Remaining` 回應標頭回傳剩餘的需求次數。 -------------------------------------------------------------------------------- /responses/use-utc-times-formatted-in-iso8601.md: -------------------------------------------------------------------------------- 1 | #### 使用 UTC 時間並以 ISO 8601 格式表達 2 | 3 | 只接受或回傳 UTC 時間,並以 ISO 8601 格式表達,例如: 4 | 5 | ``` 6 | "finished_at": "2012-01-01T12:00:00Z" 7 | ``` 8 | --------------------------------------------------------------------------------