App configuration is the foundation of your Revali application. It defines how your server runs, what dependencies are available, and how requests are handled. Every revali app has at least one app configuration (even when you haven't created one yet).
What is an AppConfig?#
An AppConfig is a class that extends Revali's base configuration and defines:
- Server Settings: Host, port, and global prefix
- Dependencies: Services, repositories, and other injectable objects
- Environment: Development, staging, or production settings
Key Concepts#
🏗️ Application Entry Point#
The app configuration serves as the entry point for your Revali application. It's where you define how your server should behave and what resources it needs.
🔧 Dependency Injection#
Configure all your application's dependencies in one place. Revali's built-in dependency injection system makes it easy to manage services, repositories, and other components.
🌍 Environment Management#
Create different configurations for different environments (development, staging, production) using flavors.
⚙️ Centralized Configuration#
All server settings and dependencies are configured in a single, well-organized location.
Default Configuration#
Revali provides sensible defaults that work out-of-the-box:
import 'package:revali_router/revali_router.dart';
@App()
final class MainApp extends AppConfig {
const MainApp()
: super(
host: 'localhost',
port: 8080,
prefix: '/api',
);
}
This means your API will be available at http://localhost:8080/api/
Configuration Hierarchy#
graph TD
A[AppConfig] --> B[Server Settings]
A --> C[Dependencies]
A --> E[Environment]
B --> F[Host & Port]
B --> G[Global Prefix]
B --> H[CORS Settings]
C --> I[Services]
C --> J[Repositories]
C --> K[External APIs]
E --> O[Development]
E --> P[Staging]
E --> Q[Production]
Everything in This Section#
Start at the top; the rest are worth reading when you hit what they solve.
| Page | What it covers |
|---|---|
| Create an App | The @App() that owns host, port and prefix |
| Configure Dependencies | Register services once and inject them anywhere |
| Request-Scoped Dependencies | One instance per request, disposed when it ends |
| Flavors | One codebase, several environments |
| Environment Variables | Env, AppConfig.fromEnv, and compile-time defines |
| Default Responses | The body returned for 404s and 500s |
| Error Responses | Structured errors that survive a service-to-service call |
| HTTPS in Development | Serve TLS locally without a proxy in front |
| Compression | Gzip responses for clients that ask for them |
| Worker Isolates | Several isolates on one port, and what they don't share |
| Graceful Shutdown | Finish in-flight requests before the process exits |
| Health Probes | Liveness and readiness, and why they are not one check |
| Request Tracing | Carry a request id and W3C trace context across a hop |
Best Practices#
📁 File Organization#
- Place app files in the
routes/directory - Use descriptive names like
main_app.dartorapi_app.dart - Follow the naming convention:
*_app.dartor*.app.dart
🔄 Dependency Management#
- Register dependencies in logical groups
- Use interfaces for better testability
- Prefer lazy singletons for expensive resources
🌐 Environment Configuration#
- Use environment variables for sensitive data
- Create separate flavors for different environments
- Keep development and production configs separate
🛡️ Security#
- Never hardcode secrets in configuration files
- Use environment variables for API keys and passwords
- Validate configuration values at startup
Next Steps#
- Create an App: Learn how to create your first app configuration
- Configure Dependencies: Set up dependency injection
- Environment Variables: Handle configuration across environments
- Health Probes: Make the server answer for its own readiness before you deploy it