Architecture Overview
ziegel is designed as a modular, layered framework that promotes separation of concerns and maintainable code architecture. This document explains the core architectural principles and how the packages work together.
Design Principles
1. Modular Architecture
Each ziegel package serves a specific purpose and can be used independently. This allows you to:
- Include only the functionality you need
- Minimize bundle size
- Reduce dependency complexity
- Enable incremental adoption
2. Layered Dependencies
ziegel follows a clear dependency hierarchy:
┌─────────────────────────────────────────┐
│ Applications │
├─────────────────────────────────────────┤
│ Platform Extensions │
│ (Analytics, Caching, HTTP, etc.) │
├─────────────────────────────────────────┤
│ Core Platform │
│ (ziegel-platform) │
├─────────────────────────────────────────┤
│ Foundation Layer │
│ (ziegel-core) │
└─────────────────────────────────────────┘3. Type Safety First
Every package is built with TypeScript-first design:
- Comprehensive type definitions
- Generic interfaces for extensibility
- Compile-time safety
- Excellent IntelliSense support
Package Categories
Core Foundation
- ziegel-core: Essential utilities, extensions, and base types
- ziegel-data: Data manipulation and validation utilities
Platform Services
- ziegel-platform: Core platform services and dependency injection
- ziegel-platform-http: HTTP client and networking utilities
- ziegel-platform-logging: Structured logging framework
- ziegel-platform-configuration: Configuration management
- ziegel-platform-caching: Caching strategies and implementations
Presentation Layer
- ziegel-presentation: UI component foundations
- ziegel-platform-presentation: Advanced presentation services
- ziegel-platform-navigation: Navigation and routing
Specialized Services
- ziegel-platform-analytics: Analytics and tracking
- ziegel-platform-messaging: Event-driven messaging
- ziegel-platform-localization: Multi-language support
- ziegel-platform-transaction: Transaction management
- ziegel-platform-translation: AI-powered translation services
Framework Integrations
- ziegel-redux: Redux integration utilities
- ziegel-rx: RxJS extensions and operators
- ziegel-intl: Internationalization support
- ziegel-intl-commerce: Commerce-specific i18n
- ziegel-intl-units: Unit conversion and formatting
Dependency Graph
The following diagram shows how packages depend on each other:
mermaid
graph TD
Core[ziegel-core]
Platform[ziegel-platform]
Data[ziegel-data]
Core --> Platform
Core --> Data
Platform --> PlatformHttp[ziegel-platform-http]
Platform --> PlatformLogging[ziegel-platform-logging]
Platform --> PlatformConfig[ziegel-platform-configuration]
Platform --> PlatformCaching[ziegel-platform-caching]
Core --> Presentation[ziegel-presentation]
Platform --> PlatformPresentation[ziegel-platform-presentation]
Core --> Intl[ziegel-intl]
Intl --> IntlCommerce[ziegel-intl-commerce]
Intl --> IntlUnits[ziegel-intl-units]Service Location Pattern
ziegel uses a service locator pattern for dependency injection:
typescript
import { ServiceLocator } from '@breadstone/ziegel-platform';
import { ILogger, LoggerManager } from '@breadstone/ziegel-platform-logging';
// Register services
ServiceLocator.register('logger', () => LoggerManager.getLogger('MyApp'));
// Use services
const logger = ServiceLocator.get<ILogger>('logger');
logger.info('Application started');Event-Driven Architecture
Many ziegel packages use reactive patterns:
typescript
import { EventAggregator } from '@breadstone/ziegel-platform';
import { fromEvent } from '@breadstone/ziegel-rx';
// Subscribe to events
const eventAggregator = new EventAggregator();
eventAggregator.subscribe('user-login', (user) => {
console.log('User logged in:', user);
});
// Publish events
eventAggregator.publish('user-login', { id: 1, name: 'John' });Configuration Management
Centralized configuration with environment-specific overrides:
typescript
import { ConfigurationManager } from '@breadstone/ziegel-platform-configuration';
const config = new ConfigurationManager();
config.addJsonFile('appsettings.json');
config.addJsonFile(`appsettings.${environment}.json`);
config.addEnvironmentVariables();
const apiUrl = config.getValue<string>('api.baseUrl');Error Handling Strategy
Consistent error handling across all packages:
typescript
import {
Exception,
ArgumentNullException,
InvalidOperationException
} from '@breadstone/ziegel-core';
// Use specific exception types
if (!user) {
throw new ArgumentNullException('user', 'User cannot be null');
}
// Handle errors consistently
try {
await performOperation();
} catch (error) {
if (error instanceof Exception) {
logger.error(error.message, error);
}
throw error;
}Best Practices
1. Package Selection
- Start with
ziegel-coreas your foundation - Add
ziegel-platformfor dependency injection and services - Include specialized packages only when needed
2. Dependency Injection
- Use interfaces for all service dependencies
- Register services at application startup
- Avoid direct instantiation in business logic
3. Error Handling
- Use ziegel's exception types for consistent error handling
- Implement proper logging throughout your application
- Handle errors at appropriate boundaries
4. Configuration
- Use the configuration system for all settings
- Separate configuration by environment
- Validate configuration at startup
5. Testing
- Each package includes comprehensive test coverage
- Use dependency injection for easier testing
- Mock external dependencies
Performance Considerations
- Lazy Loading: Packages support lazy loading of expensive resources
- Caching: Built-in caching strategies for frequently accessed data
- Bundle Optimization: Tree-shaking friendly exports
- Memory Management: Proper disposal patterns throughout
Next Steps
- Package Guide - Detailed information about each package
- Examples - Practical implementation examples
- Best Practices - Recommended patterns and practices