1.可以在客戶端設置發送帶有HTTP Headers的request
func main() {
client := haberdasher.NewHaberdasherProtobufClient("http://localhost:8080", &http.Client{})
header := make(http.Header)
header.Set("Twitch-Authorization", "uDRlDxQYbFVXarBvmTncBoWKcZKqrZTY")
header.Set("Twitch-Client-ID", "FrankerZ")
header.Set("Name", "pengjunjie")
// Attach the headers to a context
ctx := context.Background()
ctx, err := twirp.WithHTTPRequestHeaders(ctx, header)
if err != nil {
log.Printf("twirp error setting headers: %s", err)
return
}
hat, err := client.MakeHat(ctx, &haberdasher.Size{Inches: 12})
if err != nil {
fmt.Printf("oh no: %v", err)
os.Exit(1)
}
fmt.Printf("I have a nice new hat: %+v", hat)
}
分析:通過header.set(key,value)的方法來設自定義設置header中存儲的數據,並通過WithHTTPRequestHeaders方法將header整合到context中,再將context作爲接口的參數傳到服務端
2.可以通過編寫中間件來封裝服務端
func main() {
server := &haberdasherserver.Server{} // implements Haberdasher interface
twirpHandler := haberdasher.NewHaberdasherServer(server, nil)
wrapped := WithUserAgent(twirpHandler)
http.ListenAndServe(":8080", wrapped)
}
func WithUserAgent(base http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ua := r.Header.Get("Name")
fmt.Println("server:" + ua)
ctx = context.WithValue(ctx, "name", ua)
r = r.WithContext(ctx)
base.ServeHTTP(w, r)
})
}
分析:服務端經過封裝後,可以讀取到header中的數據,並把讀取的數據再一次整合到context,當調用接口時,會把context作爲接口實現方法的參數傳入
3.接口實現方法讀取到context中的數據,並把處理後的結果返回給客戶端
func (s *Server) MakeHat(ctx context.Context, size *pb.Size) (hat *pb.Hat, err error) {
ua := ctx.Value("name").(string)
log.Printf("name: %v", ua)
if size.Inches <= 0 {
return nil, twirp.InvalidArgumentError("inches", "I can't make a hat that small!")
}
return &pb.Hat{
Inches: size.Inches,
Color: []string{"white", "black", "brown", "red", "blue"}[rand.Intn(4)],
Name: []string{"bowler", "baseball cap", "top hat", "derby"}[rand.Intn(3)],
}, nil
}
4.測試