Skip to content

Frequently Asked Questions (FAQ) ​

This FAQ covers common questions, issues, and solutions when working with the ziegel library ecosystem.

General Questions ​

What is ziegel? ​

Q: What is ziegel and what problems does it solve?

A: ziegel is a comprehensive, modular TypeScript framework designed for building enterprise-grade applications. It provides:

  • Modular Architecture: Pick only the packages you need
  • Enterprise Features: Logging, caching, configuration, analytics, and more
  • Type Safety: Full TypeScript support with comprehensive type definitions
  • Scalability: Designed for large-scale applications and teams
  • Developer Experience: Intuitive APIs and extensive documentation

Getting Started ​

Q: How do I get started with ziegel?

A: Start by installing the core package:

bash
npm install @breadstone/ziegel-core

Then add additional packages as needed:

bash
npm install @breadstone/ziegel-platform-http
npm install @breadstone/ziegel-data

Check our Getting Started guide for detailed instructions.

Q: Which packages do I need for my project?

A: It depends on your requirements:

  • Web applications: ziegel-core, ziegel-platform-http, ziegel-data
  • APIs/Services: ziegel-core, ziegel-platform, ziegel-platform-logging
  • Internationalization: ziegel-intl, ziegel-intl-units, ziegel-intl-commerce
  • Frontend apps: ziegel-core, ziegel-presentation, ziegel-rx

See our Architecture guide for detailed recommendations.

Q: Can I use ziegel with existing projects?

A: Yes! ziegel is designed to be incrementally adoptable. You can start by adding individual packages to existing projects without major refactoring.

Installation and Setup ​

Package Management ​

Q: Why do I get peer dependency warnings?

A: ziegel packages have peer dependencies to avoid version conflicts. Install the required peer dependencies:

bash
# Check peer dependencies
npm ls --depth=0

# Install missing peer dependencies
npm install typescript tslib reflect-metadata

Q: Can I use ziegel with different package managers?

A: Yes, ziegel works with:

  • npm: npm install @breadstone/ziegel-core
  • Yarn: yarn add @breadstone/ziegel-core
  • pnpm: pnpm add @breadstone/ziegel-core

TypeScript Configuration ​

Q: What TypeScript configuration is required?

A: Minimum tsconfig.json configuration:

json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "lib": ["ES2020"],
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  }
}

Q: Do I need to enable decorators?

A: Yes, some ziegel features require decorators. Enable them in your tsconfig.json:

json
{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

And import reflect-metadata at your application entry point:

typescript
import 'reflect-metadata';

Core Package ​

Guid and DateTime ​

Q: Why should I use ziegel's Guid instead of crypto.randomUUID()?

A: ziegel's Guid provides:

  • Cross-platform compatibility
  • Validation methods (Guid.isValid())
  • Parsing methods (Guid.parse(), Guid.tryParse())
  • Consistent API across environments
typescript
import { Guid } from '@breadstone/ziegel-core';

const id = Guid.newGuid();
console.log(Guid.isValid(id.toString())); // true

Q: How do I work with dates and times?

A: Use ziegel's DateTime class for consistent date handling:

typescript
import { DateTime } from '@breadstone/ziegel-core';

const now = DateTime.now();
const future = now.addDays(30);
const formatted = future.toString('yyyy-MM-dd');

Error Handling ​

Q: What's the difference between ziegel's exceptions and standard Error?

A: ziegel exceptions provide:

  • Structured error information
  • Consistent error handling patterns
  • Built-in error codes and categories
typescript
import { ArgumentException, NotFoundException } from '@breadstone/ziegel-core';

// Instead of: throw new Error('Invalid argument')
throw new ArgumentException('User ID is required', 'userId');

// Instead of: throw new Error('Not found')
throw new NotFoundException('User not found');

HTTP Client ​

Configuration ​

Q: How do I configure the HTTP client for my API?

A: Configure the HttpClient with your API settings:

typescript
import { HttpClient } from '@breadstone/ziegel-platform-http';

const client = new HttpClient({
    baseUrl: 'https://api.example.com',
    timeout: 30000,
    headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
    }
});

Q: How do I add authentication to HTTP requests?

A: Use interceptors for authentication:

typescript
import { HttpInterceptor } from '@breadstone/ziegel-platform-http';

class AuthInterceptor implements HttpInterceptor {
    async request(request: HttpRequest): Promise<HttpRequest> {
        const token = await this.getAuthToken();
        request.headers['Authorization'] = `Bearer ${token}`;
        return request;
    }
}

client.addInterceptor(new AuthInterceptor());

Error Handling ​

Q: How do I handle HTTP errors?

A: HTTP errors are thrown as exceptions:

typescript
try {
    const response = await client.get('/users/123');
    return response.data;
} catch (error) {
    if (error instanceof NotFoundException) {
        console.log('User not found');
    } else if (error instanceof UnauthorizedException) {
        console.log('Authentication required');
    } else {
        console.error('Unexpected error:', error);
    }
}

