Documentation Index Fetch the complete documentation index at: https://mintlify.com/gofiber/fiber/llms.txt
Use this file to discover all available pages before exploring further.
Handling Responses
The Response struct represents the server’s reply and provides methods to access status codes, headers, body content, and cookies.
Structure
type Response struct {
client * Client
request * Request
cookie [] * fasthttp . Cookie
RawResponse * fasthttp . Response
}
Get response status details:
Status Code
Get the numeric HTTP status code:
resp , err := client . Get ( "https://httpbin.org/get" )
if err != nil {
panic ( err )
}
fmt . Printf ( "Status Code: %d \n " , resp . StatusCode ())
// Output: Status Code: 200
Signature:
func ( r * Response ) StatusCode () int
Status Message
Get the HTTP status message:
fmt . Printf ( "Status: %s \n " , resp . Status ())
// Output: Status: OK
Signature:
func ( r * Response ) Status () string
Protocol
Get the HTTP protocol version:
fmt . Printf ( "Protocol: %s \n " , resp . Protocol ())
// Output: Protocol: HTTP/1.1
Signature:
func ( r * Response ) Protocol () string
Access response headers:
contentType := resp . Header ( "Content-Type" )
fmt . Printf ( "Content-Type: %s \n " , contentType )
Signature:
func ( r * Response ) Header ( key string ) string
Iterate over all response headers:
import " strings "
for key , values := range resp . Headers () {
fmt . Printf ( " %s : %s \n " , key , strings . Join ( values , ", " ))
}
Signature:
func ( r * Response ) Headers () iter . Seq2 [ string , [] string ]
import " maps "
headers := maps . Collect ( resp . Headers ())
for key , values := range headers {
fmt . Printf ( " %s : %v \n " , key , values )
}
Header values are only valid until the response is released. Make copies if you need to store them.
Response Body
Get Body as Bytes
body := resp . Body ()
fmt . Printf ( "Body length: %d bytes \n " , len ( body ))
Signature:
func ( r * Response ) Body () [] byte
Get Body as String
Get the body as a trimmed string:
text := resp . String ()
fmt . Println ( text )
Signature:
func ( r * Response ) String () string
Stream Response Body
Read large responses as a stream:
c := client . New ()
c . SetStreamResponseBody ( true )
resp , err := c . Get ( "https://httpbin.org/bytes/1024" )
if err != nil {
panic ( err )
}
defer resp . Close ()
// Read from stream
buf := make ([] byte , 256 )
total , err := io . CopyBuffer ( io . Discard , resp . BodyStream (), buf )
if err != nil {
panic ( err )
}
fmt . Printf ( "Read %d bytes \n " , total )
Signature:
func ( r * Response ) BodyStream () io . Reader
func ( r * Response ) IsStreaming () bool
When using BodyStream(), calling Body() afterward may return an empty slice if the stream has been consumed.
Check if Streaming
if resp . IsStreaming () {
fmt . Println ( "Response is streaming" )
// Use resp.BodyStream() to read incrementally
} else {
fmt . Println ( "Response is buffered" )
// Use resp.Body() for direct access
}
Parse JSON
Unmarshal JSON responses:
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
resp , err := client . Get ( "https://api.example.com/users/1" )
if err != nil {
panic ( err )
}
var user User
if err := resp . JSON ( & user ); err != nil {
panic ( err )
}
fmt . Printf ( "User: %s ( %s ) \n " , user . Name , user . Email )
Signature:
func ( r * Response ) JSON ( v any ) error
Parse JSON Array
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
resp , err := client . Get ( "https://api.example.com/users" )
if err != nil {
panic ( err )
}
var users [] User
if err := resp . JSON ( & users ); err != nil {
panic ( err )
}
for _ , user := range users {
fmt . Printf ( "User: %s \n " , user . Name )
}
Custom JSON Unmarshaler
Use a custom JSON unmarshaler:
import " github.com/goccy/go-json "
c := client . New ()
c . SetJSONUnmarshal ( json . Unmarshal )
resp , err := c . Get ( "https://api.example.com/users/1" )
if err != nil {
panic ( err )
}
var user User
if err := resp . JSON ( & user ); err != nil {
panic ( err )
}
Parse XML
Unmarshal XML responses:
type User struct {
XMLName xml . Name `xml:"user"`
ID int `xml:"id"`
Name string `xml:"name"`
Email string `xml:"email"`
}
resp , err := client . Get ( "https://api.example.com/users/1.xml" )
if err != nil {
panic ( err )
}
var user User
if err := resp . XML ( & user ); err != nil {
panic ( err )
}
fmt . Printf ( "User: %s \n " , user . Name )
Signature:
func ( r * Response ) XML ( v any ) error
Parse CBOR
Unmarshal CBOR responses:
type User struct {
ID int `cbor:"id"`
Name string `cbor:"name"`
}
resp , err := client . Get ( "https://api.example.com/users/1.cbor" )
if err != nil {
panic ( err )
}
var user User
if err := resp . CBOR ( & user ); err != nil {
panic ( err )
}
Signature:
func ( r * Response ) CBOR ( v any ) error
Cookies
Access cookies from the response:
resp , err := client . Get ( "https://httpbin.org/cookies/set/go/fiber" )
if err != nil {
panic ( err )
}
cookies := resp . Cookies ()
for _ , cookie := range cookies {
fmt . Printf ( " %s = %s \n " , string ( cookie . Key ()), string ( cookie . Value ()))
}
// Output: go = fiber
Signature:
func ( r * Response ) Cookies () [] * fasthttp . Cookie
Cookie values are only valid until the response is released. Make copies if you need to store them.
Save Response
Save the response body to a file or writer:
Save to File
resp , err := client . Get ( "https://httpbin.org/image/png" )
if err != nil {
panic ( err )
}
defer resp . Close ()
if err := resp . Save ( "/path/to/image.png" ); err != nil {
panic ( err )
}
Save to Writer
var buf bytes . Buffer
resp , err := client . Get ( "https://httpbin.org/get" )
if err != nil {
panic ( err )
}
defer resp . Close ()
if err := resp . Save ( & buf ); err != nil {
panic ( err )
}
fmt . Printf ( "Saved %d bytes \n " , buf . Len ())
Signature:
func ( r * Response ) Save ( v any ) error
When saving to a file, parent directories are created automatically if they don’t exist.
Error Handling
Check response status and handle errors:
resp , err := client . Get ( "https://api.example.com/users/999" )
if err != nil {
panic ( err )
}
defer resp . Close ()
if resp . StatusCode () != 200 {
fmt . Printf ( "Error: %s \n " , resp . Status ())
fmt . Printf ( "Body: %s \n " , resp . String ())
return
}
var user User
if err := resp . JSON ( & user ); err != nil {
fmt . Printf ( "Failed to parse JSON: %v \n " , err )
return
}
Check Status Code Ranges
switch {
case resp . StatusCode () >= 200 && resp . StatusCode () < 300 :
fmt . Println ( "Success" )
case resp . StatusCode () >= 400 && resp . StatusCode () < 500 :
fmt . Println ( "Client error" )
case resp . StatusCode () >= 500 :
fmt . Println ( "Server error" )
}
Resource Management
Properly release responses to avoid memory leaks:
Close Response
Release both request and response to the pool:
resp , err := client . Get ( "https://httpbin.org/get" )
if err != nil {
panic ( err )
}
defer resp . Close ()
// Use the response
fmt . Println ( resp . String ())
Signature:
func ( r * Response ) Close ()
Manual Pool Management
resp := client . AcquireResponse ()
defer client . ReleaseResponse ( resp )
// Configure and use response
Signature:
func AcquireResponse () * Response
func ReleaseResponse ( resp * Response )
Always call resp.Close() or client.ReleaseResponse(resp) when done with a response. Do not use responses after releasing them.
Access Raw Response
Access the underlying fasthttp response:
resp , err := client . Get ( "https://httpbin.org/get" )
if err != nil {
panic ( err )
}
defer resp . Close ()
// Access raw fasthttp response
rawResp := resp . RawResponse
fmt . Printf ( "Connection close: %v \n " , rawResp . Header . ConnectionClose ())
Examples
Download and Save File
c := client . New ()
c . SetStreamResponseBody ( true )
resp , err := c . Get ( "https://example.com/largefile.zip" )
if err != nil {
panic ( err )
}
defer resp . Close ()
if err := resp . Save ( "/downloads/largefile.zip" ); err != nil {
panic ( err )
}
fmt . Println ( "File downloaded successfully" )
Parse Nested JSON
type Repository struct {
Name string `json:"name"`
FullName string `json:"full_name"`
Description string `json:"description"`
Owner struct {
Login string `json:"login"
} ` json : "owner"`
}
resp, err := client.Get("https://api.github.com/repos/gofiber/fiber")
if err != nil {
panic(err)
}
defer resp.Close()
var repo Repository
if err := resp.JSON(&repo); err != nil {
panic(err)
}
fmt.Printf("Repository: %s \n", repo.FullName)
fmt.Printf("Owner: %s \n", repo.Owner.Login)
fmt.Printf("Description: %s \n", repo.Description)
Handle API Errors
type APIError struct {
Error string `json:"error"`
Message string `json:"message"`
}
resp , err := client . Get ( "https://api.example.com/users/999" )
if err != nil {
panic ( err )
}
defer resp . Close ()
if resp . StatusCode () != 200 {
var apiErr APIError
if err := resp . JSON ( & apiErr ); err != nil {
fmt . Printf ( "Failed to parse error response: %v \n " , err )
return
}
fmt . Printf ( "API Error: %s - %s \n " , apiErr . Error , apiErr . Message )
return
}
var user User
if err := resp . JSON ( & user ); err != nil {
panic ( err )
}
Next Steps
Request/Response Hooks Intercept and modify responses
Examples See complete working examples