Implement Clean Architecture in Go by defining interfaces in your domain layer and injecting concrete implementations via dependency injection.
// domain/user.go
type UserRepository interface {
FindByID(id string) (*User, error)
}
// usecase/user_service.go
type UserService struct {
repo UserRepository
}
func NewUserService(repo UserRepository) *UserService {
return &UserService{repo: repo}
}
func (s *UserService) GetUser(id string) (*User, error) {
return s.repo.FindByID(id)
}
// delivery/http/handler.go
func NewHandler(svc *UserService) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
user, err := svc.GetUser(id)
if err != nil { w.WriteHeader(http.StatusNotFound); return }
json.NewEncoder(w).Encode(user)
})
}
// main.go
func main() {
repo := &postgresUserRepository{} // Concrete implementation
svc := usecase.NewUserService(repo)
http.ListenAndServe(":8080", delivery.NewHandler(svc))
}