Facades
Facades provide a clean, static interface to the services bound in Magic's IoC container, giving you expressive one-liners without sacrificing testability or container transparency.
On this page
Introduction#
Facades provide a "static" interface to classes that are available in the application's service container. Magic ships with many facades which provide access to almost all of Magic's features. Magic facades serve as "static proxies" to underlying classes in the service container, providing the benefit of a terse, expressive syntax.
// Using a facade - clean and expressive
await Cache.put('key', 'value');
final user = Auth.user<User>();
MagicRoute.to('/dashboard');
// Instead of resolving from container
final cache = app.make<CacheManager>('cache');
await cache.put('key', 'value');
When To Use Facades#
Facades have many benefits. They provide a terse, memorable syntax that allows you to use Magic's features without remembering long class names or understanding dependency injection.
Use facades when:
- You need quick access to a service from anywhere
- You want clean, readable code
- The service is stateless or globally applicable
- You're in a controller, service, or helper class
Available Facades#
Core ships 13 facades, one file each under lib/src/facades/: Auth, Cache, Config, Event, Gate, Http, Lang, Launch, Log, MagicRoute, Session, Storage and Vault.
Core Facades#
| Facade | Description |
|---|---|
Config |
Configuration values access |
Authentication & Security#
| Facade | Description |
|---|---|
Auth |
Authentication state and user |
Gate |
Authorization abilities and policies |
Vault |
Secure storage (Keychain/Keystore) |
HTTP & Network#
| Facade | Description |
|---|---|
Http |
HTTP client for API requests |
Routing#
| Facade | Description |
|---|---|
MagicRoute |
Navigation and route definitions |
Session Management#
| Facade | Description |
|---|---|
Session |
Form flash data for validation errors and old input |
Data & Storage#
| Facade | Description |
|---|---|
Cache |
Caching system |
Storage |
File storage |
Utilities#
| Facade | Description |
|---|---|
Event |
Event dispatching |
Lang |
Localization and translations |
Launch |
Open URLs, email, phone, and SMS via url_launcher |
Log |
Logging |
Related Classes#
These are static entry points too, but they are classes in their own right, not facades over a container binding.
| Class | Description |
|---|---|
Magic |
Application container, UI helpers (snackbar, dialog) |
Env |
Environment variables |
Carbon |
Date and time manipulation |
Plugin Facades#
These facades live in optional plugin packages, not in core. Each plugin is installed with flutter pub add <package> then dart run magic:dowel plugin:install <package>, and its own documentation covers the facade.
| Facade | Package | Provides |
|---|---|---|
Crypt |
magic_encryption |
AES-256-CBC encryption |
Echo |
magic_socket |
Real-time broadcasting client |
DB, Schema |
magic_local_storage |
SQLite, query builder, migrations |
Pick |
magic_picker |
File and image picking |
How Facades Work#
Behind the scenes, facades access the service container and resolve the relevant service. For example:
// When you call:
Cache.put('key', 'value');
// Magic actually does:
Magic.make<CacheManager>('cache').put('key', 'value');
Each facade has a static method that proxies to the underlying service instance.
Facade Class Reference#
Magic#
// Service container
Magic.bind('key', () => Service());
Magic.make<Service>('key');
Magic.findOrPut(Controller.new);
// UI Helpers
Magic.success('Title', 'Message');
Magic.error('Title', 'Message');
Magic.toast('Message');
Magic.loading(message: 'Please wait...');
Magic.closeLoading();
Magic.dialog<T>(Widget());
Magic.closeDialog<T>([result]);
await Magic.confirm(title: 'Delete?', message: '...');
Config#
Config.get<String>('app.name', 'Default');
Config.set('app.locale', 'tr');
Config.has('services.stripe');
Config.all();
Config.merge({'key': 'value'});
Auth#
Auth.check(); // Is authenticated?
Auth.guest; // Is guest?
Auth.user<User>(); // Get typed user
Auth.id(); // Get user ID
await Auth.login(data, user); // Login
await Auth.logout(); // Logout
await Auth.restore(); // Restore from cache
await Auth.refreshToken(); // Refresh token
MagicRoute#
// Navigation
MagicRoute.to('/path');
MagicRoute.to('/search', query: {'q': 'flutter'});
MagicRoute.push('/path');
MagicRoute.back();
MagicRoute.replace('/path');
MagicRoute.toNamed('route.name', params: {}, query: {});
// Route definition
MagicRoute.page('/path', () => Widget());
MagicRoute.group(prefix: '/admin', routes: () {});
Http#
await Http.get('/users', query: {'page': 1});
await Http.post('/users', data: {...});
await Http.put('/users/1', data: {...});
await Http.delete('/users/1');
// RESTful shortcuts
await Http.index('users');
await Http.show('users', '1');
await Http.store('users', data);
await Http.update('users', '1', data);
await Http.destroy('users', '1');
Cache#
Cache.get('key', defaultValue: 'default');
await Cache.put('key', 'value', ttl: Duration(minutes: 5));
await Cache.remember('key', duration, () async => compute());
await Cache.forget('key');
await Cache.flush();
Gate#
Gate.define('ability', (user, model) => bool);
Gate.before((user, ability) => true/false/null);
Gate.allows('ability', model);
Gate.denies('ability', model);
Lang#
trans('key', {'param': 'value'}); // Global helper
Lang.current; // Current locale
await Lang.setLocale(Locale('tr'));
Lang.supportedLocales; // Locales the app declares
Launch#
await Launch.url('https://flutter.dev');
await Launch.url('https://flutter.dev', mode: LaunchMode.inAppWebView);
await Launch.email('[email protected]', subject: 'Hello', body: 'Hi!');
await Launch.phone('+1234567890');
await Launch.sms('+1234567890', body: 'On my way!');
// Check before launch
if (await Launch.canLaunch('tel:+1234567890')) {
await Launch.phone('+1234567890');
}
Carbon#
Carbon.now();
Carbon.parse('2024-01-15');
carbon.addDays(5);
carbon.subMonths(2);
carbon.diffForHumans(); // "2 days ago"
carbon.format('yyyy-MM-dd');
carbon.isToday();
carbon.isFuture();
Vault#
await Vault.put('api_key', 'secret');
await Vault.get('api_key');
await Vault.delete('api_key');
await Vault.flush();
Related Documentation#
- Service Container: the bindings a facade resolves.
- Service Providers: where those bindings are registered.
- Testing Facades: swapping a facade for a fake in a test.