A comprehensive toolkit for building event-driven applications in Go, following the CNCF CloudEvents specification. This monorepo contains three complementary modules that work together to provide a complete event sourcing and messaging solution.
A lightweight Go library providing CloudEvents-compatible event types and validation.
- β
CloudEvents-compliant
Eventstruct - π Built-in validation with clear error messages
- π§ Safe constructors and JSON parsing helpers
- π Minimal dependencies (only UUID generation)
event, err := event.New(event.Candidate{
Type: "com.example.user.created:v1",
Source: "https://api.example.com",
Subject: "/users/123",
Data: map[string]any{"name": "John Doe"},
})An in-memory event-sourcing database with persistence and indexing capabilities.
- πΎ Fast in-memory event storage with JSON persistence
- π Indexed queries by event type and subject
- π HTTP API for external integrations
- π³ Docker-ready with volume mounting support
- π‘οΈ Graceful shutdown with automatic data persistence
curl -X POST http://localhost:5000/add \
-H "Content-Type: application/json" \
-d '{"type": "user.created", "source": "api", "subject": "/users/123", "data": {...}}'An asynchronous message queue for reliable event delivery to webhooks.
- β‘ High-performance Go channel-based queueing
- π Reliable webhook delivery with retry logic
- π Configurable capacity and delivery settings
- π HTTP API for event submission
- π³ Production-ready Docker deployment
curl -X POST http://localhost:3000 \
-H "Content-Type: application/json" \
-d '{"type": "order.created", "source": "shop", "subject": "/orders/456", "data": {...}}'Each module can be used independently in your Go projects:
# Install the event library
go get github.com/nicograef/cloudevents/event
# Install the database module
go get github.com/nicograef/cloudevents/database
# Install the queue module
go get github.com/nicograef/cloudevents/queueCreate a complete event-driven system with all three components:
# docker-compose.yml
version: "3.8"
services:
database:
image: github.com/nicograef/cloudevents/database
ports:
- "5000:5000"
environment:
- DATA_DIR=/data
volumes:
- ./data:/data
queue:
image: github.com/nicograef/cloudevents/queue
ports:
- "3000:3000"
environment:
- CAPACITY=1000
- CONSUMER_URL=http://your-webhook-endpointdocker-compose up -dClone and run locally for development:
git clone https://github.com/nicograef/cloudevents.git
cd cloudevents
# Run the database
cd database && go run .
# Run the queue (in another terminal)
cd queue && go run .The modules work together to provide a complete event-driven architecture:
βββββββββββββββ HTTP POST βββββββββββββββ Webhooks βββββββββββββββ
β Client β βββββββββββββββΊ β Queue β ββββββββββββββΊ β Consumer β
β Application β β β β Services β
βββββββββββββββ βββββββββββββββ βββββββββββββββ
β β
β HTTP POST β Optional: Store events
βΌ βΌ
βββββββββββββββ βββββββββββββββ
β Database β β Database β
β (Events) β β (Audit) β
βββββββββββββββ βββββββββββββββ
Event Flow:
- Clients submit events to the Queue via HTTP
- Queue delivers events to configured webhook endpoints
- Database stores events for querying and audit trails
- Event library ensures consistent CloudEvents format across all components
Each module supports environment-based configuration:
| Module | Variable | Default | Description |
|---|---|---|---|
| Database | PORT |
5000 |
HTTP server port |
| Database | DATA_DIR |
. |
Data persistence directory |
| Queue | PORT |
3000 |
HTTP server port |
| Queue | CAPACITY |
1000 |
Max queued messages |
| Queue | CONSUMER_URL |
http://localhost:4000 |
Webhook delivery endpoint |
package main
import (
"fmt"
"github.com/nicograef/cloudevents/database/database"
"github.com/nicograef/cloudevents/event"
)
func main() {
// Create event
candidate := event.Candidate{
Type: "com.example.user.signup:v1",
Source: "https://myapp.com",
Subject: "/users/123",
Data: map[string]any{"email": "user@example.com"},
}
// Store in database
db := database.New()
storedEvent, err := db.AddEvent(candidate)
if err != nil {
panic(err)
}
fmt.Printf("Event stored with ID: %s\n", storedEvent.ID)
// Query events
userEvents := db.GetEventsBySubject("/users/123")
fmt.Printf("Found %d events for user\n", len(userEvents))
}# Submit to queue for delivery
curl -X POST http://localhost:3000 \
-H "Content-Type: application/json" \
-d '{
"type": "com.shop.order.created:v1",
"source": "https://shop.example.com",
"subject": "/orders/12345",
"data": {"amount": 99.99, "currency": "USD"}
}'
# Store in database for querying
curl -X POST http://localhost:5000/add \
-H "Content-Type: application/json" \
-d '{
"type": "com.shop.order.created:v1",
"source": "https://shop.example.com",
"subject": "/orders/12345",
"data": {"amount": 99.99, "currency": "USD"}
}'Run tests across all modules:
# Using Make (recommended)
make test
# Test all modules manually
find . -name "go.mod" -execdir go test ./... \;
# Test individual modules
cd event && go test ./...
cd database && go test ./...
cd queue && go test ./...
# Run integration tests
make integration-testThe repository uses GitHub Actions for automated testing with smart path-based triggering:
- Module-specific CI: Only runs tests for modules that have changes
- Integration tests: Runs when multiple modules change
- Security scanning: Weekly dependency and vulnerability checks
- Automated releases: Builds and publishes Docker images on tags
CI Workflows:
ci.yml- Main CI pipeline with path filterssecurity.yml- Security scanning and dependency checksrelease.yml- Automated releases with Docker images
Workflow triggers:
- Changes to
event/β Event module CI - Changes to
database/β Database module CI + Docker build - Changes to
queue/β Queue module CI + Docker build - Multiple module changes β Integration tests
- Tagged releases β Automated release with binaries and Docker images
Example deployment manifests:
# database-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: cloudevents-database
spec:
replicas: 1
selector:
matchLabels:
app: cloudevents-database
template:
metadata:
labels:
app: cloudevents-database
spec:
containers:
- name: database
image: github.com/nicograef/cloudevents/database
ports:
- containerPort: 5000
env:
- name: DATA_DIR
value: /data
volumeMounts:
- name: data-volume
mountPath: /data
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: database-pvc# docker-stack.yml
version: "3.8"
services:
database:
image: github.com/nicograef/cloudevents/database
deploy:
replicas: 1
environment:
DATA_DIR: /data
volumes:
- database-data:/data
ports:
- "5000:5000"
queue:
image: github.com/nicograef/cloudevents/queue
deploy:
replicas: 3
environment:
CAPACITY: 5000
CONSUMER_URL: http://your-webhook-service
ports:
- "3000:3000"
volumes:
database-data:We welcome contributions! Here's how to get started:
- Fork the repository
- Clone your fork:
git clone https://github.com/yourusername/cloudevents.git - Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes and add tests
- Test everything:
find . -name "go.mod" -execdir go test ./... \; - Commit your changes:
git commit -m 'Add amazing feature' - Push to your branch:
git push origin feature/amazing-feature - Open a Pull Request
- Follow Go best practices and
gofmtformatting - Add tests for new functionality
- Update documentation and examples
- Ensure backwards compatibility when possible
- Keep modules loosely coupled
- Clustering support for horizontal scaling
- Event replay capabilities in database
- Dead letter queues in queue module
- Metrics and observability endpoints
- gRPC APIs alongside HTTP
- Stream processing capabilities
- Event schema registry integration
- CloudEvents Specification - Official CNCF specification
- CloudEvents SDK - Official Go SDK
- EventStore - Production event sourcing database
- Apache Kafka - Distributed event streaming platform
- NATS - Cloud native messaging system
This project is licensed under the MIT License - see the LICENSE file for details.
- π Documentation: Check individual module READMEs for detailed usage
- π Bug Reports: Open an issue
- π‘ Feature Requests: Start a discussion
- π§ Contact: nico@example.com
Built with β€οΈ for the event-driven future