Skip to main content

Overview

The envelope middleware wraps all responses in a consistent structure, adding metadata like status, pagination, and timestamps. Use it when you need:
  • Consistent API responses
  • Response metadata
  • Standardized error format

Installation

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

Quick Start

app := mizu.New()

app.Use(envelope.New())

app.Get("/users", func(c *mizu.Ctx) error {
    return c.JSON(200, users)
})
// Response: {"success": true, "data": [...users]}

Configuration

Options

OptionTypeDefaultDescription
SuccessKeystring"success"Success field name
DataKeystring"data"Data field name
ErrorKeystring"error"Error field name
IncludeTimestampboolfalseAdd timestamp
IncludeRequestIDboolfalseAdd request ID

Examples

Default Envelope

app.Use(envelope.New())
// Success: {"success": true, "data": {...}}
// Error: {"success": false, "error": "message"}

With Metadata

app.Use(envelope.WithOptions(envelope.Options{
    IncludeTimestamp: true,
    IncludeRequestID: true,
}))
// {"success": true, "data": {...}, "timestamp": "...", "request_id": "..."}

Custom Structure

app.Use(envelope.WithOptions(envelope.Options{
    SuccessKey: "ok",
    DataKey:    "result",
    ErrorKey:   "message",
}))
// {"ok": true, "result": {...}}

With Pagination

app.Use(envelope.New())

app.Get("/users", func(c *mizu.Ctx) error {
    envelope.SetMeta(c, map[string]any{
        "page":       1,
        "per_page":   20,
        "total":      100,
        "total_pages": 5,
    })
    return c.JSON(200, users)
})
// {"success": true, "data": [...], "meta": {"page": 1, ...}}

API Reference

Functions

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

// WithOptions creates with configuration
func WithOptions(opts Options) mizu.Middleware

// SetMeta adds metadata to response
func SetMeta(c *mizu.Ctx, meta map[string]any)

Response Format

Success Response

{
    "success": true,
    "data": { ... },
    "meta": { ... }
}

Error Response

{
    "success": false,
    "error": "Error message",
    "code": "ERROR_CODE"
}

Technical Details

Implementation Architecture

The envelope middleware uses a custom response writer (envelopeWriter) to intercept and capture the original response before wrapping it in the envelope structure.

Response Writer

The middleware captures responses through a buffer-based writer:
  • Intercepts WriteHeader() calls to capture HTTP status codes
  • Buffers response body through Write() calls
  • Stores status code (defaults to 200 if not explicitly set)

Envelope Construction

The envelope is constructed after the handler completes:
  1. Content-Type Check: Only wraps responses matching configured content types (default: application/json)
  2. Success Determination: Status codes 200-399 are considered successful
  3. Response Parsing: Original JSON response is unmarshaled into the data field
  4. Error Handling: For error responses, attempts to extract error message from:
    • error field in response body
    • message field in response body
    • Handler error if available
  5. Metadata Addition: When IncludeMeta is enabled, adds status code and request ID
  6. Re-encoding: Final envelope is marshaled to JSON and written to the original writer

Field Customization

All field names are customizable through options:
  • SuccessField: Controls the success indicator field name
  • DataField: Controls the data payload field name
  • ErrorField: Controls the error message field name

Content-Type Filtering

The middleware only wraps responses with matching content types:
  • Checks exact match or with charset suffix (e.g., application/json; charset=utf-8)
  • Non-matching responses pass through unmodified
  • Default content types: ["application/json"]

Helper Functions

The package provides convenience functions for common responses:
  • Success(): 200 OK with data
  • Created(): 201 Created with data
  • NoContent(): 204 No Content
  • BadRequest(): 400 Bad Request with error message
  • Unauthorized(): 401 Unauthorized with error message
  • Forbidden(): 403 Forbidden with error message
  • NotFound(): 404 Not Found with error message
  • InternalError(): 500 Internal Server Error with error message

Best Practices

  • Use consistent structure across APIs
  • Include relevant metadata
  • Document envelope format
  • Handle nested errors properly

Testing

The envelope middleware includes comprehensive tests covering all functionality:
Test CaseDescriptionExpected Behavior
TestNewDefault middleware initializationWraps response with success: true and data field
TestWithOptions_IncludeMetaMetadata inclusion with request IDIncludes meta object with status_code and request_id
TestWithOptions_CustomFieldsCustom field namesUses custom ok, result, and message fields
TestSuccessSuccess helper functionReturns 200 OK with success: true and data
TestErrorError helper functionReturns error status with success: false and error message
TestCreatedCreated helper functionReturns 201 Created status with success response
TestBadRequestBadRequest helper functionReturns 400 Bad Request with error message
TestUnauthorizedUnauthorized helper functionReturns 401 Unauthorized with error message
TestForbiddenForbidden helper functionReturns 403 Forbidden with error message
TestNotFoundNotFound helper functionReturns 404 Not Found with error message
TestInternalErrorInternalError helper functionReturns 500 Internal Server Error with error message
TestNoContentNoContent helper functionReturns 204 No Content without body