evsrc

module
v0.0.0-...-3c1f1b8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 17, 2025 License: MIT

README ΒΆ

EVSRC - Event Sourcing Framework for Go

Go Version Go Report Card

EVSRC is a production-ready Event Sourcing and CQRS framework for Go applications. It provides the building blocks to implement event-driven architectures with complete audit trails, time-travel capabilities, and scalable read models.

πŸš€ Features

Core Event Sourcing
  • Event Store: Append-only event persistence with PostgreSQL
  • Aggregate Root: DDD-compliant aggregate base classes
  • Event Sourcing: Complete state reconstruction from events
  • Optimistic Concurrency: Built-in conflict detection and resolution
CQRS Implementation
  • Command Bus: Type-safe command routing and handling
  • Query Bus: Optimized read model queries
  • Projections: Automated read model generation from events
  • Event Bus: Reactive event publishing and subscription
Production Ready
  • High Performance: Optimized for throughput and low latency
  • Scalability: Horizontal scaling support
  • Observability: Structured logging and metrics
  • Testing: Comprehensive test utilities

πŸ“¦ Installation

go get github.com/scelaryus/evsrc

πŸ—οΈ Quick Start

1. Define Your Domain Events
import "github.com/scelaryus/evsrc/internal/domain"

type UserRegistered struct {
    UserID string `json:"user_id"`
    Email  string `json:"email"`
    Name   string `json:"name"`
}

func (e UserRegistered) EventType() string { return "user_registered" }
2. Create Your Aggregate
import "github.com/scelaryus/evsrc/internal/domain"

type User struct {
    domain.AggregateRoot
    Email    string
    Name     string
    IsActive bool
}

func (u *User) Register(email, name string) error {
    if u.Email != "" {
        return errors.New("user already registered")
    }
    
    event := UserRegistered{
        UserID: u.ID().String(),
        Email:  email,
        Name:   name,
    }
    
    u.RaiseEvent(event)
    return nil
}

func (u *User) On(event interface{}) {
    switch e := event.(type) {
    case UserRegistered:
        u.Email = e.Email
        u.Name = e.Name
        u.IsActive = true
    }
}
3. Setup Event Store
import (
    "github.com/scelaryus/evsrc/internal/infrastructure"
    "github.com/scelaryus/evsrc/internal/application"
)

// Initialize event store
eventStore, err := infrastructure.NewPostgreSQLEventStore(databaseURL)
if err != nil {
    log.Fatal(err)
}

// Create repository
repo := application.NewAggregateRepository(eventStore)

// Create command bus
commandBus := application.NewCommandBus()
4. Handle Commands
type RegisterUserCommand struct {
    UserID string
    Email  string
    Name   string
}

type UserCommandHandler struct {
    repo *application.AggregateRepository
}

func (h *UserCommandHandler) Handle(cmd RegisterUserCommand) error {
    user := &User{}
    user.SetID(uuid.MustParse(cmd.UserID))
    
    if err := user.Register(cmd.Email, cmd.Name); err != nil {
        return err
    }
    
    return h.repo.Save(user)
}
5. Query with Projections
type UserSummaryProjection struct {
    infrastructure.BaseProjection
}

func (p *UserSummaryProjection) Handle(event interface{}) error {
    switch e := event.(type) {
    case UserRegistered:
        return p.Store.Save("user_summary", e.UserID, map[string]interface{}{
            "user_id": e.UserID,
            "email":   e.Email,
            "name":    e.Name,
            "status":  "active",
        })
    }
    return nil
}

πŸ“š Framework Structure

github.com/scelaryus/evsrc/
β”œβ”€β”€ internal/
β”‚   β”œβ”€β”€ domain/           # Core domain types and aggregate base
β”‚   β”œβ”€β”€ infrastructure/   # Event store and external integrations
β”‚   └── application/      # CQRS implementation and services
β”œβ”€β”€ examples/             # Working examples and demos
β”œβ”€β”€ migrations/           # Database schema migrations
└── cmd/                  # Optional tools and utilities

πŸ›οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Application Layer                        β”‚
β”‚  πŸ“¦ Commands β€’ Queries β€’ Projections β€’ Event Bus          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Domain Layer                             β”‚
β”‚  πŸ—οΈ Aggregates β€’ Events β€’ Domain Logic                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Infrastructure Layer                     β”‚
β”‚  πŸ—„οΈ Event Store β€’ Database β€’ HTTP β€’ Messaging             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ’Ό Use Cases

Perfect For:
  • Financial Systems: Complete audit trails and transaction history
  • E-commerce Platforms: Order processing and inventory management
  • User Management: Account lifecycle and activity tracking
  • IoT Applications: Time-series data and device state management
  • Analytics Platforms: Event-driven data processing pipelines
Framework Benefits:
  • Audit Compliance: Every change is recorded as an immutable event
  • Time Travel: Query system state at any point in time
  • Scalability: Separate read and write concerns for optimal performance
  • Flexibility: Easy to add new projections and query models
  • Reliability: Event sourcing provides natural disaster recovery

πŸš€ Examples

Check out the examples directory for complete working implementations:

  • User Management: Registration, updates, and querying
  • Demo Application: End-to-end example with HTTP API
  • Testing Examples: Unit and integration test patterns

πŸ§ͺ Testing Your Implementation

# Run framework tests
go test ./internal/...

# Test with coverage
go test -cover ./internal/...

# Run example tests
go test ./examples/...

πŸ“– Documentation

πŸ› οΈ Framework Development

To contribute to or modify the framework:

# Clone the repository
git clone https://github.com/scelaryus/evsrc.git
cd evsrc

# Install dependencies
go mod tidy

# Run all tests
go test ./...

# Run the demo
go run examples/demo/main.go

🀝 Integration Examples

Web APIs

Use with any HTTP framework (Gin, Echo, Gorilla Mux) by importing the framework components.

gRPC Services

Integrate with gRPC servers for high-performance microservices.

Message Queues

Connect to Kafka, RabbitMQ, or other message brokers for distributed processing.

Mobile Backends

Perfect foundation for mobile app backends requiring audit trails and offline sync.

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • Inspired by EventStore and Axon Framework
  • Built with Go's excellent concurrency primitives
  • PostgreSQL for reliable event persistence

Ready to build event-driven applications? Import EVSRC into your project and start building scalable, auditable systems today! πŸš€

Directories ΒΆ

Path Synopsis
cmd
migrate command
server command
demo command
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL