Skip to main content

Overview

The msgpack middleware provides MessagePack content negotiation and serialization for efficient binary data transfer. Use it when you need:
  • Binary serialization
  • Reduced payload size
  • Faster parsing

Installation

import "github.com/go-mizu/mizu/middlewares/msgpack"

Quick Start

app := mizu.New()

app.Use(msgpack.New())

app.Get("/data", func(c *mizu.Ctx) error {
    // Auto-negotiates based on Accept header
    return c.Negotiate(200, data)
})

Examples

Enable MessagePack

app.Use(msgpack.New())

Explicit MessagePack Response

app.Get("/data", func(c *mizu.Ctx) error {
    return msgpack.Send(c, 200, data)
})

Parse MessagePack Request

app.Post("/data", func(c *mizu.Ctx) error {
    var data MyStruct
    if err := msgpack.Bind(c, &data); err != nil {
        return err
    }
    return c.JSON(200, data)
})

Content Negotiation

app.Use(msgpack.New())

app.Get("/data", func(c *mizu.Ctx) error {
    // Returns MessagePack if Accept: application/msgpack
    // Returns JSON if Accept: application/json
    return c.Negotiate(200, data)
})

API Reference

Functions

// New creates MessagePack middleware
func New() mizu.Middleware

// Send sends MessagePack response
func Send(c *mizu.Ctx, status int, data any) error

// Bind parses MessagePack request body
func Bind(c *mizu.Ctx, v any) error

Content Types

TypeDescription
application/msgpackStandard MessagePack
application/x-msgpackAlternative

Technical Details

Architecture

The msgpack middleware implements a lightweight MessagePack encoder/decoder without external dependencies. It consists of three main components:

Middleware Handler

  • Intercepts requests with MessagePack content types
  • Stores raw request body in context for later parsing
  • Supports configurable content types (default: application/msgpack, application/x-msgpack)

Encoder

  • Implements MessagePack binary format specification
  • Uses fixed-size optimizations for common value ranges
  • Supports fixint, int8/16/32/64, uint8/16/32/64 encoding
  • Handles fixstr, str8/16/32 for strings with automatic size selection
  • Encodes binary data with bin8/16/32 formats
  • Supports fixarray, array16/32 and fixmap, map16/32 structures

Decoder

  • Parses MessagePack binary format to Go values
  • Returns generic any types (string, int64, uint64, float32/64, []any, map[string]any)
  • Validates buffer boundaries to prevent out-of-bounds access
  • Handles all MessagePack type codes including fixint, negative fixint, and type-specific codes

Type Mappings

Go TypeMessagePack FormatNotes
nil0xc0Null value
bool0xc2, 0xc3false, true
int, int8-64fixint, int8-64Optimized by value range
uint, uint8-64fixint, uint8-64Optimized by value range
float32float 32 (0xca)4-byte IEEE 754
float64float 64 (0xcb)8-byte IEEE 754
stringfixstr, str8-32Length-prefixed
[]bytebin8-32Binary data
[]anyfixarray, array16-32Recursive encoding
map[string]anyfixmap, map16-32Key-value pairs

Error Handling

The middleware defines three error types:
  • ErrUnsupportedType: Returned when attempting to encode unsupported Go types
  • ErrInvalidFormat: Returned when decoding encounters invalid MessagePack data
  • ErrBufferTooSmall: Returned when the input buffer is insufficient for the declared data

Context Storage

The middleware stores the raw MessagePack request body in the request context using a private context key. This allows:
  • Multiple reads of the request body
  • Access via the Body() helper function
  • Preservation of the original request body for middleware chain

Best Practices

  • Use for internal APIs
  • Fall back to JSON for browsers
  • Consider client library support
  • Benchmark for your use case

Testing

Test Coverage

The msgpack middleware includes comprehensive test coverage for all functionality:
Test CaseDescriptionExpected Behavior
TestNewMiddleware initializationMiddleware successfully initializes and passes requests through
TestMarshalUnmarshal - nilNil value encoding/decodingCorrectly encodes and decodes nil values
TestMarshalUnmarshal - true/falseBoolean encoding/decodingCorrectly encodes and decodes true/false values
TestMarshalUnmarshal - positive intPositive integer encodingCorrectly encodes and decodes positive integers
TestMarshalUnmarshal - negative intNegative integer encodingCorrectly encodes and decodes negative integers
TestMarshalUnmarshal - zeroZero value encodingCorrectly encodes and decodes zero
TestMarshalUnmarshal - large intLarge integer encodingCorrectly encodes and decodes large integers (1000000)
TestMarshalUnmarshal - uintUnsigned integer encodingCorrectly encodes and decodes unsigned integers
TestMarshalUnmarshal - float64Float64 encodingCorrectly encodes and decodes float64 values
TestMarshalUnmarshal - stringString encodingCorrectly encodes and decodes strings
TestMarshalUnmarshal - empty stringEmpty string encodingCorrectly encodes and decodes empty strings
TestMarshalUnmarshal - long stringLong string encodingCorrectly encodes and decodes strings exceeding 31 bytes
TestMarshalArrayArray encoding/decodingCorrectly encodes and decodes arrays with multiple elements
TestMarshalMapMap encoding/decodingCorrectly encodes and decodes maps with string keys
TestMarshalBinaryBinary data encodingCorrectly encodes and decodes raw byte slices
TestResponseHTTP response generationSets correct Content-Type header and encodes response data
TestBindRequest body parsingCorrectly parses MessagePack request bodies
TestBodyRaw body retrievalRetrieves raw MessagePack body from context
TestEncoderIntegers - zeroZero integerEncodes/decodes zero correctly
TestEncoderIntegers - positive fixintPositive fixint (100)Uses optimized fixint encoding
TestEncoderIntegers - negative fixintNegative fixint (-20)Uses optimized negative fixint encoding
TestEncoderIntegers - int8 positiveint8 range (127)Uses int8 encoding
TestEncoderIntegers - int8 negativeint8 range (-128)Uses int8 encoding
TestEncoderIntegers - int16 positiveint16 range (1000)Uses int16 encoding
TestEncoderIntegers - int16 negativeint16 range (-1000)Uses int16 encoding
TestEncoderIntegers - int32 positiveint32 range (100000)Uses int32 encoding
TestEncoderIntegers - int32 negativeint32 range (-100000)Uses int32 encoding
TestEncoderIntegers - int64 positiveint64 range (5000000000)Uses int64 encoding
TestEncoderIntegers - int64 negativeint64 range (-5000000000)Uses int64 encoding
TestEncoderFloats - float32float32 encodingEncodes/decodes float32 with correct precision
TestEncoderFloats - float64float64 encodingEncodes/decodes float64 with correct precision
TestUnsupportedTypeUnsupported type errorReturns ErrUnsupportedType for custom structs
TestEmptyBufferEmpty buffer errorReturns error when unmarshaling empty buffer