go-chassis
go-chassis实现的rest-server是在go-restful上的一层封装。Register时只要将注册的schema解析成routes,并注册到webService中,Start启动server时 container.Add(r.ws) ,同时将container作为handler交给 http.Server , 最后开始ListenAndServe即可。
type restfulServer struct {
microServiceName string
container *restful.Container
ws *restful.WebService
opts server.Options
mux sync.RWMutex
exit chan chan error
server *http.Server
}
根据Method不同,向WebService注册不同方法的handle,从schema读取的routes信息包含Method,Func以及PathPattern。
func (r *restfulServer)Register(schemainterface{}, options ...server.RegisterOption)(string, error) {
schemaType := reflect.TypeOf(schema)
schemaValue := reflect.ValueOf(schema)
var schemaName string
tokens := strings.Split(schemaType.String(), ".")
if len(tokens) >= 1 {
schemaName = tokens[len(tokens)-1]
}
routes, err := GetRoutes(schema)
for _, route := range routes {
lager.Logger.Infof("Add route path: [%s] Method: [%s] Func: [%s]. ",
route.Path, route.Method, route.ResourceFuncName)
method, exist := schemaType.MethodByName(route.ResourceFuncName)
...
handle := func(req *restful.Request, rep *restful.Response) {
c, err := handler.GetChain(common.Provider, r.opts.ChainName)
inv := invocation.Invocation{
MicroServiceName: config.SelfServiceName,
SourceMicroService: req.HeaderParameter(common.HeaderSourceName),
Args: req,
Protocol: common.ProtocolRest,
SchemaID: schemaName,
OperationID: method.Name,
}
bs := NewBaseServer(context.TODO())
bs.req = req
bs.resp = rep
c.Next(&inv, func(ir *invocation.InvocationResponse)error {
if ir.Err != nil {
return ir.Err
}
method.Func.Call([]reflect.Value{schemaValue, reflect.ValueOf(bs)})
if bs.resp.StatusCode() >= http.StatusBadRequest {
return ...
}
return nil
})
}
switch route.Method {
case http.MethodGet:
r.ws.Route(r.ws.GET(route.Path).To(handle).
Doc(route.ResourceFuncName).
Operation(route.ResourceFuncName))
...
}
}
return reflect.TypeOf(schema).String(), nil
}
实在是比较简单,就不写了。今天好困。
遗留问题
-
reflect在路由注册中的使用,反射与性能
route select时涉及到模糊匹配 如何保证处理速度
pathParams的解析
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持易采站长站。









