README
ΒΆ
EVSRC - Event Sourcing Framework for Go
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
- Architecture Guide - Design principles and patterns
- Project Guide - Detailed file structure explanation
- API Reference - HTTP API documentation (for cmd/server)
- Testing Guide - Testing strategies and utilities
π οΈ 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! π