About xConnect
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ xconnect: clean abstraction layer โ
โ for RabbitMQ, Redis and more โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
โณ lightweight, testable, production-ready

xconnect is a lightweight Go library providing unified interfaces and wrappers for external connection services like RabbitMQ, Redis and more.
The main goal is to abstract connection management and messaging operations, allowing you to unit test easily with mocks and seamlessly integrate into production systems.
๐ Why Use xconnect/rabbitmq
- Clean separation between transport and business logic.
- Easy-to-mock interfaces for unit tests without real brokers.
- Flexible architecture supporting both low-level access (publish/consume) and high-level Worker abstraction.
- Context-driven cancellation and graceful shutdowns.
- No external types leak into your application domain.
- Designed for real production systems with CI/CD in mind.
โจ Features
- Clean Go interfaces for messaging and data brokers
- Simple wrappers over popular libraries (e.g., streadway/amqp)
- Easy mocking for unit testing
- Support for both publishers and consumers
- High-level
Worker
abstraction for consuming queues elegantly
- Ready for CI/CD integration and local development
- No external types leaking through interfaces
๐ฆ Installation
go get github.com/eugene-ruby/xconnect
๐ Usage Examples
See full working examples in examples/rabbitmq
.
Producer (Publishing Messages)
// ... your producer code (unchanged) ...
Consumer (Receiving Messages)
// ... your consumer code (unchanged) ...
๐งช Mock Support for Unit Testing
xconnect
provides ready-to-use mocks for unit testing your applications without requiring a live RabbitMQ server.
- Available under
rabbitmq/mocks
.
- Provides
MockChannel
implementing rabbitmq.Channel
interface.
- Useful for testing publishers, workers, and custom logic.
Example:
import "github.com/eugene-ruby/xconnect/rabbitmq/mocks"
func TestPublish(t *testing.T) {
mock := mocks.NewMockChannel()
publisher := rabbitmq.NewPublisher(mock)
err := publisher.Publish(\"\", \"queue\", []byte(\"test message\"))
require.NoError(t, err)
}
โ
No need for real broker
โ
Instant feedback during development
๐ Full Example Applications
examples/rabbitmq
โ Basic Producer + Worker example with graceful shutdown.
examples/app
โ Full example of building an application using Publisher, Worker, and unit tests based on mocks.
RABBITMQ_URL=amqp://guest:guest@localhost:5672/ go run ./examples/rabbitmq/
2025/04/26 16:52:39 [Publisher] Published: message #1
2025/04/26 16:52:39 [Worker] Received: message #1
2025/04/26 16:52:40 [Publisher] Published: message #2
2025/04/26 16:52:40 [Worker] Received: message #2
2025/04/26 16:52:41 [Publisher] Published: message #3
2025/04/26 16:52:41 [Worker] Received: message #3
.....
๐ Local Development
Requirements
- Go 1.21+
- Docker and Docker Compose (for integration testing)
Useful Commands
Run unit tests:
make unit-test
Run integration tests (requires running RabbitMQ):
make integration-test
Run example client:
make run-example
Start RabbitMQ with Docker Compose:
make docker-up
Stop RabbitMQ:
make docker-down
๐ Project Structure
/rabbitmq/ # Core RabbitMQ interfaces and wrappers
/rabbitmq/mocks/ # Public mocks for unit testing (MockChannel, etc.)
/examples/rabbitmq/ # Basic live example (Publisher + Worker + graceful shutdown)
/examples/app/ # Full application example with unit tests using mocks
/tests/integration/ # Integration tests for RabbitMQ (real broker tests)
/cmd/ # (Reserved for CLI applications if needed)
/internal/ # (Reserved for internal utilities)
/docker-compose.test.yml # Docker Compose setup for integration testing
/go.mod # Go module definition
/go.sum # Go module checksum file
/README.md # Project documentation
๐ Worker Overview
General structure of Worker
in xconnect/rabbitmq
1. Interfaces and types
Channel
: abstraction for working with queues and messages.
Delivery
: structure describing a received message.
HandlerFunc func(Delivery) error
: function for handling messages.
Worker
: structure that manages subscription and message processing.
2. What does Worker
do?
- Subscribes to a queue using
Channel.Consume
.
- Starts a goroutine to read and handle messages via
HandlerFunc
.
- Listens for cancellation via
context.Context
.
- Waits for graceful shutdown using
sync.WaitGroup
.
3. Worker lifecycle
NewWorker() -> Start(ctx) -> Consume(queue) -> for msg in msgs -> HandlerFunc(msg) -> Wait()
๐ Redis Store Support
The xconnect/redisstore
package provides a minimal abstraction over Redis to store and retrieve data without exposing any dependency on go-redis
.
โ
Why
- Avoid tight coupling with
go-redis
- Use a clean and minimal
Client
interface
- Inject mocks for testing, or real clients in production
- Store any serialized format: JSON, protobuf, base64, etc.
๐ง Usage
import (
"github.com/redis/go-redis/v9"
"github.com/eugene-ruby/xconnect/redisstore"
)
// Real Redis connection
rdb := redis.NewClient(&redis.Options{Addr: "localhost:6379"})
adapter := redisstore.NewGoRedisAdapter(rdb)
store := redisstore.New(adapter)
store.Set(ctx, "mykey", "some-data", 10*time.Minute)
val, _ := store.Get(ctx, "mykey")
๐งช Unit Testing with Mocks
Use the built-in MockClient
for unit tests:
mock := redisstore.NewMockClient()
store := redisstore.New(mock)
store.Set(ctx, "test", "value", time.Minute)
val, _ := store.Get(ctx, "test")
โ
Features
-
Minimal Client
interface:
type Client interface {
Get(ctx context.Context, key string) (string, error)
Set(ctx context.Context, key string, value string, ttl time.Duration) error
}
-
Adapter for go-redis
-
Full Store
abstraction for app-level access
-
MockClient with in-memory map (thread-safe)
-
Integration tests with real Redis (make integration-test
)
๐ค Contributing
We welcome contributions!
Please open issues or submit pull requests.
- Follow Go best practices (
gofmt
, go vet
)
- Write clear, well-tested code
- Keep pull requests small and focused
๐ License
This project is licensed under the MIT License.