對RESTful Web API的理解與設計思路

2021-06-22 19:22:50 字數 3267 閱讀 9209

眾所周知,http有四個方法,get、post、put和delete,分別對應資料庫的select、insert、update和delete,一般的教程說到這裡也就over了,其實光是知道這個還不夠,還不足以把各種業務操作轉變為這四個方法。下面我給出一些設計思路,這是我自行實踐的總結,如有謬誤,請不吝指正:

這麼看來get可是使用相當多的方法。

update一條記錄就抽象成put方法,那這個動作是不是也會用得很多呢?這個比你想像中的少得多,為什麼?因為大量的修改記錄的動作都不只是乙個簡單的update動作,比如使用者要撤銷乙個訂單,這個操作表面上看起來是修改一條訂單記錄的狀態為「撤銷」,但實際上比這個要複雜得多,我們的訂貨是有流程的,使用者撤銷乙個訂單其實只是向我們的伺服器提出了乙個撤銷訂單的請求,讓這個訂單轉入了撤銷流程,而不是簡單地修改訂單記錄的狀態,這裡面有一連串的動作,比如:等待管理員確認,更新應收款資訊,將已出庫的貨物重新入庫,寫操作日誌,傳送系統通知等等,所以這個動作應該是post,而不是put,大多數涉及業務流程的東西都是post,這個我後面會再提到,而put則用於簡單的,不涉及業務流程的資料庫單條記錄update,例如:

表面上看起來對應到資料庫的一次insert,但實際上對比put,post的使用是廣泛很多的,可以說大多數業務操作都會被抽象成post方法,例如:

想想看上述的這些動作往往涉及到資料庫的若干張表的一系列的變化,這個時候就不能簡單地使用put,而是應該使用post,代表「提交了乙個xx的請求」,理解這點很關鍵。

對應sql語句的delete,表示刪除乙個物件,是不是應該使用也很多呢?其實跟put一樣,使用得比你想像的少,因為大多數時候,我們的資料庫所執行的「刪除」都不是簡單的delete,甚至大多數物件,我們都不會提供直接的刪除,例如使用者,為了保證資料的完整性,我們在資料庫中使用了許多的外來鍵約束,要直接delete一條使用者記錄是不會成功的,我們只能「停用」乙個使用者,表示此使用者不再生效。當然了,話不是那麼絕對,如果這是個剛剛增加的使用者並且沒有在其它表中引用到它,那麼確實可以直接把它delete掉,這種情況出現在管理員剛剛新增了乙個使用者,但發現使用者名稱輸錯了,而使用者名稱卻是無法修改的,管理員只能嘗試刪除這個使用者然後重新新增,或者「停用」掉這個錯誤的使用者,只是這麼一來會產生一條完全沒意義的使用者記錄。delete用於你認為需要提供delete方法的場合(很多時候其實不需要,這取決於你的設計),例如:

為了表達得更具體些,我就把上面舉的這些例子轉變為具體化的uri及動作描述:

操作uri

http方法

說明獲取所有員工列表

/api/emp/employees

get按條件分頁查詢某些員工資訊

/api/emp/employees?***=m&page=1&numberperpage=20

get在uri中帶上引數

獲取乙個員工的資訊

/api/emp/employees/58

get58是員工的id,當然你也可以設計成使用者名稱

/api/fileservice/files/2832

get2832是檔案的id,當然你可以設計成檔名或者guid

獲取當前輸入的商品的**

/api/sale/goods/32680

get32680是商品的id

使用者修改自己的個人資訊(假設這個修改動作不需要審批)

/api/admin/users/8642

put8642是使用者的id,另外要帶上修改所需要的各種資訊

使用者編輯了一張暫存(未轉入執行流程)的訂單

/api/sale/orders/234892

put234892是訂單的id,另外要帶上修改訂單所需的各種資訊

新增乙個使用者

/api/admin/users

post

帶上新增使用者所需要的資訊

提交乙個訂單

/api/sale/orders

post

帶上訂單完整資訊

付款/api/sale/pay

post

付款完整資訊,將包含要支付的訂單的id等資訊

給員工發放工資

/api/emp/paysalary

post

帶上發放工資的完整資訊,將包括員工id,發放工資的月份和金額等

提交乙個基礎資料的修改申請(需要審批)

/api/basic/modifymanufacture

post

帶上要修改的物件的完整資訊,包括id等

啟用乙個產品

/api/sale/activateproduct

post

帶上要啟用的產品的相關資訊,包括id等

駁回乙個員工的申請

post

帶上申請id、駁回原因等

刪除乙個使用者(很可能執行失敗)

/api/admin/users/567

delete

567為要刪除的使用者的id

刪除一條暫存的訂單(此訂單尚未轉入處理流程)

/api/sale/orders/234892

delete

234892為訂單id

刪除一條系統訊息

/api/sys/messages/1008689021

delete

1008689021為系統訊息的id

uri中的「api」是固定的,用於區別於普通的網頁的uri,接下去的「emp」、「fileservice」、「sale」、「admin」、「basic」和「sys」等可看作是分類,例如「給員工發放工資」和「員工資訊」這兩個「資源」都是放在「emp」這個分類中的,剩餘的部分是物件名稱,或稱資源名稱,其實準確地說,完整的uri位址才是真正的資源名稱,為什麼叫資源?google一下restful web api,看看restful的「r」就理解了,簡單地說,我們把各種操作都最終抽象為資源,一切業務操作(不管多複雜)都轉變為對某個資源的增刪查改,也就是上面提到的四個http的方法。

get、put和delete方法都比較顯而易見,好理解,大多數時候,這幾個方法的資源都確確實實對應著資料庫的某張表或某條記錄,例如「/api/admin/users」可能對應著資料庫中的admin_user表,而「/api/admin/users/8642」則對應著admin_user表中的id為8642的這條使用者記錄。

post方法則不是那麼直截了當,例如「/api/emp/paysalary」,也許資料庫中根本就沒有乙個直接與之一一對應的表,paysalary是乙個抽象的業務操作物件,往這個物件執行一下post就相當於給某個員工發放了一次工資,其實際的動作可能涉及到多張表的聯動,如員工表的工資發放標誌、工資發放記錄表插入一條記錄,公司財務表插入一條記錄,操作日誌表插入一條記錄,系統訊息表插入一條記錄等……

這就是我對web api的設計的理解,大家看看有什麼問題?

如何實現RESTful Web API的身份驗證

最近想拿乙個小專案來試水restful web api,專案只有幾個呼叫,比較簡單,但同樣需要身份驗證,如果是傳統的 的話,那不用說,肯定是使用者名稱 密碼在登入頁獲得登入token,並把登入token記在cookie和session中作為身份標識的這種方式,但現在不同了,關鍵是restful,這意...

如何實現RESTful Web API的身份驗證

最近想拿乙個小專案來試水restful web api,專案只有幾個呼叫,比較簡單,但同樣需要身份驗證,如果是傳統的 的話,那不用說,肯定是使用者名稱 密碼在登入頁獲得登入token,並把登入token記在cookie和session中作為身份標識的這種方式,但現在不同了,關鍵是restful,這意...

php對mysql的了解 對MySQL的初步了解

首先安裝mysql 一.單詞部分 networking網路 option選擇 port埠 firewall防火牆 engine引擎 standard標準 character字元 collation校對 stirage儲存 二.預習部分 1.請寫出建立和刪除資料庫的sql語句 create datab...