Golang - restful-url的接口注册处理

一、注册 /根请求转到rootHandle,在rootHandle中为不同的url查找对应的处理接口并执行。

1、tars业务端配置restful url与处理函数,指定url与对应的处理函数。

    type TarsHttpMux struct {
        http.ServeMux
        cfg *TarsHttpConf
    }
    mux := &tars.TarsHttpMux{}
    mux.HandleFunc("/", model.RootHandler)

2、这种方法在注册时把所有的url请求转到rootHandle中进行处理,在业务端rootHandle要实现为不同的url转到不同的接口进行处理的逻辑。rootHandle包含以下逻辑。

var handlers = make(map[string]Handler)
// Handler ...
type Handler interface {
	HandleFunc(req string) (interface{}, int, error)
}
//入参handle的接口实现者不同,处理url的逻辑不同
func RegisterHandler(url string, h Handler) error {
	_, ok := handlers[url]
	if ok {
		return errors.New("Url handle func alread registed")
	}

	handlers[url] = h
	return nil
}

RegisterHandler("/test", &test)

func GetHandler(url string) (Handler, error) {
	p, ok := handlers[url]
	if ok {
		return p, nil
	}
	return nil, errors.New("Get Url handle func failed")
}
 
GetHandler("test").HandleFunc(req)

3、 mux.HandleFunc("/", model.RootHandler) 调用net/http包的处理函数,注册url与自定义func RootHandler(w http.ResponseWriter, r*http.Request) 处理函数 。

// HandleFunc registers the handler function for the given pattern.
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
	if handler == nil {
		panic("http: nil handler")
	}
	mux.Handle(pattern, HandlerFunc(handler))
}

4、若通过HandleFunc接口注册,需要适配函数类型为Handler接口。即含有ServeHTTP方法。HandlerFunc为一个函数类型,实现了ServeHTTP的方法,是一个Handle接口类型。

// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as HTTP handlers. If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// Handler that calls f.

type Handler interface {
	ServeHTTP(ResponseWriter, *Request)
}

type HandlerFunc func(ResponseWriter, *Request)

// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
	f(w, r)
}

5. 注册url的处理入口函数

// Handle registers the handler for the given pattern.
// If a handler already exists for pattern, Handle panics.
func (mux *ServeMux) Handle(pattern string, handler Handler) {
	mux.mu.Lock()
	defer mux.mu.Unlock()

	if pattern == "" {
		panic("http: invalid pattern")
	}
	if handler == nil {
		panic("http: nil handler")
	}
	if _, exist := mux.m[pattern]; exist {
		panic("http: multiple registrations for " + pattern)
	}

	if mux.m == nil {
		mux.m = make(map[string]muxEntry)
	}
	e := muxEntry{h: handler, pattern: pattern}
	mux.m[pattern] = e
	if pattern[len(pattern)-1] == '/' {
		mux.es = appendSorted(mux.es, e)
	}

	if pattern[0] != '/' {
		mux.hosts = true
	}
}

二、在http/net中为不同的restful-url请求注册不同的接口

1、tars业务端配置restful url与处理函数,指定url与对应的处理函数。

    type TarsHttpMux struct {
        http.ServeMux
        cfg *TarsHttpConf
    }
    // AdminMux admin http处理对象
	var AdminMux *tars.TarsHttpMux = &tars.TarsHttpMux{}

2、业务端定义httphandle结构体,结构体中的成员为接口类型成员,传入结构体接口成员的实现者不同,结构体拥有不同的处理逻辑。 由于 IHandler为httpHandle的匿名类型成员,所以httpHandle结构体可以直接调用HandleFunc接口,即实现了IHandler接口方法,httpHandle结构体也为IHandle接口类型。若想要某一结构体拥有某一接口不同的实现方法时,可以把接口类型作为结构体的一个类型成员。接口成员赋予不同的实现者时,结构体拥有不同的接口实现方法

	type httpHandler struct {
        IHandler
    }
	type IHandler interface {
		HandleFunc(url string, req []byte) (interface{}, int, error)
	}

3、同时业务端httpHandler结构体实现了serverhttp方法,为所有的url通用的处理方法逻辑,不同的处理逻辑在于调用httpHandler.HandleFunc()时。此结构体可为net/http中的Handle接口类型。 不同的url请求对应不同的httpHandle结构体进行处理。

    func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
     //所有的url通用的处理方法逻辑,不同的处理逻辑在于调用httpHandler.HandleFunc()时

    }

4、业务端调用RegisterURLHandler接口为不同的url绑定不同的处理接口IHandler,在业务端为所有的url和相应的处理接口,最终执行net/http包中handle接口进行注册。入参Ihandle的接口实现者不同,httpHandle调用的HandleFunc函数逻辑不同,即处理pattern url的逻辑不同。

	func RegisterURLHandler(pattern string, handler IHandler) {
		h := &httpHandler{handler}
		AdminMux.Handle(pattern, h)
	}


5、执行net/http包中handle接口,注册url的处理入口函数

// Handle registers the handler for the given pattern.
// If a handler already exists for pattern, Handle panics.
func (mux *ServeMux) Handle(pattern string, handler Handler) {
	mux.mu.Lock()
	defer mux.mu.Unlock()

	if pattern == "" {
		panic("http: invalid pattern")
	}
	if handler == nil {
		panic("http: nil handler")
	}
	if _, exist := mux.m[pattern]; exist {
		panic("http: multiple registrations for " + pattern)
	}

	if mux.m == nil {
		mux.m = make(map[string]muxEntry)
	}
	e := muxEntry{h: handler, pattern: pattern}
	mux.m[pattern] = e
	if pattern[len(pattern)-1] == '/' {
		mux.es = appendSorted(mux.es, e)
	}

	if pattern[0] != '/' {
		mux.hosts = true
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值