将参数传递给http.HandlerFunc函数

huangapple go评论71阅读模式
英文:

Passing in parameters to a http.HandlerFunc

问题

我正在使用Go语言内置的http服务器和pat来响应一些URL:

mux.Get("/products", http.HandlerFunc(index))

func index(w http.ResponseWriter, r *http.Request) {
    // 做一些事情。
}

我需要向这个处理函数传递一个额外的参数 - 一个接口。

func (api Api) Attach(resourceManager interface{}, route string) {
    // 将典型的REST操作应用于Mux。
    // 例如:Product - 对应 /products
    mux.Get(route, http.HandlerFunc(index(resourceManager)))

    // 例如:Product ID: 1 - 对应 /products/1
    mux.Get(route+"/:id", http.HandlerFunc(show(resourceManager)))
}

func index(w http.ResponseWriter, r *http.Request, resourceManager interface{}) {
    managerType := string(reflect.TypeOf(resourceManager).String())
    w.Write([]byte(fmt.Sprintf("%v", managerType)))
}

func show(w http.ResponseWriter, r *http.Request, resourceManager interface{}) {
    managerType := string(reflect.TypeOf(resourceManager).String())
    w.Write([]byte(fmt.Sprintf("%v", managerType)))
}

如何向处理函数传递额外的参数?

英文:

I'm using Go's built in http server and pat to respond to some URLs:

mux.Get("/products", http.HandlerFunc(index))

func index(w http.ResponseWriter, r *http.Request) {
	// Do something.
}

I need to pass in an extra parameter to this handler function - an interface.

func (api Api) Attach(resourceManager interface{}, route string) {
	// Apply typical REST actions to Mux.
	// ie: Product - to /products
	mux.Get(route, http.HandlerFunc(index(resourceManager)))

	// ie: Product ID: 1 - to /products/1
	mux.Get(route+"/:id", http.HandlerFunc(show(resourceManager)))
}

func index(w http.ResponseWriter, r *http.Request, resourceManager interface{}) {
	managerType := string(reflect.TypeOf(resourceManager).String())
	w.Write([]byte(fmt.Sprintf("%v", managerType)))
}

func show(w http.ResponseWriter, r *http.Request, resourceManager interface{}) {
	managerType := string(reflect.TypeOf(resourceManager).String())
	w.Write([]byte(fmt.Sprintf("%v", managerType)))
}

How can I send in an extra paramter to the handler function?

答案1

得分: 16

你可以通过使用闭包来实现你想要的功能。

func index()更改为以下内容(未经测试):

func index(resourceManager interface{}) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        managerType := string(reflect.TypeOf(resourceManager).String())
        w.Write([]byte(fmt.Sprintf("%v", managerType)))
    }
}

然后对func show()做同样的更改。

英文:

You should be able to do what you wish by using closures.

Change func index() to the following (untested):

func index(resourceManager interface{}) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
	    managerType := string(reflect.TypeOf(resourceManager).String())
	    w.Write([]byte(fmt.Sprintf("%v", managerType)))
	}
}

And then do the same to func show()

答案2

得分: 8

另一种选择是直接使用实现了http.Handler接口的类型,而不仅仅使用函数。例如:

type IndexHandler struct {
    resourceManager interface{}
}

func (ih IndexHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    managerType := string(reflect.TypeOf(ih.resourceManager).String())
    w.Write([]byte(fmt.Sprintf("%v", managerType)))
}

...
mux.Get(route, IndexHandler{resourceManager})

如果你想将ServeHTTP处理方法重构为多个方法,这种模式可能会很有用。

英文:

Another option is to use types implementing http.Handler directly rather than only using functions. For example:

type IndexHandler struct {
    resourceManager interface{}
}

func (ih IndexHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    managerType := string(reflect.TypeOf(ih.resourceManager).String())
    w.Write([]byte(fmt.Sprintf("%v", managerType)))
}

...
mux.Get(route, IndexHandler{resourceManager})

This kind of pattern can be useful if you want to refactor your ServeHTTP handler method into multiple methods.

huangapple
  • 本文由 发表于 2014年5月21日 11:12:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/23773322.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定