How to Implement Clean Architecture in Go

Implement Clean Architecture in Go by defining domain interfaces and injecting concrete implementations to decouple business logic from external dependencies.

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))
}