Skip to content

Budget365 API Architecture

Overview

Budget365 API is built following clean architecture principles and SOLID design patterns. The project structure promotes separation of concerns, testability, and maintainability.

SOLID Principles Implementation

Single Responsibility Principle (SRP)

  • Each package has a single, well-defined responsibility
  • /internal/api: HTTP handlers for specific domains
  • /internal/services: Business logic implementation
  • /internal/repositories: Data access layer
  • /internal/models: Domain entities
  • /internal/config: Configuration management

Open/Closed Principle (OCP)

  • Code is open for extension but closed for modification
  • Interfaces: All core components depend on interfaces, allowing easy extension
  • Middleware: New middleware can be added without modifying existing code
  • Services: New services can be added by implementing existing interfaces

Liskov Substitution Principle (LSP)

  • Any implementation of an interface can be substituted without breaking functionality
  • Repository implementations: Any database can be used by implementing the repository interfaces
  • Service implementations: Business logic can be replaced by implementing service interfaces

Interface Segregation Principle (ISP)

  • Interfaces are focused and not monolithic
  • UserReader/UserWriter: Separate read and write operations
  • BudgetReader/BudgetWriter: Focused interfaces for specific operations
  • Clients only depend on methods they actually use

Dependency Inversion Principle (DIP)

  • High-level modules don't depend on low-level modules; both depend on abstractions
  • Services depend on repository interfaces, not concrete implementations
  • Handlers depend on service interfaces, not concrete implementations
  • Dependency injection is used throughout the application

Architecture Layers

┌─────────────────────────────────────────────────┐
│                 HTTP Layer                      │
│  (Handlers, Middleware, Routing)               │
├─────────────────────────────────────────────────┤
│                Business Layer                   │
│  (Services, Domain Logic, Validation)          │
├─────────────────────────────────────────────────┤
│               Data Access Layer                 │
│  (Repositories, Database Operations)            │
├─────────────────────────────────────────────────┤
│                Database Layer                   │
│  (PostgreSQL, GORM ORM)                        │
└─────────────────────────────────────────────────┘

Directory Structure

.
├── cmd/                   # Application entry points
│   ├── server/           # API server startup
│   └── migrate/          # Database migrations
├── internal/             # Private application code
│   ├── api/              # HTTP handlers
│   ├── routes/           # HTTP routing configuration
│   ├── services/         # Business logic layer
│   ├── repositories/     # Data access layer
│   ├── models/           # Domain models
│   ├── schema/           # Request/Response DTOs
│   │   ├── request/      # API request schemas
│   │   └── response/     # API response schemas
│   ├── config/           # Configuration management
│   ├── middleware/       # HTTP middleware
│   └── pkg/              # Internal utilities
│       ├── auth/         # Authentication utilities
│       ├── database/     # Database connection
│       ├── logging/      # Structured logging
│       ├── cache/        # Caching utilities
│       └── utils/        # Common helpers
├── docs/                 # Documentation
├── test/                 # Integration tests
├── scripts/              # Utility scripts
└── main.go               # Application entry point

Key Design Decisions

1. Interface-First Design

All core components are defined by interfaces first, then implemented. This allows for easy testing, mocking, and future changes.

2. Dependency Injection

Manual dependency injection is used throughout the application for better control and understanding of dependencies.

3. Error Handling

  • Structured error handling with context
  • Errors are logged at the service layer
  • API responses provide appropriate HTTP status codes

4. Logging

  • Structured logging with Zap
  • Request-scoped logging with correlation IDs
  • Configurable log levels and output formats

5. Configuration

  • Environment-based configuration with Viper
  • Sensible defaults for development
  • Clear separation of configuration concerns

Database Design

Models

  • User: Core user entity with authentication data
  • Budget: Budget tracking with user relationships
  • Category: Transaction categories (future enhancement)

Relationships

  • One-to-Many: User → Budgets
  • Many-to-Many: Budgets ↔ Categories (future)

API Design

RESTful Endpoints

  • Standard HTTP methods (GET, POST, PUT, DELETE)
  • Consistent response format with metadata
  • Pagination support for list endpoints
  • Error responses with meaningful messages

Response Format

{
  "success": true,
  "message": "Optional message",
  "data": { ... },
  "meta": {
    "page": 1,
    "limit": 10,
    "total": 100,
    "total_pages": 10
  }
}

Testing Strategy

Unit Tests

  • Each package should have comprehensive unit tests
  • Mock dependencies using interfaces
  • Test business logic in isolation

Integration Tests

  • Test complete request/response cycles
  • Use test database for data persistence tests
  • Test middleware and routing

Test Structure

internal/
├── services/
│   ├── user_service.go
│   └── user_service_test.go
├── repositories/
│   ├── user_repository.go
│   └── user_repository_test.go
└── api/
    ├── user.go
    └── user_test.go

Security Considerations

Authentication

  • JWT-based authentication (future implementation)
  • Password hashing with bcrypt
  • Secure secret management

Data Validation

  • Request validation at the API layer
  • Database constraints for data integrity
  • Sanitization of user inputs

HTTP Security

  • CORS middleware for cross-origin requests
  • Request timeout limits
  • Recovery middleware for panic handling

Future Enhancements

  1. Authentication & Authorization
  2. JWT implementation
  3. Role-based access control
  4. OAuth2 integration

  5. Advanced Features

  6. Caching layer with Redis
  7. Background job processing
  8. File upload handling
  9. Email notifications

  10. Monitoring & Observability

  11. Metrics collection
  12. Distributed tracing
  13. Health checks with dependencies

  14. Performance

  15. Database query optimization
  16. Response caching
  17. Connection pooling tuning