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.
Overview
While JSON is the most common format for web APIs, binary serialization formats can provide significant performance and size benefits. Fiber supports multiple formats out of the box.
MessagePack (MsgPack)
MessagePack is an efficient binary serialization format that’s like JSON but faster and smaller.
Benefits
- 30-50% smaller than JSON
- Faster encoding/decoding
- Type preservation
- Wide language support
Setup
Fiber doesn’t bundle MsgPack (it’s not in Go’s standard library), so choose a library:
Recommended Libraries:
go get github.com/shamaton/msgpack/v3
Configuration
import (
"github.com/gofiber/fiber/v3"
"github.com/shamaton/msgpack/v3"
)
app := fiber.New(fiber.Config{
MsgPackEncoder: msgpack.Marshal,
MsgPackDecoder: msgpack.Unmarshal,
})
Basic Usage
type User struct {
Name string `msgpack:"name"`
Age int `msgpack:"age"`
Email string `msgpack:"email"`
}
app.Post("/msgpack", func(c fiber.Ctx) error {
user := new(User)
// Bind MsgPack request body
if err := c.Bind().MsgPack(user); err != nil {
return err
}
// Respond with MsgPack (Content-Type: application/vnd.msgpack)
return c.MsgPack(user)
})
Fiber can automatically choose MsgPack based on the Accept header:
app.Get("/data", func(c fiber.Ctx) error {
data := map[string]interface{}{
"name": "John",
"age": 30,
}
// Returns JSON or MsgPack based on Accept header
return c.AutoFormat(data)
})
// Client request with Accept: application/vnd.msgpack -> MsgPack response
// Client request with Accept: application/json -> JSON response
Using vmihailenco/msgpack
Alternative library with more features:
import (
"github.com/gofiber/fiber/v3"
"github.com/vmihailenco/msgpack/v5"
)
app := fiber.New(fiber.Config{
MsgPackEncoder: msgpack.Marshal,
MsgPackDecoder: msgpack.Unmarshal,
})
type Product struct {
ID int `msgpack:"id"`
Name string `msgpack:"name"`
Price float64 `msgpack:"price"`
CreatedAt time.Time `msgpack:"created_at"`
}
app.Get("/products/:id", func(c fiber.Ctx) error {
product := Product{
ID: 1,
Name: "Widget",
Price: 19.99,
CreatedAt: time.Now(),
}
return c.MsgPack(product)
})
CBOR (Concise Binary Object Representation)
CBOR is a binary format similar to MessagePack, defined in RFC 8949.
Benefits
- Standardized (IETF RFC)
- Compact binary encoding
- Supports more data types than JSON
- Good for IoT and constrained environments
Setup
go get github.com/fxamacker/cbor/v2
Configuration
import (
"github.com/gofiber/fiber/v3"
"github.com/fxamacker/cbor/v2"
)
app := fiber.New(fiber.Config{
CBOREncoder: cbor.Marshal,
CBORDecoder: cbor.Unmarshal,
})
Basic Usage
type Sensor struct {
DeviceID string `cbor:"device_id"`
Temperature float64 `cbor:"temp"`
Humidity float64 `cbor:"humidity"`
Timestamp time.Time `cbor:"ts"`
}
app.Post("/sensor/data", func(c fiber.Ctx) error {
sensor := new(Sensor)
// Bind CBOR request body
if err := c.Bind().CBOR(sensor); err != nil {
return err
}
// Process sensor data
log.Printf("Received data from %s: temp=%.2f, humidity=%.2f",
sensor.DeviceID, sensor.Temperature, sensor.Humidity)
// Respond with CBOR (Content-Type: application/cbor)
return c.CBOR(fiber.Map{
"status": "received",
"timestamp": time.Now(),
})
})
app.Get("/api/data", func(c fiber.Ctx) error {
data := map[string]interface{}{
"temperature": 23.5,
"humidity": 65.2,
"timestamp": time.Now(),
}
// Returns JSON, CBOR, or MsgPack based on Accept header
return c.AutoFormat(data)
})
// Accept: application/cbor -> CBOR response
// Accept: application/vnd.msgpack -> MsgPack response
// Accept: application/json -> JSON response
XML Support
Fiber has built-in XML support using Go’s standard library:
type Book struct {
XMLName xml.Name `xml:"book"`
Title string `xml:"title"`
Author string `xml:"author"`
Year int `xml:"year"`
}
app.Post("/books", func(c fiber.Ctx) error {
book := new(Book)
// Bind XML request body
if err := c.Bind().XML(book); err != nil {
return err
}
// Respond with XML (Content-Type: application/xml)
return c.XML(book)
})
Custom XML Encoder
For better performance, use a custom XML library:
import "github.com/clbanning/mxj/v2"
app := fiber.New(fiber.Config{
XMLEncoder: customXMLMarshal,
XMLDecoder: customXMLUnmarshal,
})
Fiber supports form data with automatic binding:
type LoginForm struct {
Username string `form:"username"`
Password string `form:"password"`
Remember bool `form:"remember"`
}
app.Post("/login", func(c fiber.Ctx) error {
form := new(LoginForm)
// Bind form data (application/x-www-form-urlencoded)
if err := c.Bind().Form(form); err != nil {
return err
}
// Process login
return c.JSON(fiber.Map{"username": form.Username})
})
import "mime/multipart"
type UploadForm struct {
Title string `form:"title"`
Description string `form:"description"`
File *multipart.FileHeader `form:"file"`
}
app.Post("/upload", func(c fiber.Ctx) error {
form := new(UploadForm)
// Bind multipart form data
if err := c.Bind().Form(form); err != nil {
return err
}
// Save file
if err := c.SaveFile(form.File, "./uploads/"+form.File.Filename); err != nil {
return err
}
return c.JSON(fiber.Map{
"title": form.Title,
"filename": form.File.Filename,
})
})
Content Negotiation
Fiber’s AutoFormat automatically selects the best format:
app.Get("/api/users", func(c fiber.Ctx) error {
users := []User{
{Name: "Alice", Age: 30},
{Name: "Bob", Age: 25},
}
// Automatically responds in the requested format
return c.AutoFormat(users)
})
// Client headers determine response format:
// Accept: application/json -> JSON
// Accept: application/xml -> XML
// Accept: application/vnd.msgpack -> MsgPack
// Accept: application/cbor -> CBOR
Size Comparison
For a typical API response with 1000 users:
| Format | Size | Compression |
|---|
| JSON | 85 KB | Baseline |
| JSON (minified) | 65 KB | 23% smaller |
| MessagePack | 48 KB | 43% smaller |
| CBOR | 52 KB | 39% smaller |
| Protobuf* | 35 KB | 59% smaller |
*Protobuf requires schema definition
Benchmark results for encoding/decoding 1000 objects:
| Format | Encode | Decode | Total |
|---|
| JSON (stdlib) | 2.5ms | 3.2ms | 5.7ms |
| JSON (goccy/go-json) | 0.9ms | 1.1ms | 2.0ms |
| MessagePack | 0.8ms | 1.0ms | 1.8ms |
| CBOR | 1.0ms | 1.2ms | 2.2ms |
When to Use What
JSON
- Human-readable debugging needed
- Browser/JavaScript clients
- Wide compatibility required
- Simple data structures
MessagePack
- Performance is critical
- Network bandwidth is limited
- Server-to-server communication
- Mobile applications
CBOR
- IoT/embedded systems
- Standards compliance required
- Complex data types needed
- Interoperability with other CBOR systems
XML
- Legacy system integration
- SOAP services
- Complex document structures
- Schema validation required
Custom Serialization
Implement custom encoding for specialized formats:
import "google.golang.org/protobuf/proto"
app := fiber.New(fiber.Config{
// Custom format handlers
})
app.Get("/data.proto", func(c fiber.Ctx) error {
// Assuming you have protobuf definitions
message := &pb.UserMessage{
Name: "John",
Age: 30,
}
data, err := proto.Marshal(message)
if err != nil {
return err
}
c.Set("Content-Type", "application/x-protobuf")
return c.Send(data)
})
Best Practices
- Choose the right format - JSON for web, MsgPack for performance
- Document your API - Specify supported formats in docs
- Support multiple formats - Use
AutoFormat for flexibility
- Version your APIs - Format changes can break clients
- Benchmark your use case - Test with realistic data
- Consider compression - Gzip can reduce JSON size significantly
- Validate input - Always validate regardless of format
See Also