Skip to main content

Flavors

Flavors are the fundamental building blocks of Tasteful applications. They represent modular, self-contained components that can be composed together to create complete applications. Each flavor encapsulates a specific domain or feature area with its own HTTP interface, business logic, and data access patterns.

What is a Flavor?

A Flavor is a collection of related functionality organized into distinct layers: Think of flavors as “micro-applications” that can run independently or be combined with other flavors to build complete systems. Each flavor follows the same architectural patterns, making them predictable and maintainable.

Basic Flavor Structure

A complete flavor consists of four main components working together:
This structure demonstrates the clear separation of concerns:
  • Controller handles HTTP requests and delegates to services
  • Service contains all business logic and coordinates with repositories
  • Repository manages data access and persistence
  • Configuration provides settings and dependencies

Key Features

1. Constructor-Based Initialization

Flavors use constructor-based initialization where you specify the components that make up your flavor:
The dependency injection system automatically wires up the dependencies between components based on their constructor parameters.

2. HTTP Route Decorators

Controllers use decorators to define HTTP endpoints. These decorators mirror FastAPI’s functionality while integrating with Tasteful’s architecture:
For detailed information about route decorators and controller patterns, see the Controller concept page.

3. URL Prefixing and Organization

All routes in a controller are automatically prefixed based on the controller configuration, providing clean URL organization:
This automatic prefixing ensures consistent URL patterns across your application and makes it easy to organize related endpoints together.

4. Dependency Injection

Flavors leverage Tasteful’s dependency injection system to automatically wire up components. Dependencies are resolved based on constructor parameters:
The dependency injection system handles the complexity of wiring up your components, making your code cleaner and more testable.

Built-in Flavors

Tasteful comes with several pre-built flavors for common functionality: These built-in flavors follow the same architectural patterns as custom flavors and can be used as examples for building your own flavors.

Flavor Composition

Combine multiple flavors to build complete applications:

Best Practices

1. Single Responsibility Principle

Each flavor should have a single, well-defined responsibility that aligns with a specific domain or feature area:

2. Meaningful Naming

Use descriptive names that clearly communicate the purpose of flavors and their components:

Migration from Microservices

When migrating from microservices to flavors:
  1. Map service boundaries - Each microservice typically becomes a flavor
  2. Consolidate shared logic - Move common code to shared services or base classes
  3. Simplify data access - Replace multiple databases with shared repositories where appropriate
  4. Replace HTTP calls - Convert inter-service HTTP calls to direct service method calls
  5. Maintain transaction boundaries - Ensure data consistency is preserved during migration
When migrating, carefully consider data consistency and transaction boundaries that may have been handled at the microservice level. You may need to implement distributed transaction patterns or redesign your data model.