框架的意義在於,封裝大部分手工操作的功能,提公升開發效率。
gee框架模仿gin,於是我們整體構造乙個web引擎類engine。如果直接使用基礎庫http,啟動整個web應用依賴以下**:
使用engine進行封裝:
func (engine *engine) run(addr string) error
於是engine自然要實現handler介面的servehttp方法。
當乙個web請求到達時,我們至少要考慮並完成以下動作:
獲取請求的引數,進行儲存。
找尋路由對應的方法,進行呼叫。
如果有路由分組,考慮鏈式呼叫下的中介軟體。
動態路由的對映(可選)。
由於要暫時儲存引數和中介軟體方法,所以我們構造唯一的context進行狀態管理。
}首先基於當前request和response構造context,然後去遍歷分組列表,簡單根據字首獲取當前請求對應分組,將對應的中介軟體加入進來。之後交給engine的router模組處理請求。注意,此時引數以封裝為context,我們所有關於本次請求的資訊都能在context中找到。
這裡分組的思想依然模仿gin,根據group的prefix和parent實現分元件的父子關係,每個group都會維護自身的中介軟體切片。
func (group *routergroup) group(prefix string) *routergroup
return newgroup
}func (group *routergroup) use(handlers ...handlefunc)
func new() *engine
engine.routergroup = &routergroup
//這裡會有預設載入的中介軟體
engine.groups = *routergroup
return engine
}
我們規定,engine本身就是預設的特殊group,因為框架可能不需要分組就能新增路由對映,或是定義於引擎全域性的中介軟體,例如日誌和錯誤回覆。當然,它還要同時維護router物件和分組切片。
起碼在呼叫handle方法時,能根據字串位址查詢到對應方法呼叫,同樣實現動態路由我們採用了字首樹的資料結構,所以需要維護兩個map。
type handlefunc func(context *context)
type router struct
我們實現的動態路由滿足兩個功能,引數匹配和通配*。資料結構如下:
我們註冊路由時需要新增方法對映,新增字首樹節點。查詢路由時需要查詢字首樹進行引數匹配,根據對映查詢方法。所以字首樹trie只對外提供search和insert方法即可。(有關字首樹方法自行前往官網或其他路徑學習)。
引數匹配後新增路由對應方法就可以開始呼叫。
func (r *router) handle(ctx *context) else )
} ctx.next()
}
func recovery() handlefunc
}()context.next()
}}
通過主動呼叫next方法,此時的中介軟體成為了父函式,子函式呼叫後返回當然能繼續邏輯處理,也能實現錯誤恢復。
補充:註冊路由功能是由分組去呼叫get,post方法完成,最終是呼叫engine的router模組方法。實現靜態檔案服務也很簡單,首先借助字首路由樹完成檔案路徑獲取,最終通過fileserver的servehttp方法完成檔案請求。
虹貓藍兔七俠傳 衝刺第五天
1.進度 曹泳 完成任務 優化歷史訂單業務邏輯 花費時間 4小時剩餘時間 2天遇到問題 因為歷史訂單的後端業務邏輯對資料庫有多次請求,所以每次跳轉歷史訂單頁面,需要重新整理很長時間,對使用者體驗極不友好 解決問題 1.重新優化前端業務邏輯 2.將獲取的歷史訂單資料存入本地儲存 明天計畫 對使用者端進...
虹貓藍兔七俠傳 衝刺第二天
1.進度 曹泳 完成任務 完成位址列表的資料儲存與修改 花費時間 8小時剩餘時間 5天遇到問題 預設位址的無法正常修改與更新 解決問題 1.優化靜態頁面,拿出乙個單獨的模組顯示預設位址 2.在跳轉修改位址頁面 的時候傳遞乙個引數 該訂單的唯一標識 id 3.對資料庫操作時,使用doc id 方法直接...
跟siki老師學C 第七天
今天我們要學習的內容是函式,也叫做方法。什麼叫方法?就是我們為了達到某個目的或者實現某項功能而設定的一系列步驟。為什麼要使用方法呢?我們在之前編寫的控制台應用程式都是寫在main 方法中的,在控制台應用程式中,程式的執行是以main 方法為程式入口的,也就是說無論你main 方法寫在 只要你執行這個...