一個go的API架構
來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。# goweb一個基於go語言開發API的工具,這個工具受到了SpringMVC的啟發,結合了go語言本身的特性,整體比較簡單,接下來,看看如何使用它。下載安裝:```go get github.com/alberliu/goweb```### 1.核心功能#### 請求體參數注入```gopackage mainimport "github.com/alberliu/goweb"type User struct {Id int `json:"id"`Name string `json:"name"`}func handler(user User) User {return user}func main() {goweb.HandlePost("/test", handler)goweb.ListenAndServe(":8000")}```請求體:```json{ "id": 1, "name": "alber"}```響應體:```json{ "id": 1, "name": "alber"}```上面的代碼是一個最簡的例子,HandlePost(string, interface{})會將一個handler註冊到一個全域的內建的goweb執行個體defultGoWeb,ListenAndServe(":8000")會將defultGoWeb賦給Server的handler變數,然後啟動這個Server。(是不是和內建的ServerMux有點像)goweb會自動解析註冊到它本身的handler,當請求到來時,會將請求體的json資料還原序列化並注入到handler的參數,handler處理完邏輯返回時,會將handler的傳回值序列化為json資料返回。goweb預設使用json的序列化和還原序列化方式,當然你可以定義自己的序列化方式,這個在後面你可以看到。例子給出的handler的參數和返回都是結構體類型,當然你也可以使用指標類型。結構體goweb其實本質上就是一個路由,它實現了Handler介面。上面的例子都是預設的defultGoWeb,你也可以自己執行個體化一個goweb。```gofunc main() {goweb:=goweb.NewGoWeb();goweb.HandlePost("/test", handler)server := &http.Server{Addr: ":8000", Handler: goweb}server.ListenAndServe()}```#### url參數注入```gopackage mainimport "github.com/alberliu/goweb"type User struct {Id int64 `json:"id"`Name string `json:"name"`}func handler(id int64, name string) User {return User{id, name}}func main() {goweb := goweb.NewGoWeb();goweb.HandleGet("/test/{id}/{name}", handler)goweb.ListenAndServe(":8000")}```執行上面的代碼,然後訪問url:http://localhost:8000/test/123456/alber就可以返回下面的json資料```json{ "id": 123456, "name": "alber"}```handler可以擷取到url中的參數,並且注入到handler參數中。handler的第一個參數對應url中的第一個參數,第二個參數對應url中的的第二個參數,依次類推。不過暫時還有個限制,在url中使用參數時,handler中的參數必須與url中的參數個數一致,且類型必須為string或者int64。### 2.handlergoweb可以註冊多種形式的handler,goweb會利用反射自動解析函數,支援多種類型,但是不能超出它可以解析的範圍。以下是它所有能解析的類型。```gofunc handler(ctx goweb.Context) {}func handler(ctx goweb.Context) User {return User{}}func handler(user User) User {return User{}}func handler(ctx goweb.Context, user User) User {return User{}}func handler(name string, id int64) User {return User{}}func handler(ctx goweb.Context, name string, id int64) User {return User{}}```Context是一個請求上下文,他只有ResponseWriter和Request兩個欄位,它的內部結構如下所示。你可以根據自己的需求修改源碼進行擴充,例如,把它作為一個請求的會話使用。```gotype Context struct {w http.ResponseWriterr *http.Request}```### 3.用Group組織你的handler```gofunc main() {group1:=goweb.NewGroup("/group1")group1.HandleGet("/handler1",handler)group1.HandleGet("/handler2",handler)group1.HandleGet("/handler3",handler)group2:=goweb.NewGroup("/group2")group2.HandleGet("/handler1",handler)group2.HandleGet("/handler2",handler)group2.HandleGet("/handler3",handler)group3:=goweb.NewGroup("/group3")group3.HandleGet("/handler1",handler)group3.HandleGet("/handler2",handler)group3.HandleGet("/handler3",handler)goweb.HandleGroup(group1)goweb.HandleGroup(group2)goweb.HandleGroup(group3)goweb.ListenAndServe(":8000")}```group可以協助你分層次的組織你的handler,使你的路由結構更清晰。### 4.定義自己序列化和反序列話方式```govar json = jsoniter.ConfigCompatibleWithStandardLibraryfunc jsonUnmarshal(data []byte, v interface{}) error {return json.Unmarshal(data, v)}func jsonMarshal(v interface{}) ([]byte, error){return json.Marshal(v)}func main() {goweb:=goweb.NewGoWeb();goweb.Unmarshal=jsonUnmarshalgoweb.Marshal=jsonMarshalgoweb.ListenAndServe(":8000")}```goweb預設採用json(使用的是開源的jsoniter)序列化和還原序列化資料,goweb的Marshal、Unmarshal變數本身是一個函數.如果你想定義自己的序列化方式,只需要覆蓋掉它就行,就像上面那樣。### 5.攔截器```gofunc interceptor1(http.ResponseWriter, *http.Request) bool {return true}func interceptor2(http.ResponseWriter, *http.Request) bool {return true}func interceptor3(http.ResponseWriter, *http.Request) bool {return true}func main() {goweb := goweb.NewGoWeb();goweb.AddInterceptor(interceptor1)goweb.AddInterceptor(interceptor2)goweb.AddInterceptor(interceptor3)goweb.ListenAndServe(":8000")}```goweb在執行handler之前,會執行一個或者多個interceptor,並且會根據AddInterceptor的先後順序執行,當interceptor返回true時,會接著往下執行,返回false時,會終止執行。### 6.過濾器```gofunc filter(w http.ResponseWriter, r *http.Request, f func(http.ResponseWriter, *http.Request)) {f(w, r)}func main() {goweb := goweb.NewGoWeb();goweb.Filter = filtergoweb.ListenAndServe(":8000")}```你可以給goweb添加一個過略器,在過濾器中,如果你想執行完自己的邏輯之後,執行handler,只需要調用f(w, r)。### 7.自訂錯誤處理```gofunc handler400(w http.ResponseWriter, r *http.Request) {w.WriteHeader(400)w.Write([]byte("bad request"))}func handler404(w http.ResponseWriter, r *http.Request) {w.WriteHeader(404)w.Write([]byte("url not found"))}func handler405(w http.ResponseWriter, r *http.Request) {w.WriteHeader(405)w.Write([]byte("method not found"))}func main() {goWeb := goweb.NewGoWeb()goWeb.Handler400 = handler400goWeb.Handler404 = handler404goWeb.Handler405 = handler405goweb.ListenAndServe(":8000")}```當請求執行失敗時,goweb中給出了一些預設的錯誤處理方式,就像上面那樣。當然,你也可以定義一些自己錯誤處理方式。### 寫在後面如果你有什麼好的建議,可以發我郵箱,一起交流。alber_liu@qq.com1199 次點擊