docs/client/hooks.md
Hooks let you intercept and modify the request or response flow of the Fiber client. They are useful for:
There are two kinds of hooks:
Request hooks are functions executed before the HTTP request is sent. They follow the signature:
type RequestHook func(*Client, *Request) error
A request hook receives both the Client and the Request objects, allowing you to modify the request before it leaves your application. For example, you could:
Example:
type Repository struct {
Name string `json:"name"`
FullName string `json:"full_name"`
Description string `json:"description"`
Homepage string `json:"homepage"`
Owner struct {
Login string `json:"login"`
} `json:"owner"`
}
func main() {
cc := client.New()
// Add a request hook that modifies the request URL before sending.
cc.AddRequestHook(func(c *client.Client, r *client.Request) error {
r.SetURL("https://api.github.com/" + r.URL())
return nil
})
resp, err := cc.Get("repos/gofiber/fiber")
if err != nil {
panic(err)
}
var repo Repository
if err := resp.JSON(&repo); err != nil {
panic(err)
}
fmt.Printf("Status code: %d\n", resp.StatusCode())
fmt.Printf("Repository: %s\n", repo.FullName)
fmt.Printf("Description: %s\n", repo.Description)
fmt.Printf("Homepage: %s\n", repo.Homepage)
fmt.Printf("Owner: %s\n", repo.Owner.Login)
fmt.Printf("Name: %s\n", repo.Name)
fmt.Printf("Full Name: %s\n", repo.FullName)
}
Status code: 200
Repository: gofiber/fiber
Description: ⚡️ Express inspired web framework written in Go
Homepage: https://gofiber.io
Owner: gofiber
Name: fiber
Full Name: gofiber/fiber
Fiber includes built-in request hooks:
PathParam and QueryParam methods.:::info If a request hook returns an error, Fiber stops the request and returns the error immediately. :::
Example with Multiple Hooks:
func main() {
cc := client.New()
cc.AddRequestHook(func(c *client.Client, r *client.Request) error {
fmt.Println("Hook 1")
return errors.New("error")
})
cc.AddRequestHook(func(c *client.Client, r *client.Request) error {
fmt.Println("Hook 2")
return nil
})
_, err := cc.Get("https://example.com/")
if err != nil {
panic(err)
}
}
Hook 1.
panic: error
goroutine 1 [running]:
main.main()
main.go:25 +0xaa
exit status 2
Response hooks are functions executed after the HTTP response is received. They follow the signature:
type ResponseHook func(*Client, *Response, *Request) error
A response hook receives the Client, Response, and Request objects, allowing you to inspect and modify the response or perform additional actions such as logging, tracing, or processing response data.
Example:
func main() {
cc := client.New()
cc.AddResponseHook(func(c *client.Client, resp *client.Response, req *client.Request) error {
fmt.Printf("Response Status Code: %d\n", resp.StatusCode())
fmt.Printf("HTTP protocol: %s\n\n", resp.Protocol())
fmt.Println("Response Headers:")
for key, value := range resp.RawResponse.Header.All() {
fmt.Printf("%s: %s\n", key, value)
}
return nil
})
_, err := cc.Get("https://example.com/")
if err != nil {
panic(err)
}
}
Response Status Code: 200
HTTP protocol: HTTP/1.1
Response Headers:
Content-Length: 1256
Content-Type: text/html; charset=UTF-8
Server: ECAcc (dcd/7D5A)
Age: 216114
Cache-Control: max-age=604800
Date: Fri, 10 May 2024 10:49:10 GMT
Etag: "3147526947+gzip+ident"
Expires: Fri, 17 May 2024 10:49:10 GMT
Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
Vary: Accept-Encoding
X-Cache: HIT
Fiber includes built-in response hooks:
log.CommonLogger interface.:::info If a response hook returns an error, Fiber skips the remaining hooks and returns that error. :::
Example with Multiple Response Hooks:
func main() {
cc := client.New()
cc.AddResponseHook(func(c *client.Client, r1 *client.Response, r2 *client.Request) error {
fmt.Println("Hook 1")
return nil
})
cc.AddResponseHook(func(c *client.Client, r1 *client.Response, r2 *client.Request) error {
fmt.Println("Hook 2")
return errors.New("error")
})
cc.AddResponseHook(func(c *client.Client, r1 *client.Response, r2 *client.Request) error {
fmt.Println("Hook 3")
return nil
})
_, err := cc.Get("https://example.com/")
if err != nil {
panic(err)
}
}
Hook 1
Hook 2
panic: error
goroutine 1 [running]:
main.main()
main.go:30 +0xd6
exit status 2
Hooks run in FIFO order (first in, first out), so they're executed in the order you add them. Keep this in mind when adding multiple hooks, as the order can affect the outcome.
Example:
func main() {
cc := client.New()
cc.AddRequestHook(func(c *client.Client, r *client.Request) error {
fmt.Println("Hook 1")
return nil
})
cc.AddRequestHook(func(c *client.Client, r *client.Request) error {
fmt.Println("Hook 2")
return nil
})
_, err := cc.Get("https://example.com/")
if err != nil {
panic(err)
}
}
Hook 1
Hook 2