github.com/zhongdalu/gf@v1.0.0/g/net/ghttp/ghttp_server_router_group.go (about) 1 // Copyright 2018 gf Author(https://github.com/zhongdalu/gf). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/zhongdalu/gf. 6 // 分组路由管理. 7 8 package ghttp 9 10 import ( 11 "reflect" 12 "strings" 13 14 "github.com/zhongdalu/gf/g/os/glog" 15 "github.com/zhongdalu/gf/g/util/gconv" 16 ) 17 18 // 分组路由对象 19 type RouterGroup struct { 20 server *Server // Server 21 domain *Domain // Domain 22 prefix string // URI前缀 23 } 24 25 // 分组路由批量绑定项 26 type GroupItem = []interface{} 27 28 // 获取分组路由对象 29 func (s *Server) Group(prefix ...string) *RouterGroup { 30 group := &RouterGroup{ 31 server: s, 32 } 33 if len(prefix) > 0 { 34 group.prefix = prefix[0] 35 } 36 return group 37 } 38 39 // 获取分组路由对象 40 func (d *Domain) Group(prefix ...string) *RouterGroup { 41 if len(prefix) > 0 { 42 return &RouterGroup{ 43 domain: d, 44 prefix: prefix[0], 45 } 46 } 47 return &RouterGroup{} 48 } 49 50 // 执行分组路由批量绑定 51 func (g *RouterGroup) Bind(items []GroupItem) { 52 for _, item := range items { 53 if len(item) < 3 { 54 glog.Fatalf("invalid router item: %s", item) 55 } 56 if strings.EqualFold(gconv.String(item[0]), "REST") { 57 g.bind("REST", gconv.String(item[0])+":"+gconv.String(item[1]), item[2]) 58 } else { 59 method := gconv.String(item[0]) 60 if strings.EqualFold(method, "ALL") { 61 method = "" 62 } else { 63 method += ":" 64 } 65 if len(item) > 3 { 66 g.bind("HANDLER", method+gconv.String(item[1]), item[2], item[3]) 67 } else { 68 g.bind("HANDLER", method+gconv.String(item[1]), item[2]) 69 } 70 } 71 } 72 } 73 74 // 绑定所有的HTTP Method请求方式 75 func (g *RouterGroup) ALL(pattern string, object interface{}, params ...interface{}) { 76 g.bind("HANDLER", gDEFAULT_METHOD+":"+pattern, object, params...) 77 } 78 79 // 绑定常用方法: GET/PUT/POST/DELETE 80 func (g *RouterGroup) COMMON(pattern string, object interface{}, params ...interface{}) { 81 g.GET(pattern, object, params...) 82 g.PUT(pattern, object, params...) 83 g.POST(pattern, object, params...) 84 g.DELETE(pattern, object, params...) 85 } 86 87 func (g *RouterGroup) GET(pattern string, object interface{}, params ...interface{}) { 88 g.bind("HANDLER", "GET:"+pattern, object, params...) 89 } 90 91 func (g *RouterGroup) PUT(pattern string, object interface{}, params ...interface{}) { 92 g.bind("HANDLER", "PUT:"+pattern, object, params...) 93 } 94 95 func (g *RouterGroup) POST(pattern string, object interface{}, params ...interface{}) { 96 g.bind("HANDLER", "POST:"+pattern, object, params...) 97 } 98 99 func (g *RouterGroup) DELETE(pattern string, object interface{}, params ...interface{}) { 100 g.bind("HANDLER", "DELETE:"+pattern, object, params...) 101 } 102 103 func (g *RouterGroup) PATCH(pattern string, object interface{}, params ...interface{}) { 104 g.bind("HANDLER", "PATCH:"+pattern, object, params...) 105 } 106 107 func (g *RouterGroup) HEAD(pattern string, object interface{}, params ...interface{}) { 108 g.bind("HANDLER", "HEAD:"+pattern, object, params...) 109 } 110 111 func (g *RouterGroup) CONNECT(pattern string, object interface{}, params ...interface{}) { 112 g.bind("HANDLER", "CONNECT:"+pattern, object, params...) 113 } 114 115 func (g *RouterGroup) OPTIONS(pattern string, object interface{}, params ...interface{}) { 116 g.bind("HANDLER", "OPTIONS:"+pattern, object, params...) 117 } 118 119 func (g *RouterGroup) TRACE(pattern string, object interface{}, params ...interface{}) { 120 g.bind("HANDLER", "TRACE:"+pattern, object, params...) 121 } 122 123 // REST路由注册 124 func (g *RouterGroup) REST(pattern string, object interface{}) { 125 g.bind("REST", pattern, object) 126 } 127 128 // 执行路由绑定 129 func (g *RouterGroup) bind(bindType string, pattern string, object interface{}, params ...interface{}) { 130 // 注册路由处理 131 if len(g.prefix) > 0 { 132 domain, method, path, err := g.server.parsePattern(pattern) 133 if err != nil { 134 glog.Fatalf("invalid pattern: %s", pattern) 135 } 136 if bindType == "REST" { 137 pattern = g.prefix + "/" + strings.TrimLeft(path, "/") 138 } else { 139 pattern = g.server.serveHandlerKey(method, g.prefix+"/"+strings.TrimLeft(path, "/"), domain) 140 } 141 } 142 methods := gconv.Strings(params) 143 // 判断是否事件回调注册 144 if _, ok := object.(HandlerFunc); ok && len(methods) > 0 { 145 bindType = "HOOK" 146 } 147 switch bindType { 148 case "HANDLER": 149 if h, ok := object.(HandlerFunc); ok { 150 if g.server != nil { 151 g.server.BindHandler(pattern, h) 152 } else { 153 g.domain.BindHandler(pattern, h) 154 } 155 } else if g.isController(object) { 156 if len(methods) > 0 { 157 if g.server != nil { 158 g.server.BindControllerMethod(pattern, object.(Controller), methods[0]) 159 } else { 160 g.domain.BindControllerMethod(pattern, object.(Controller), methods[0]) 161 } 162 } else { 163 if g.server != nil { 164 g.server.BindController(pattern, object.(Controller)) 165 } else { 166 g.domain.BindController(pattern, object.(Controller)) 167 } 168 } 169 } else { 170 if len(methods) > 0 { 171 if g.server != nil { 172 g.server.BindObjectMethod(pattern, object, methods[0]) 173 } else { 174 g.domain.BindObjectMethod(pattern, object, methods[0]) 175 } 176 } else { 177 if g.server != nil { 178 g.server.BindObject(pattern, object) 179 } else { 180 g.domain.BindObject(pattern, object) 181 } 182 } 183 } 184 case "REST": 185 if g.isController(object) { 186 if g.server != nil { 187 g.server.BindControllerRest(pattern, object.(Controller)) 188 } else { 189 g.domain.BindControllerRest(pattern, object.(Controller)) 190 } 191 } else { 192 if g.server != nil { 193 g.server.BindObjectRest(pattern, object) 194 } else { 195 g.domain.BindObjectRest(pattern, object) 196 } 197 } 198 case "HOOK": 199 if h, ok := object.(HandlerFunc); ok { 200 if g.server != nil { 201 g.server.BindHookHandler(pattern, methods[0], h) 202 } else { 203 g.domain.BindHookHandler(pattern, methods[0], h) 204 } 205 } else { 206 glog.Fatalf("invalid hook handler for pattern:%s", pattern) 207 } 208 } 209 } 210 211 // 判断给定对象是否控制器对象: 212 // 控制器必须包含以下公开的属性对象:Request/Response/Server/Cookie/Session/View. 213 func (g *RouterGroup) isController(value interface{}) bool { 214 // 首先判断是否满足控制器接口定义 215 if _, ok := value.(Controller); !ok { 216 return false 217 } 218 // 其次检查控制器的必需属性 219 v := reflect.ValueOf(value) 220 if v.Kind() == reflect.Ptr { 221 v = v.Elem() 222 } 223 if v.FieldByName("Request").IsValid() && v.FieldByName("Response").IsValid() && 224 v.FieldByName("Server").IsValid() && v.FieldByName("Cookie").IsValid() && 225 v.FieldByName("Session").IsValid() && v.FieldByName("View").IsValid() { 226 return true 227 } 228 return false 229 }