Q: Can I retry failed requests?

A: Yes, configure retry behavior:

typescript
const client = new HttpClient({
    baseUrl: 'https://api.example.com',
    retry: {
        maxAttempts: 3,
        delay: 1000,
        backoff: 'exponential'
    }
});

Data Layer ​

Repository Pattern ​

Q: How do I implement the repository pattern?

A: Extend the base Repository class:

typescript
import { Repository } from '@breadstone/ziegel-data';

interface User {
    id: string;
    name: string;
    email: string;
}

class UserRepository extends Repository<User> {
    constructor(httpClient: HttpClient) {
        super('/api/users', httpClient);
    }

    async findByEmail(email: string): Promise<User | null> {
        const results = await this.query()
            .where('email', QueryOperator.Equals, email)
            .take(1)
            .toArray();

        return results.length > 0 ? results[0] : null;
    }
}

Query Building ​

Q: How do I build complex queries?

A: Use the query builder API:

typescript
const users = await userRepository.query()
    .where('active', QueryOperator.Equals, true)
    .and('role', QueryOperator.In, ['admin', 'moderator'])
    .orderBy('createdAt', 'desc')
    .skip(20)
    .take(10)
    .toArray();

Q: Can I use raw SQL queries?

A: While ziegel encourages using the query builder for type safety, you can execute raw queries when needed:

typescript
const results = await dataSource.query(
    'SELECT * FROM users WHERE created_at > @date',
    { date: '2023-01-01' }
);

Dependency Injection ​

Container Configuration ​

Q: How do I set up dependency injection?

A: Configure the container at application startup:

typescript
import { Container } from '@breadstone/ziegel-platform';

// Configure services
Container.configure(container => {
    container.registerSingleton('ILogger', ConsoleLogger);
    container.registerTransient('IUserService', UserService);
    container.registerScoped('IUnitOfWork', UnitOfWork);
});

// Resolve services
const userService = Container.resolve<IUserService>('IUserService');

Q: What's the difference between singleton, transient, and scoped?

A: Service lifetimes determine how instances are created:

  • Singleton: One instance for the entire application
  • Transient: New instance every time it's requested
  • Scoped: One instance per scope (e.g., per HTTP request)
typescript
// Singleton - shared instance
container.registerSingleton('ILogger', ConsoleLogger);

// Transient - new instance each time
container.registerTransient('IEmailService', EmailService);

// Scoped - one per scope
container.registerScoped('IDbContext', DatabaseContext);

Internationalization ​

Basic Setup ​

Q: How do I add multi-language support?

A: Use the internationalization packages:

typescript
import {
    LocalizationManagerBuilder,
    MapLocalizationProvider
} from '@breadstone/ziegel-platform-localization';

const provider = new MapLocalizationProvider(new Map([
    ['en-US', new Map([
        ['welcome', 'Welcome!'],
        ['goodbye', 'Goodbye!']
    ])],
    ['de-DE', new Map([
        ['welcome', 'Willkommen!'],
        ['goodbye', 'Auf Wiedersehen!']
    ])]
]));

const manager = new LocalizationManagerBuilder()
    .withProvider(provider)
    .build();

const message = await manager.getLocalizedString('welcome');

Units and Formatting ​

Q: How do I format numbers, currencies, and units?

A: Use the specialized internationalization packages:

typescript
import {
    LengthQuantity,
    LengthUnit,
    Currency,
    CurrencyFormatter
} from '@breadstone/ziegel-intl-units';
import { Money, Iban } from '@breadstone/ziegel-intl-commerce';

// Length formatting
const distance = new LengthQuantity(1000, LengthUnit.Meter);
console.log(distance.toString()); // "1000 m"

// Currency formatting
const price = new Money(99.99, Currency.USD);
console.log(price.toString()); // "$99.99"

// IBAN validation
const iban = new Iban('DE89370400440532013000');
console.log(iban.isValid); // true

Testing ​

Unit Testing ​

Q: How do I test ziegel applications?

A: ziegel works well with standard testing frameworks. We recommend Vitest:

typescript
import { describe, it, expect, beforeEach } from 'vitest';
import { UserService } from '../src/UserService';

describe('UserService', () => {
    let userService: UserService;

    beforeEach(() => {
        userService = new UserService();
    });

    it('should create user with valid data', async () => {
        const userData = { name: 'John Doe', email: 'john@example.com' };
        const user = await userService.createUser(userData);

        expect(user.id).toBeDefined();
        expect(user.name).toBe(userData.name);
    });
});

Q: How do I mock ziegel dependencies?

A: Create mock implementations of interfaces:

typescript
class MockUserRepository implements IUserRepository {
    private users = new Map<string, User>();

    async getById(id: string): Promise<User> {
        const user = this.users.get(id);
        if (!user) throw new NotFoundException('User not found');
        return user;
    }

    async save(user: User): Promise<void> {
        this.users.set(user.id, user);
    }
}

Integration Testing ​

Q: How do I test HTTP integrations?

