go-saas

repository·main·Indexed 43 days ago

https://github.com/go-saas/saas

A headless Go framework for providing multi-tenancy solutions in monolithic SaaS applications. It supports single-tenancy (separate databases), multi-tenancy (shared databases with filtering), and hybrid models. It integrates with web frameworks like gin, iris, net/http, and kratos, and ORMs including gorm and ent.

Tokens
11K
Snippets
52
Records
66
Agent score
56%

What's inside go-saas

  1. Overview of go-saas multi-tenancy capabilities

    main

    go-saas is a headless (UI-less) multi-tenancy framework for Go. It is designed for simple or monolithic (Web) projects. For microservices-based solutions, use go-saas-kit instead.

    Key features include:

    • Flexible Data Storage Models:
      • Database-per-tenant: Each tenant has its own dedicated database.
      • Shared database: Tenants share a database, with isolation provided at the data access layer.
      • Hybrid mode: A combination of both models.
      • Custom Resolver: Ability to implement your own Resolver for advanced logic like sharding.
    • Web Framework Support:
      • gin
      • net/http
      • kratos
    • Automatic Data Isolation:
      • Supports gorm for automatic data isolation when using a shared database model.
    • Custom Tenant Resolution:
      • Supports extracting tenant information from: Query String, Form parameters, Headers, Cookies, and Domain formats.
    • Lifecycle Management:
      • Handles initialization and database migrations for tenants upon creation or version upgrades.
    • Gateway Integration:
      • Supports integration with apisix.
  2. Supported frameworks and ORMs in go-saas

    main

    go-saas is designed to be flexible and integrates with various web frameworks and ORMs:

    Web Frameworks:

    • gin
    • iris
    • net/http
    • kratos

    ORMs (with data filtering support):

    • gorm
    • ent

    Gateway Integration:

    • apisix
  3. How tenant resolution works in go-saas

    main

    The framework uses a TenantResolver to identify the tenant from an incoming request. Once identified, the tenant information is stored in a Tenant Context. This context is then used by a ConnectionString Resolver to determine which database connection to use for the request.

    Supported methods for resolving a tenant include:

    • Query String
    • Form parameters
    • Header
    • Cookie
    • Domain format
  4. How go-saas handles multi-tenancy

    main

    go-saas is a headless framework designed for building SaaS (multi-tenant) applications in Go, specifically optimized for monolithic (web) projects. It manages tenant isolation through several database architectures:

    • Single-tenancy: Each tenant has its own dedicated database.
    • Multi-tenancy: Multiple tenants share a single database, using data filtering mechanisms to ensure privacy.
    • Hybrid models: A combination of the above approaches.

    Users can implement custom resolvers to achieve advanced patterns like database sharding.

  5. How go-saas request processing and tenant resolution works

    main

    The framework follows a specific flow to identify tenants and route data requests:

    1. Incoming Request: A request arrives containing tenant identifiers in various formats (cookie, domain, form, header, query, etc.).
    2. TenantResolver: The framework uses a TenantResolver to extract the tenant identity from the request.
    3. Tenant Context: The identified tenant is injected into the request context.
    4. ConnectionString Resolver: Based on the tenant context, a ConnectionString Resolver determines which database connection to use.
    5. Data Access:
      • For dedicated databases, the resolver provides a direct connection to the tenant's specific database.
      • For shared databases, a Data Filter is applied to the ORM to ensure data isolation within the shared schema.
  6. Embed go-saas mixins into your Ent schema

    main

    To add multi-tenancy capabilities to your Ent entities, embed the sent.HasTenant mixin into your schema definition. This is done by implementing the Mixin() method on your schema struct and returning the sent.HasTenant{} mixin.

    import (
    	"github.com/go-saas/saas/ent"
    )
    
    // Post holds the schema definition for the Post entity.
    type Post struct {
        ent.Schema
    }
    
    func (Post) Mixin() []ent.Mixin {
        return []ent.Mixin{
            sent.HasTenant{},
        }
    }
  7. Enable EntQL Filtering and Privacy Layer for go-saas

    main

    To use the advanced filtering and privacy features provided by the go-saas Ent adapter, you must enable the intercept and schema/snapshot feature flags in your Ent code generation command. Modify your ent/generate.go file to include these flags.

    go generate ... --feature intercept,schema/snapshot ...
  8. Access data in the GORM example

    main

    Once the example is running (default port 8090), you can access data using different multi-tenancy strategies via URL query parameters:

    • Host side (Shared Database): Access global data at /posts.
    • Multi-tenancy (Shared Database): Access tenant-specific data using the __tenant query parameter (e.g., ?__tenant=1).
    • Single-tenancy (Separate Database): Access tenants that have their own dedicated database using the __tenant query parameter (e.g., ?__tenant=3).
    Host side: http://localhost:8090/posts
    
    Multi-tenancy (shared db): http://localhost:8090/posts?__tenant=1
    
    Single-tenancy (separate db): http://localhost:8090/posts?__tenant=3
  9. Integrate Apisix with go-runner

    main

    To use the Apisix gateway integration within your go-runner application, you must import the github.com/go-saas/saas/gateway/apisix package with a blank identifier to trigger its side effects. After importing, call apisix.InitTenantStore(ts) to initialize the tenant store with your provided tenant store instance (ts).

    This integration is based on the apache/apisix-go-plugin-runner.

    import _ "github.com/go-saas/saas/gateway/apisix"
    
    // ... inside your setup logic
    apisix.InitTenantStore(ts)
  10. Run the GORM example project

    main

    The GORM example demonstrates a combination of go-saas, gin, and gorm using different database drivers. You can run the example using sqlite3 (default), mysql, or postgres (via pgx).

    For mysql or postgres, ensure you have docker-compose up -d running to provide the database infrastructure.

    # Run with sqlite3
    go run github.com/go-saas/saas/examples/gorm
    
    # Run with mysql
    docker-compose up -d
    go run github.com/go-saas/saas/examples/gorm --driver mysql
    
    # Run with postgres
    docker-compose up -d
    go run github.com/go-saas/saas/examples/gorm --driver pgx
  11. Explore go-saas sample projects

    main

    To see how to integrate go-saas with specific frameworks and ORMs, refer to these example repositories:

    • GORM + Gin: example-gorm (supports sqlite/mysql)
    • Ent + Gin: example-ent (supports sqlite)

    If you require a microservice-compatible architecture instead of a monolith, use go-saas-kit.