Project Structure
Sphere follows a pragmatic project structure that keeps code generation, server code, and business logic cleanly separated while staying fast to iterate on. The structure is based on the sphere-layout template and follows Go community best practices.
Overview
The project structure is designed to:
- Provide clear separation of concerns
- Support efficient code generation workflows
- Enable easy testing and development
- Scale from monolith to microservices
Directory Structure
├── api # Go files generated by Protobuf definitions
├── assets # Static files (e.g., UI assets, templates)
├── cmd # Application entry points
│ ├── app # Main application
│ └── tools # Developer tools
├── devops # DevOps and infrastructure files (e.g., Docker, CI/CD)
├── internal # Private application and library code
│ ├── biz # Business logic layer (use cases)
│ ├── config # Configuration loading and management
│ ├── pkg # Shared internal packages
│ │ ├── database # Database setup, including ent schemas and client
│ │ └── ... # Other shared utilities
│ ├── server # Server implementation (gRPC, HTTP)
│ └── service # Service layer implementing the API interfaces
├── proto # Protobuf source files (.proto)
├── scripts # Helper scripts for development
└── swagger # Generated Swagger/OpenAPI documentationKey Directories
At a glance, common top-level directories:
api/: Generated Go from.proto(do not edit)cmd/: Entrypoints and developer toolsinternal/: Private application code (service, biz, data, server)proto/: Protobuf contractsdevops/: CI/CD and infrastructurescripts/: Developer scripts and helpersswagger/: Generated OpenAPI assets
Layer Responsibilities
Transport Layer (internal/server/)
- HTTP request/response handling
- Protocol-specific concerns
- Middleware application
- Request routing
Service Layer (internal/service/)
- API contract implementation
- Request validation
- Response formatting
- Transport-agnostic logic
Business Layer (internal/biz/)
- Core business logic
- Use case orchestration
- Domain rules enforcement
- Transaction management
Data Layer (internal/pkg/database/)
- Data persistence
- Query optimization
- Schema management
- Database transactions
Notes
- Keep generated code under
api/separate and unedited - Group proto and services by domain + version (e.g.,
api.v1) - Add custom Make targets for project-specific tasks
- Modify the build process in the Makefile
However, maintain the core separation between generated code (api/), business logic (internal/biz/), and service implementations (internal/service/) to ensure code generation tools continue to work effectively.
Migration from Other Structures
If you’re migrating from other project layouts:
- From Standard Go Layout: Move business logic from
pkg/tointernal/biz/ - From DDD Layout: Align domain packages with proto package structure
- From Layered Architecture: Merge controller and service layers into
internal/service/ - From Hexagonal Architecture: Map ports/adapters to service/biz layers
The key is maintaining clear boundaries between transport, business logic, and data access while leveraging code generation for the transport layer.
Last updated on