goweb
一個(gè)基于go語言開發(fā)API的工具枫吧,這個(gè)工具受到了SpringMVC的啟發(fā),結(jié)合了go語言本身的特性张症,整體比較簡(jiǎn)單,接下來鸵贬,看看如何使用它俗他。
下載安裝:
go get github.com/alberliu/goweb
1.核心功能
請(qǐng)求體參數(shù)注入
package main
import "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")
}
請(qǐng)求體:
{
"id": 1,
"name": "alber"
}
響應(yīng)體:
{
"id": 1,
"name": "alber"
}
上面的代碼是一個(gè)最簡(jiǎn)的例子,HandlePost(string, interface{})會(huì)將一個(gè)handler注冊(cè)到一個(gè)全局的內(nèi)置的goweb實(shí)例defultGoWeb阔逼,ListenAndServe(":8000")會(huì)將defultGoWeb賦給Server的handler變量兆衅,然后啟動(dòng)這個(gè)Server。(是不是和內(nèi)置的ServerMux有點(diǎn)像)
goweb會(huì)自動(dòng)解析注冊(cè)到它本身的handler,當(dāng)請(qǐng)求到來時(shí)嗜浮,會(huì)將請(qǐng)求體的json數(shù)據(jù)反序列化并注入到handler的參數(shù)羡亩,handler處理完邏輯返回時(shí),會(huì)將handler的返回值序列化為json數(shù)據(jù)返回危融。goweb默認(rèn)使用json的序列化和反序列化方式畏铆,當(dāng)然你可以定義自己的序列化方式,這個(gè)在后面你可以看到吉殃。
例子給出的handler的參數(shù)和返回都是結(jié)構(gòu)體類型及志,當(dāng)然你也可以使用指針類型片排。
結(jié)構(gòu)體goweb其實(shí)本質(zhì)上就是一個(gè)路由,它實(shí)現(xiàn)了Handler接口速侈。上面的例子都是默認(rèn)的defultGoWeb率寡,你也可以自己實(shí)例化一個(gè)goweb。
func main() {
goweb:=goweb.NewGoWeb();
goweb.HandlePost("/test", handler)
server := &http.Server{Addr: ":8000", Handler: goweb}
server.ListenAndServe()
}
url參數(shù)注入
package main
import "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")
}
執(zhí)行上面的代碼倚搬,然后訪問url:http://localhost:8000/test/123456/alber
就可以返回下面的json數(shù)據(jù)
{
"id": 123456,
"name": "alber"
}
handler可以獲取到url中的參數(shù)冶共,并且注入到handler參數(shù)中。handler的第一個(gè)參數(shù)對(duì)應(yīng)url中的第一個(gè)參數(shù)每界,第二個(gè)參數(shù)對(duì)應(yīng)url中的的第二個(gè)參數(shù)捅僵,依次類推。不過暫時(shí)還有個(gè)限制眨层,在url中使用參數(shù)時(shí)庙楚,handler中的參數(shù)必須與url中的參數(shù)個(gè)數(shù)一致,且類型必須為string或者int64趴樱。
2.handler
goweb可以注冊(cè)多種形式的handler馒闷,goweb會(huì)利用反射自動(dòng)解析函數(shù),支持多種類型叁征,但是不能超出它可以解析的范圍纳账。以下是它所有能解析的類型。
func 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是一個(gè)請(qǐng)求上下文捺疼,他只有ResponseWriter和Request兩個(gè)字段疏虫,它的內(nèi)部結(jié)構(gòu)如下所示。你可以根據(jù)自己的需求修改源碼進(jìn)行擴(kuò)展啤呼,例如卧秘,把它作為一個(gè)請(qǐng)求的會(huì)話使用。
type Context struct {
w http.ResponseWriter
r *http.Request
}
3.用Group組織你的handler
func 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,使你的路由結(jié)構(gòu)更清晰官扣。
4.定義自己序列化和反序列化方式
var json = jsoniter.ConfigCompatibleWithStandardLibrary
func 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=jsonUnmarshal
goweb.Marshal=jsonMarshal
goweb.ListenAndServe(":8000")
}
goweb默認(rèn)采用json(使用的是開源的jsoniter)序列化和反序列化數(shù)據(jù)翅敌,goweb的Marshal、Unmarshal變量本身是一個(gè)函數(shù).如果你想定義自己的序列化方式醇锚,只需要覆蓋掉它就行,就像上面那樣坯临。
5.攔截器
func 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在執(zhí)行handler之前焊唬,會(huì)執(zhí)行一個(gè)或者多個(gè)interceptor,并且會(huì)根據(jù)AddInterceptor的先后順序執(zhí)行看靠,當(dāng)interceptor返回true時(shí)赶促,會(huì)接著往下執(zhí)行,返回false時(shí)挟炬,會(huì)終止執(zhí)行鸥滨。
6.過濾器
func filter(w http.ResponseWriter, r *http.Request, f func(http.ResponseWriter, *http.Request)) {
f(w, r)
}
func main() {
goweb := goweb.NewGoWeb();
goweb.Filter = filter
goweb.ListenAndServe(":8000")
}
你可以給goweb添加一個(gè)過略器嗦哆,在過濾器中,如果你想執(zhí)行完自己的邏輯之后婿滓,執(zhí)行handler老速,只需要調(diào)用f(w, r)。
7.自定義錯(cuò)誤處理
func 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 = handler400
goWeb.Handler404 = handler404
goWeb.Handler405 = handler405
goweb.ListenAndServe(":8000")
}
當(dāng)請(qǐng)求執(zhí)行失敗時(shí)凸主,goweb中給出了一些默認(rèn)的錯(cuò)誤處理方式橘券,就像上面那樣。當(dāng)然卿吐,你也可以定義一些自己錯(cuò)誤處理方式旁舰。
寫在后面
如果你有什么好的建議,可以發(fā)我郵箱嗡官,一起交流箭窜。