API 就是開發者使用的界面。個人目標不只是能用,並且好用,跨平臺(PC, Android, IOS, etc...)使用。本文將詳細介紹 API 的設計及異常處理,並將異常信息進行封裝友好地反饋給前端.前端
上篇文章 先後端徹底分離初探 只是講了些寬泛的概念,接下來的文章將直接上乾貨,乾貨的源碼會掛在 GitHub 上。git
先後端徹底分離後,前端和後端如何交互?答:經過雙方協商好的API。github
接下來我分享我本身設計的 API 接口,歡迎各位朋友指教。json
將涉及的實體抽象成資源,即按 id
訪問資源,在 url
上作文章,之後不再用爲 url
起名字而苦惱了;segmentfault
使用 HTTP
動詞對資源進行 CRUD
(增刪改查):後端
get -> 查, post -> 增, put -> 改, delete -> 刪
URL 命名規則,對於資源沒法使用一個單數名詞表示的狀況,我使用中橫線 -
鏈接api
資源採用名詞命名,e.g:產品 -> product
安全
新增資源,e.g:新增產品 url -> /product, verb -> POST
分佈式
修改資源,e.g:修改產品 url -> /products/{id}, verb -> PUT
模塊化
資源詳情,e.g:指定產品詳情 url -> /products/{id}, verb -> GET
刪除資源,e.g:刪除產品 url -> /products/{id}, verb -> DELETE
資源列表,e.g:產品列表 url -> /products, verb -> GET
資源關聯關係,e.g:收藏產品 url -> /products/{id}/star, verb -> PUT
資源關聯關係,e.g:刪除收藏產品 url -> /products/{id}/star, verb -> DELETE
目前我 API 的設計只涉及這兩點,至於第三點 HATEOAS
(Hypermedia As The Engine Of Application State) 那就由讀者本身去選擇了,
<!--more-->
本文中只涉及了設計的理念,具體的實現請下載源碼 rest-api,項目內寫了比較詳細的註釋。
實戰將從業務場景出發,詳細介紹如何使用 HTTP verb 對資源進行操做(狀態轉移),使用 JSON 返回結果(資源表述),並定義 JSON 的基礎結構。
requestParams:
{ }
responseBody:
{ "meta": { }, "data": { } }
meta
中封裝操做成功或失敗的消息,data
中封裝返回的具體數據。
當新建商品或更新產品時,相關屬性封裝在 JSON 中,經過 POST 或 PUT 發送。
{ "name": "Apple Watch SPORT", "description": "Sport 系列的錶殼材料爲輕巧的銀色及深空灰色陽極氧化鋁金屬,強化 Ion-X 玻璃材質爲顯示屏提供保護。搭配高性能 Fluoroelastomer 錶帶,共有 5 款繽紛色彩。" }
當用戶對商品進行操做後,將獲得響應結果。GET, POST, PUT 操做成功,返回以下結果
{ "meta": { "code": 201, "message": "建立成功" }, "data": { "id": "5308e9c2-a4ce-4dca-9373-cc1ffe63d5f9", "name": "Apple Watch SPORT", "description": "Sport 系列的錶殼材料爲輕巧的銀色及深空灰色陽極氧化鋁金屬,強化 Ion-X 玻璃材質爲顯示屏提供保護。搭配高性能 Fluoroelastomer 錶帶,共有 5 款繽紛色彩。" } }
DELETE 操做成功,返回以下結果
{ "meta": { "code": 204, "message": "刪除成功" } }
電商網站的管理員對商品進行新增、編輯、刪除、瀏覽的操做,暫時不考慮認證受權,只關注對商品的操做。
爲了之後便於作分佈式,全部資源 id(表主鍵)均採用 uuid。
url: /api/product
method: POST
requestParams:
{ "name": "Apple Watch SPORT", "description": "Sport 系列的錶殼材料爲輕巧的銀色及深空灰色陽極氧化鋁金屬,強化 Ion-X 玻璃材質爲顯示屏提供保護。搭配高性能 Fluoroelastomer 錶帶,共有 5 款繽紛色彩。" }
responseBody
{ "meta": { "code": 201, "message": "建立成功" }, "data": { "id": "5308e9c2-a4ce-4dca-9373-cc1ffe63d5f9", "name": "Apple Watch SPORT", "description": "Sport 系列的錶殼材料爲輕巧的銀色及深空灰色陽極氧化鋁金屬,強化 Ion-X 玻璃材質爲顯示屏提供保護。搭配高性能 Fluoroelastomer 錶帶,共有 5 款繽紛色彩。" } }
url: /api/products/{id}
method: PUT
requestParams:
{ "name": "iPhone 6", "description": "這次蘋果發佈會發佈了iPhone 6與iPhone 6 Plus,搭載iOS 8,尺寸分別是4.7和5.5英寸。外觀設計再也不棱角分明,表層玻璃邊有一個弧度向下延伸,與陽極氧化鋁金屬機身邊框銜接。機身背部採用三段式設計。機身更薄,續航能力更強。" }
responseBody
{ "meta": { "code": 200, "message": "修改爲功" }, "data": { "id": "5308e9c2-a4ce-4dca-9373-cc1ffe63d5f9", "name": "iPhone 6", "description": "這次蘋果發佈會發佈了iPhone 6與iPhone 6 Plus,搭載iOS 8,尺寸分別是4.7和5.5英寸。外觀設計再也不棱角分明,表層玻璃邊有一個弧度向下延伸,與陽極氧化鋁金屬機身邊框銜接。機身背部採用三段式設計。機身更薄,續航能力更強。" } }
url: /api/products/{id}
method: DELETE
responseBody
{ "meta": { "code": 204, "message": "刪除成功" }, "data": {} }
url: /api/products/{id}
method: GET
responseBody:
//刪除前 { "meta": { "code": 200, "message": "查詢成功" }, "data": { "id": "5308e9c2-a4ce-4dca-9373-cc1ffe63d5f9", "name": "Apple Watch SPORT", "description": "Sport 系列的錶殼材料爲輕巧的銀色及深空灰色陽極氧化鋁金屬,強化 Ion-X 玻璃材質爲顯示屏提供保護。搭配高性能 Fluoroelastomer 錶帶,共有 5 款繽紛色彩。" } }
//刪除後 { "meta": { "code": 404, "message": "指定產品不存在" } }
url: /api/products
method: GET
responseBody
{ "meta": { "code": 200, "message": "獲取所有商品成功" }, "data": [ { "id": "5308e9c2-a4ce-4dca-9373-cc1ffe63d5f9", "name": "Apple Watch SPORT", "description": "Sport 系列的錶殼材料爲輕巧的銀色及深空灰色陽極氧化鋁金屬,強化 Ion-X 玻璃材質爲顯示屏提供保護。搭配高性能 Fluoroelastomer 錶帶,共有 5 款繽紛色彩。" }, { "id": "9db1992a-c342-4ff0-a2a4-aeb3dbfd93f6", "name": "Apple Watch SPORT", "description": "Sport 系列的錶殼材料爲輕巧的銀色及深空灰色陽極氧化鋁金屬,強化 Ion-X 玻璃材質爲顯示屏提供保護。搭配高性能 Fluoroelastomer 錶帶,共有 5 款繽紛色彩。" }, { "id": "4481619b-45c5-4729-9539-f93bb01f10d8", "name": "Apple Watch SPORT", "description": "Sport 系列的錶殼材料爲輕巧的銀色及深空灰色陽極氧化鋁金屬,強化 Ion-X 玻璃材質爲顯示屏提供保護。搭配高性能 Fluoroelastomer 錶帶,共有 5 款繽紛色彩。" } ] }
業務場景一中只涉及了單個資源的操做,但實際場景中還有些關聯操做;如用戶去電商網站瀏覽商品,並收藏了一些商品,以後又取消收藏了部分商品。
暫時不考慮用戶認證受權,之後加了token
後,用戶信息能夠從中獲取。
url: /api/products/{id}/star
method: PUT
responseBody
{ "meta": { "code": 200, "message": "收藏商品[5308e9c2-a4ce-4dca-9373-cc1ffe63d5f9]成功" }, "data": [ { "id": "5308e9c2-a4ce-4dca-9373-cc1ffe63d5f9", "name": "iPhone 6", "description": "這次蘋果發佈會發佈了iPhone 6與iPhone 6 Plus,搭載iOS 8,尺寸分別是4.7和5.5英寸。外觀設計再也不棱角分明,表層玻璃邊有一個弧度向下延伸,與陽極氧化鋁金屬機身邊框銜接。機身背部採用三段式設計。機身更薄,續航能力更強。" } ] }
url: /api/products/{id}/star
method: DELETE
responseBody
{ "meta": { "code": 200, "message": "刪除收藏商品[5308e9c2-a4ce-4dca-9373-cc1ffe63d5f9]成功" }, "data": [] }
全部自定義異常繼承 RuntimeException,在業務層拋出,統一在 Controller 層進行處理。
異常分爲全局異常和局部異常,例如 http method unsupported (405),unauthorized (401),accessDenied (403),not found (404) 等屬於全局異常。針對對獨立業務的一些異常屬於局部異常,例如產品編輯出錯。
異常在 Controller 中進行處理,並封裝成 json 返回給前端,封裝後的數據以下,相關實現見源碼
{ "meta": { "code": 404, "message": "指定產品不存在" } }
{ "meta": { "code": 405, "message": "Request method 'POST' not supported" } }
先後端徹底分離之安全認證與受權-上
先後端徹底分離之安全認證與受權-下
先後端徹底分離以前端模塊化開發
先後端徹底分離以前端路由系統
先後端徹底分離以後端面向服務的模塊化開發
原文出自 先後端徹底分離之API設計,歡迎轉載,轉載請註明出處。