A: Use test servers and mock HTTP responses:

typescript
import { TestServer } from './TestServer';
import { HttpClient } from '@breadstone/ziegel-platform-http';

describe('User API Integration', () => {
    let testServer: TestServer;
    let httpClient: HttpClient;

    beforeAll(async () => {
        testServer = new TestServer();
        await testServer.start();
        httpClient = new HttpClient({ baseUrl: testServer.url });
    });

    it('should create and retrieve user', async () => {
        const newUser = { name: 'Test User', email: 'test@example.com' };
        const created = await httpClient.post('/users', newUser);
        const retrieved = await httpClient.get(`/users/${created.data.id}`);

        expect(retrieved.data.name).toBe(newUser.name);
    });
});

Performance ​

Optimization ​

Q: How can I improve application performance?

A: Follow these optimization strategies:

  1. Use caching:
typescript
import { MemoryCache } from '@breadstone/ziegel-platform-caching';

const cache = new MemoryCache({ maxSize: 1000, ttl: 300 });
  1. Implement connection pooling:
typescript
const httpClient = new HttpClient({
    connectionPool: {
        maxConnections: 50,
        keepAlive: true
    }
});
  1. Use lazy loading:
typescript
import { Lazy } from '@breadstone/ziegel-core';

const expensiveResource = new Lazy(() => new ExpensiveResource());

Q: How do I monitor performance?

A: Use the analytics package for monitoring:

typescript
import { PerformanceMonitor } from '@breadstone/ziegel-platform-analytics';

const monitor = new PerformanceMonitor();

@monitor.measure('user-service.get-user')
async getUser(id: string): Promise<User> {
    // Method implementation
}

Troubleshooting ​

Common Issues ​

Q: I'm getting "Cannot resolve module" errors

A: This usually indicates missing packages. Install the required dependencies:

bash
npm install @breadstone/ziegel-core tslib reflect-metadata

Q: Decorators aren't working

A: Ensure decorators are enabled in your tsconfig.json:

json
{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

And import reflect-metadata:

typescript
import 'reflect-metadata';
import { Container } from '@breadstone/ziegel-platform';

Q: HTTP requests are failing with CORS errors

A: Configure CORS on your server or use a proxy for development:

typescript
// Development proxy
const client = new HttpClient({
    baseUrl: '/api', // Proxy to actual API
    headers: {
        'Content-Type': 'application/json'
    }
});

Q: Memory leaks in long-running applications

A: Ensure proper resource disposal:

typescript
// Use 'using' statement for automatic disposal
using connection = await database.connect();

// Or manually dispose
const subscription = observable.subscribe(handler);
// Later...
subscription.unsubscribe();

Debugging ​

Q: How do I debug ziegel applications?

A: Enable debug logging:

typescript
import { ConsoleLogger, LogLevel } from '@breadstone/ziegel-platform-logging';

const logger = new ConsoleLogger(LogLevel.Debug);
Container.registerSingleton('ILogger', () => logger);

Q: How can I trace HTTP requests?

A: Use HTTP interceptors for logging:

typescript
class LoggingInterceptor implements HttpInterceptor {
    request(request: HttpRequest): HttpRequest {
        console.log('Request:', request.method, request.url);
        return request;
    }

    response(response: HttpResponse): HttpResponse {
        console.log('Response:', response.status, response.statusText);
        return response;
    }
}

Migration and Upgrades ​

Version Compatibility ​

Q: How do I upgrade to a new version of ziegel?

A: Follow our Migration Guide for version-specific instructions. Generally:

  1. Update package versions:
bash
npm update @breadstone/ziegel-core @breadstone/ziegel-platform
  1. Review breaking changes in the changelog
  2. Update your code as needed
  3. Run tests to verify compatibility

Q: Can I use different versions of ziegel packages together?

A: We recommend using compatible versions. Check the compatibility matrix in our documentation or use:

bash
npm ls @breadstone/

Legacy Code ​

Q: How do I migrate from other frameworks to ziegel?

A: Start incrementally:

  1. Begin with core utilities (ziegel-core)
  2. Replace HTTP clients (ziegel-platform-http)
  3. Migrate data access (ziegel-data)
  4. Add advanced features as needed

See our Migration Guide for framework-specific migration strategies.

Contributing ​

Q: How can I contribute to ziegel?

A: We welcome contributions! See our Contributing Guide for:

  • Setting up the development environment
  • Code style guidelines
  • Testing requirements
  • Pull request process

Q: How do I report bugs?

A: Create an issue on our issue tracker with:

  • Description of the issue
  • Steps to reproduce
  • Expected vs actual behavior
  • Environment information

Q: Can I request new features?

A: Yes! Submit feature requests through our issue tracker. Include:

  • Use case description
  • Proposed API design
  • Examples of how it would be used

Still Have Questions? ​

If you can't find the answer to your question:

  1. Check our documentation
  2. Search existing issues
  3. Create a new issue with your question
  4. Join our community discussions

We're here to help you succeed with ziegel!