Go HTTP客户端是否有“中间件”?

I would like to ask if we can create 'middleware' functions for Go http client? Example I want to add a log function, so every sent request will be logged, or add setAuthToken so the token will be added to each request's header.

You can use the Transport parameter in HTTP client to that effect, with a composition pattern, using the fact that:

  • http.Client.Transport defines the function that will handle all HTTP requests;
  • http.Client.Transport has interface type http.RoundTripper, and can thus be replaced with your own implementation;

For example:

package main

import (
    "fmt"
    "net/http"
)

// This type implements the http.RoundTripper interface
type LoggingRoundTripper struct {
    Proxied http.RoundTripper
}

func (lrt LoggingRoundTripper) RoundTrip(req *http.Request) (res *http.Response, e error) {
    // Do "before sending requests" actions here.
    fmt.Printf("Sending request to %v
", req.URL)

    // Send the request, get the response (or the error)
    res, e = lrt.Proxied.RoundTrip(req)

    // Handle the result.
    if (e != nil) {
        fmt.Printf("Error: %v", e)
    } else {
        fmt.Printf("Received %v response
", res.Status)
    }

    return
}

func main() {
    var c = &http.Client{Transport:LoggingRoundTripper{http.DefaultTransport}}
    c.Get("https://www.google.com")
}

Feel free to alter names as you wish, I did not think on them for very long.

This can be achieved using closure functions. It's probably more clear with an example:

package main

import (  
  "fmt"
  "net/http"
)

func main() {  
  http.HandleFunc("/hello", logged(hello))
  http.ListenAndServe(":3000", nil)
}

func logged(f func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {  
  return func(w http.ResponseWriter, r *http.Request) {
    fmt.Println("logging something")
    f(w, r)
    fmt.Println("finished handling request")
  }
}

func hello(w http.ResponseWriter, r *http.Request) {  
  fmt.Fprintln(w, "<h1>Hello!</h1>")
}

credit goes to: http://www.calhoun.io/5-useful-ways-to-use-closures-in-go/