Implement the repository pattern by defining an interface for your data operations and creating a struct that implements it to interact with your data source. This separates your business logic from data access details.
// Define the interface
type UserRepository interface {
GetByID(id int) (*User, error)
Save(user *User) error
}
// Implement the interface
type PostgresUserRepository struct {
db *sql.DB
}
func (r *PostgresUserRepository) GetByID(id int) (*User, error) {
var user User
err := r.db.QueryRow("SELECT * FROM users WHERE id = $1", id).Scan(&user.ID, &user.Name)
return &user, err
}
func (r *PostgresUserRepository) Save(user *User) error {
_, err := r.db.Exec("INSERT INTO users (id, name) VALUES ($1, $2)", user.ID, user.Name)
return err
}