Skip to main content

Overview

The multitenancy middleware extracts and provides tenant information for multi-tenant SaaS applications. It supports various resolution strategies including subdomain, header, path, and query parameters.

Installation

Quick Start

Configuration

Tenant Structure

Resolution Strategies

Subdomain Resolution

Header Resolution

Path Resolution

Query Parameter Resolution

Examples

Basic Subdomain Tenant

Database Lookup

Chain Multiple Resolvers

Custom Error Handler

Optional Tenant

MustGet (Panic on Missing)

Custom Resolver

Tenant-Scoped Database

Tenant Middleware Chain

Tenant Metadata

Built-in Resolvers

API Reference

Technical Details

Architecture

The multitenancy middleware uses Go’s context package to store and retrieve tenant information throughout the request lifecycle. It implements a resolver pattern that allows flexible tenant identification strategies.

Context Storage

The middleware stores tenant information in the request context using a private contextKey{} type. This ensures type safety and prevents key collisions with other middleware or application code.

Resolver Chain

The resolver pattern allows composing multiple tenant identification strategies:
  1. Each resolver implements the Resolver function type
  2. Resolvers return (*Tenant, error) allowing error propagation
  3. ChainResolver tries resolvers sequentially until one succeeds
  4. LookupResolver wraps a resolver with a database lookup function

Path Rewriting

The PathResolver automatically rewrites the request path to remove the tenant prefix:
This allows routes to be defined without tenant prefixes while maintaining tenant isolation.

Error Handling

The middleware supports both required and optional tenant resolution:
  • Required mode (default): Returns error via ErrorHandler when tenant not found
  • Optional mode: Continues request processing with nil tenant
  • Custom error handler: Allows application-specific error responses

Performance Considerations

  • Context lookups are O(1) operations
  • Subdomain parsing uses efficient string operations
  • Header lookups use Go’s optimized HTTP header map
  • Consider caching with LookupResolver for database-backed tenants

Best Practices

  • Use subdomain resolution for user-friendly URLs
  • Implement database lookup for rich tenant data
  • Use chain resolver for flexibility
  • Always validate tenant access to resources
  • Include tenant ID in all database queries
  • Cache tenant lookups for performance

Testing

The middleware includes comprehensive test coverage for all resolvers and scenarios: