This document proposes a refactoring of the `edge-connect-client` project to a Hexagonal Architecture (also known as Ports and Adapters). This will improve the project's maintainability, testability, and flexibility.
## Current Architecture
The current project structure is a mix of concerns. The `cmd` package contains both CLI handling and business logic, the `sdk` package is a client for the EdgeXR API, and the `internal` package contains some business logic and configuration handling. This makes it difficult to test the business logic in isolation and to adapt the application to different use cases.
## Proposed Hexagonal Architecture
The hexagonal architecture separates the application's core business logic from the outside world. The core communicates with the outside world through ports (interfaces), which are implemented by adapters.
Here is the proposed directory structure:
```
.
├── cmd/
│ └── main.go
├── internal/
│ ├── core/
│ │ ├── domain/
│ │ │ ├── app.go
│ │ │ └── instance.go
│ │ ├── ports/
│ │ │ ├── driven/
│ │ │ │ ├── app_repository.go
│ │ │ │ └── instance_repository.go
│ │ │ └── driving/
│ │ │ ├── app_service.go
│ │ │ └── instance_service.go
│ │ └── services/
│ │ ├── app_service.go
│ │ └── instance_service.go
│ └── adapters/
│ ├── cli/
│ │ ├── app.go
│ │ └── instance.go
│ └── edgeconnect/
│ ├── app.go
│ └── instance.go
├── go.mod
└── go.sum
```
### Core
*`internal/core/domain`: Contains the core domain objects (e.g., `App`, `AppInstance`). These are plain Go structs with no external dependencies.
*`internal/core/ports`: Defines the interfaces for communication with the outside world.
*`driving`: Interfaces for the services offered by the application (e.g., `AppService`, `InstanceService`).
*`driven`: Interfaces for the services the application needs (e.g., `AppRepository`, `InstanceRepository`).
*`internal/core/services`: Implements the `driving` port interfaces. This is where the core business logic resides.
*`cmd/cli/main.go`: The main entry point of the CLI application. It is responsible for wiring everything together: creating the adapters, injecting them into the core services, and starting the CLI.
***Improved Testability:** The core business logic can be tested in isolation, without the need for the CLI framework or the EdgeXR API.
***Increased Flexibility:** The application can be easily adapted to different use cases by creating new adapters. For example, we could add a REST API by creating a new adapter.
***Better Separation of Concerns:** The hexagonal architecture enforces a clear separation between the business logic and the infrastructure, making the code easier to understand and maintain.