mirror of
https://github.com/Warky-Devs/ResolveSpec.git
synced 2025-09-13 17:01:30 +00:00
4.6 KiB
4.6 KiB
Migration Guide: Database and Router Abstraction
This guide explains how to migrate from the direct GORM/Router dependencies to the new abstracted interfaces.
Overview of Changes
What was changed:
- Database Operations: GORM-specific code is now abstracted behind
Database
interface - Router Integration: HTTP router dependencies are abstracted behind
Router
interface - Model Registry: Models are now managed through a
ModelRegistry
interface - Backward Compatibility: Existing code continues to work with
NewAPIHandler()
Benefits:
- Database Flexibility: Switch between GORM, Bun, or other ORMs without code changes
- Router Flexibility: Use Gorilla Mux, Gin, Echo, or other routers
- Better Testing: Easy to mock database and router interactions
- Cleaner Separation: Business logic separated from ORM/router specifics
Migration Path
Option 1: No Changes Required (Backward Compatible)
Your existing code continues to work without any changes:
// This still works exactly as before
handler := resolvespec.NewAPIHandler(db)
Option 2: Gradual Migration to New API
Step 1: Use New Handler Constructor
// Old way
handler := resolvespec.NewAPIHandler(gormDB)
// New way
handler := resolvespec.NewHandlerWithGORM(gormDB)
Step 2: Use Interface-based Approach
// Create database adapter
dbAdapter := resolvespec.NewGormAdapter(gormDB)
// Create model registry
registry := resolvespec.NewModelRegistry()
// Register your models
registry.RegisterModel("public.users", &User{})
registry.RegisterModel("public.orders", &Order{})
// Create handler
handler := resolvespec.NewHandler(dbAdapter, registry)
Switching Database Backends
From GORM to Bun
// Add bun dependency first:
// go get github.com/uptrace/bun
// Old GORM setup
gormDB, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
gormAdapter := resolvespec.NewGormAdapter(gormDB)
// New Bun setup
sqlDB, _ := sql.Open("sqlite3", "test.db")
bunDB := bun.NewDB(sqlDB, sqlitedialect.New())
bunAdapter := resolvespec.NewBunAdapter(bunDB)
// Handler creation is identical
handler := resolvespec.NewHandler(bunAdapter, registry)
Router Flexibility
Current Gorilla Mux (Default)
router := mux.NewRouter()
resolvespec.SetupRoutes(router, handler)
BunRouter (Built-in Support)
// Simple setup
router := bunrouter.New()
resolvespec.SetupBunRouterWithResolveSpec(router, handler)
// Or using adapter
routerAdapter := resolvespec.NewStandardBunRouterAdapter()
// Use routerAdapter.GetBunRouter() for the underlying router
Using Router Adapters (Advanced)
// For when you want router abstraction
routerAdapter := resolvespec.NewStandardRouter()
routerAdapter.RegisterRoute("/{schema}/{entity}", handlerFunc)
Model Registration
Old Way (Still Works)
// Models registered through existing models package
handler.RegisterModel("public", "users", &User{})
New Way (Recommended)
registry := resolvespec.NewModelRegistry()
registry.RegisterModel("public.users", &User{})
registry.RegisterModel("public.orders", &Order{})
handler := resolvespec.NewHandler(dbAdapter, registry)
Interface Definitions
Database Interface
type Database interface {
NewSelect() SelectQuery
NewInsert() InsertQuery
NewUpdate() UpdateQuery
NewDelete() DeleteQuery
// ... transaction methods
}
Available Adapters
GormAdapter
- For GORM (ready to use)BunAdapter
- For Bun (add dependency:go get github.com/uptrace/bun
)- Easy to create custom adapters for other ORMs
Testing Benefits
Before (Tightly Coupled)
// Hard to test - requires real GORM setup
func TestHandler(t *testing.T) {
db := setupRealGormDB()
handler := resolvespec.NewAPIHandler(db)
// ... test logic
}
After (Mockable)
// Easy to test - mock the interfaces
func TestHandler(t *testing.T) {
mockDB := &MockDatabase{}
mockRegistry := &MockModelRegistry{}
handler := resolvespec.NewHandler(mockDB, mockRegistry)
// ... test logic with mocks
}
Breaking Changes
- None for existing code - Full backward compatibility maintained
- New interfaces are additive, not replacing existing APIs
Recommended Migration Timeline
- Phase 1: Use existing code (no changes needed)
- Phase 2: Gradually adopt new constructors (
NewHandlerWithGORM
) - Phase 3: Move to interface-based approach when needed
- Phase 4: Switch database backends if desired
Getting Help
- Check example functions in
resolvespec.go
- Review interface definitions in
database.go
- Examine adapter implementations for patterns