Web API 處理機制剖析 --- 撥開迷霧看本質
前言 最近開發了幾個專案,用到了web api,也通過專案加深了對web api的理解。本文試圖從內部原理講解web api的本質。透過重重迷霧,看清本質,就能更好的把握和利用好web api。
1 Web API 的本質
1.1 互動說明
Web API 是基於http傳輸協議的函式呼叫。http是應用最廣泛的傳輸協議,web服務端就實現了http伺服器。由於web的流行,也帶動了web伺服器的完善和優化。web伺服器的功能也不僅限於傳輸html文字,任何資料都可以通過文字傳輸(其實,圖片,視訊也可以通過變通的方式實現傳輸)。函式的呼叫就是傳送資料和接收資料的過程;既然http也能傳送和接收資料,當然也可以通過http實現函式呼叫,這就是web api。
http是傳輸協議,並不解釋傳輸的內容。http協議同時也定義了一些標準的術語,方便客戶端和服務端互動。一個典型的http傳送和響應資料如下:
---->request
Request URL: https://www.baidu.com/ Request Method: GET Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Connection: keep-alive Cookie: BAIDUID=43E2CBB543131B011BC1861E7CDD83DB:FG=1 Host: www.baidu.com Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36 body data
<----reponse
Status Code: 200 OK Remote Address: 111.13.100.91:443 Referrer Policy: no-referrer-when-downgrade Bdpagetype: 1 Bdqid: 0xecff8dba0009a0bc Cache-Control: private Connection: Keep-Alive Content-Type: text/html Cxy_all: baidu+5bd9cbe0adf9080de3f7682cf8f45af1 Date: Fri, 19 Apr 2019 13:44:36 GMT Expires: Fri, 19 Apr 2019 13:44:05 GMT Server: BWS/1.1 Set-Cookie: BIDUPSID=43E2CBB543131B011BC1861E7CDD83DB; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com Set-Cookie: PSTM=1555681476; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com body data
http分為包頭和包體,包頭包含一些關鍵欄位,如Accept,Cookie,這些是http的保留字。你也可以通過包頭傳輸資料,只要不使用保留字就行。如:
myguid: 6F9619FF-8B86-D011-B42D-00C04FC964FF
通常包頭傳輸一組函式公用的資料,比如有10個函式,這些函式都用到guid,可以把guid放入包頭。
1.2 包體資料說明
http請求(request)資料:
a)對於瀏覽器的表單,包體資料格式如下:
key1=value1&key2=value2
就是key,value對,通過&號分割。key,value也可以是漢字,會做轉義處理。這些細節不需要我們處理。只需要知道key、value可以是任何字元就行。
b)json和其他資料格式
對於web api,包體資料可以是json格式。當然不限於json,可以是任意形式的資料,只要雙方對處理協議達成一致就行。
{ "sites": [ { "name":"菜鳥教程" , "url":"www.runoob.com" }, { "name":"google" , "url":"www.google.com" }, { "name":"微博" , "url":"www.weibo.com" } ] }
傳輸複雜的資料建議使用json,json函式可以把複雜的類變數序列化;對方反序列化,就可以得到一個類變數。這樣,遠端函式呼叫與本地呼叫區別就很小;僅僅多一層json序列化。
2 asp.net 對web API的實現
常言:巧婦難為無米之炊。對於web api,http承載的資料就是米,asp.net框架就是巧婦。web api的本質就是資料的傳送和接收,asp.net 能做的的就是方便你的接收和返回。asp.net這裡是好心幫程式設計師減輕負擔,但這種好心也有副作用:很難探究web api的本質,遇到問題難以從本質上去分析解決。
2.1 資料如何變成函式引數
我們一般不處理http原始資料,這些資料一般會對映為函式引數。這種對映關係多種多樣,見下圖:
asp.net做這種對映處理就是為了減輕開發人員的負擔,但是開發人員必須瞭解這些對映關係。不同框架處理這種對映邏輯也是不一樣的,其實,開發人員可以定製自己的對映邏輯;但是好像沒必要這樣做,直接處理http資料,就是從asp.net request變數抽取http資料再處理,也增加不了多少工作量;這樣反而使開發人員對底層資料瞭解更加透徹。
2.2 asp.net 客戶端呼叫舉例
使用類WebClient做為示例:
//客戶端呼叫 void clientPost() { using (var client = new System.Net.WebClient()) { var postParam = new NameValueCollection(); //傳遞引數 postParam.Add("code", "123"); postParam.Add("name", "tom); //http body部分就變為 code=123&name=tom var responsebytes = client.UploadValues(uri, postParam); string strResult = System.Text.Encoding.UTF8.GetString(responsebytes); } } //服務端: string ServerDeal(string code, string name) { //http body資料部分對映為引數:code為123,name為tom return "ok"; }
NameValueCollection類將資料組成key、value對,並處理字元轉義。通過上面的程式碼可以看出,web api呼叫其實很簡單,框架幫我們做了資料對映,字元轉義等常規操作,讓我從繁雜的瑣事中脫身,專注處理業務邏輯。
後記:對事物的瞭解要抓住本質,只要瞭解了本質,就一通百通。web api原理並不繁雜,但是由於上層的封裝,使我們很難了解到底層處理原理,導致很難抓住事物的本質。本文通過自身的領悟,試圖剖析其本質,希望對讀者有所裨益!