Skip to content

Commit e471101

Browse files
appleboyCopilot
andauthored
feat: unify store initialization with flexible option-based API (#92)
* feat: unify store initialization with flexible option-based API - Replace legacy initialization functions with a unified NewStore() using the Option Pattern - Add extensive configuration options for connection, authentication, Redis, and session settings - Implement strict validation for configuration and connection options at initialization - Remove code duplication and improve separation of concerns in store setup - Update documentation and usage examples for the new API - Add a comprehensive migration guide for upgrading from v1 to v2 - Update module path to github.com/boj/redistore/v2 for semantic versioning - Improve error messages and fail-fast behavior for invalid configurations - Add a new test suite with thorough coverage for option validation and error handling - Deprecate v1 API and document migration steps - Enhance developer experience with clearer, more flexible, and self-documenting options Signed-off-by: Bo-Yi Wu <[email protected]> * refactor: refactor error handling and option selection logic - Refactor error construction to use multiline return statements for clarity - Replace if-else chains with a switch statement for connection option selection - Update tests to build expected error strings in multiple lines for consistency with implementation Signed-off-by: Bo-Yi Wu <[email protected]> * feat: refactor key management to support key rotation and helpers - Change NewStore to accept key pairs as [][]byte instead of []byte, enabling proper support for key rotation - Add Keys and KeysFromStrings helper functions for easier key pair creation - Update documentation and migration guides to reflect the new key pairs format and usage - Add detailed examples and explanations for key rotation and helper usage - Update all code and tests to use the new key pairs format and helpers - Add tests for key rotation and the new helper functions Signed-off-by: Bo-Yi Wu <[email protected]> * Update redistore.go Co-authored-by: Copilot <[email protected]> * refactor: refactor Redis error handling to use shared constants - Refactor repeated Redis connection error strings into constants for improved maintainability - Update tests to use the new error constants instead of hardcoded error messages Signed-off-by: Bo-Yi Wu <[email protected]> --------- Signed-off-by: Bo-Yi Wu <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent 5c47f51 commit e471101

File tree

7 files changed

+2129
-199
lines changed

7 files changed

+2129
-199
lines changed

CHANGELOG.md

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [2.0.0] - 2026-01-13
9+
10+
### Breaking Changes
11+
12+
This is a major version update with breaking API changes. Please see [MIGRATION.md](MIGRATION.md) for detailed migration instructions.
13+
14+
#### Removed
15+
16+
- **`NewRediStore(size, network, address, username, password, keyPairs)`** - Replaced by `NewStore()` with `WithAddress()` option
17+
- **`NewRediStoreWithDB(size, network, address, username, password, db, keyPairs)`** - Replaced by `NewStore()` with `WithAddress()` and `WithDB()` options
18+
- **`NewRediStoreWithPool(pool, keyPairs)`** - Replaced by `NewStore()` with `WithPool()` option
19+
- **`NewRediStoreWithURL(size, url, keyPairs)`** - Replaced by `NewStore()` with `WithURL()` option
20+
21+
### Added
22+
23+
#### New API
24+
25+
- **`NewStore(keyPairs [][]byte, opts...)`** - New unified initialization function using Option Pattern
26+
27+
```go
28+
// Single key
29+
store, err := NewStore(
30+
[][]byte{[]byte("secret-key")},
31+
WithAddress("tcp", ":6379"),
32+
WithDB("1"),
33+
WithMaxLength(8192),
34+
)
35+
36+
// Multiple keys for key rotation
37+
store, err := NewStore(
38+
[][]byte{
39+
[]byte("new-auth-key"),
40+
[]byte("new-encrypt-key"),
41+
[]byte("old-auth-key"), // For decoding existing sessions
42+
[]byte("old-encrypt-key"),
43+
},
44+
WithAddress("tcp", ":6379"),
45+
)
46+
```
47+
48+
#### Key Rotation Support
49+
50+
- **Key pairs parameter changed from `[]byte` to `[][]byte`** - Enables proper support for encryption key rotation
51+
- Keys are provided as byte slice pairs (authentication key, encryption key)
52+
- First key pair is used for encoding new sessions
53+
- All key pairs are tried for decoding, allowing seamless key rotation without invalidating existing sessions
54+
55+
#### Helper Functions
56+
57+
- **`Keys(keys ...[]byte)`** - Convenience function to create key pairs from byte slices
58+
59+
```go
60+
store, err := NewStore(Keys([]byte("key")), WithAddress("tcp", ":6379"))
61+
```
62+
63+
- **`KeysFromStrings(keys ...string)`** - Most convenient way to create key pairs from strings
64+
65+
```go
66+
store, err := NewStore(KeysFromStrings("secret-key"), WithAddress("tcp", ":6379"))
67+
```
68+
69+
These helpers simplify the creation of key pairs, eliminating the need to write `[][]byte{[]byte(...)}` every time.
70+
71+
#### Connection Options
72+
73+
- **`WithPool(pool)`** - Use custom Redis connection pool
74+
- **`WithAddress(network, address)`** - Connect using network protocol and address
75+
- **`WithURL(url)`** - Connect using Redis URL
76+
77+
#### Authentication Options
78+
79+
- **`WithAuth(username, password)`** - Set username and password for Redis authentication
80+
- **`WithPassword(password)`** - Set password only (convenience function)
81+
82+
#### Redis Configuration Options
83+
84+
- **`WithDB(db)`** - Set Redis database index as string ("0"-"15")
85+
- **`WithDBNum(dbNum)`** - Set Redis database index as integer (0-15)
86+
- **`WithPoolSize(size)`** - Set connection pool size (default: 10)
87+
- **`WithIdleTimeout(timeout)`** - Set connection idle timeout (default: 240s)
88+
89+
#### Store Configuration Options
90+
91+
- **`WithMaxLength(length)`** - Set maximum session data size (default: 4096 bytes)
92+
- **`WithKeyPrefix(prefix)`** - Set Redis key prefix (default: "session\_")
93+
- **`WithDefaultMaxAge(age)`** - Set default TTL in seconds (default: 1200)
94+
- **`WithSerializer(serializer)`** - Set session serializer (default: GobSerializer)
95+
- **`WithSessionOptions(opts)`** - Set full session options
96+
- **`WithPath(path)`** - Set cookie path (default: "/")
97+
- **`WithMaxAge(age)`** - Set cookie MaxAge (default: 30 days)
98+
99+
#### Testing
100+
101+
- **`redistore_options_test.go`** - Comprehensive test suite for option validation
102+
- Added 23+ new tests covering:
103+
- Configuration validation
104+
- Error handling
105+
- Option combinations
106+
- Default values
107+
108+
### Changed
109+
110+
- Module path updated to `github.com/boj/redistore/v2` for v2 versioning
111+
- Improved error messages with detailed context
112+
- Configuration validation moved to initialization time (fail fast)
113+
114+
### Improved
115+
116+
- **Code Quality**
117+
118+
- Eliminated code duplication across initialization functions
119+
- Better separation of concerns with internal configuration structures
120+
- More maintainable and extensible codebase
121+
122+
- **API Design**
123+
124+
- Self-documenting option names
125+
- Compile-time validation of configuration
126+
- Flexible option combinations
127+
- Better default values
128+
129+
- **Developer Experience**
130+
- Single entry point reduces learning curve
131+
- Options can be applied in any order
132+
- Clear error messages for invalid configurations
133+
- Comprehensive documentation
134+
135+
### Fixed
136+
137+
- Connection validation now happens during initialization (not on first use)
138+
- Better handling of nil values in configuration
139+
- Improved database number validation (0-15 range)
140+
141+
### Documentation
142+
143+
- **Added `MIGRATION.md`** - Comprehensive migration guide from v1 to v2
144+
- **Added `CHANGELOG.md`** - Version history and change tracking
145+
- Updated all code examples to use new API
146+
- Improved inline documentation with examples
147+
148+
### Technical Details
149+
150+
#### Internal Changes
151+
152+
- Added `Option` function type for configuration
153+
- Added `storeConfig` struct for internal configuration management
154+
- Added `addressConfig` struct for network address configuration
155+
- Implemented `defaultConfig()` for sensible defaults
156+
- Implemented `validate()` for configuration validation
157+
- Implemented `buildPool()` for pool creation from configuration
158+
159+
#### Compatibility
160+
161+
- **Go Version**: Requires Go 1.23+
162+
- **Dependencies**: No changes to external dependencies
163+
- `github.com/gomodule/redigo v1.9.3`
164+
- `github.com/gorilla/securecookie v1.1.2`
165+
- `github.com/gorilla/sessions v1.4.0`
166+
167+
## [1.0.0] - Previous Releases
168+
169+
For changes prior to v2.0.0, please refer to the git history.
170+
171+
### v1 API (Deprecated)
172+
173+
The v1 API included four initialization functions:
174+
175+
- `NewRediStore()` - Basic initialization
176+
- `NewRediStoreWithDB()` - With database selection
177+
- `NewRediStoreWithPool()` - With custom pool
178+
- `NewRediStoreWithURL()` - With Redis URL
179+
180+
These have been replaced by the unified `NewStore()` function with options in v2.
181+
182+
---
183+
184+
## Migration Guide
185+
186+
See [MIGRATION.md](MIGRATION.md) for step-by-step instructions on upgrading from v1 to v2.
187+
188+
## Support
189+
190+
- **Issues**: https://github.com/boj/redistore/issues
191+
- **Discussions**: https://github.com/boj/redistore/discussions
192+
- **Documentation**: https://pkg.go.dev/github.com/boj/redistore/v2

0 commit comments

Comments
 (0)