Architecture
The API follows a layered architecture with clear separation of concerns.
Directory Structure
src/
├── controllers/v1/ # TSOA controllers (HTTP layer)
├── services/ # Business logic
├── data/
│ ├── entities/ # TypeORM entities
│ ├── repositories/ # Repository pattern
│ └── graph/ # Neo4j operations
├── security/ # Route guards & auth
├── producers/ # Service Bus message producers
├── consumers/ # Service Bus message consumers
├── authentication.ts # TSOA auth module
├── bindings.ts # IoC bindings
└── ioc.ts # IoC containerLayer Responsibilities
Controllers
- Handle HTTP requests/responses
- Validate input via TSOA decorators
- Delegate to services
- Apply security middleware
Services
- Business logic
- Orchestrate repository calls
- Handle transactions
- Emit domain events
Repositories
- Data access layer
- CRUD operations
- Query building
- Cache management
Graph Layer
- Neo4j operations
- Relationship queries
- CypherBuilder queries
Request Flow
Dependency Injection
The API uses typescript-ioc for dependency injection:
typescript
// bindings.ts
Container.bind(DataSource).factory(() => dataSource)
Container.bind(Redis).factory(() => redis)
// Controller
export class UserController extends Controller {
constructor(@Inject private service: UserService) {
super()
}
}Key Patterns
Repository Pattern
All repositories extend TypeormRepository<T>:
- Automatic CRUD with caching
- Event emission for side effects
- Paged query support
Route Guards
Security middleware chain:
AuthenticationMiddleware- Validates JWT/API keyAccountRouteGuard- Validates account accessAccessGuard- Permission-based accessSubscriptionGuard- Tier validation
Message Queues
Azure Service Bus for async operations:
- Producers create messages
- Consumers process in background
- Retries with exponential backoff