跳到主要内容

Annotations Reference

Fluttron provides two annotations for defining service contracts and models in fluttron_shared.

Import

import 'package:fluttron_shared/fluttron_shared.dart';

@FluttronServiceContract

Marks an abstract class as a Fluttron Host service contract.

Syntax

(namespace: 'your_namespace')
abstract class YourService {
// Method declarations
}

Parameters

ParameterTypeRequiredDescription
namespaceStringYesThe routing namespace for namespace.method calls

Namespace Rules

  • Must be unique within the application's service registry
  • Use snake_case convention (e.g., weather_service, user_auth)
  • Avoid reserved namespaces: file, dialog, clipboard, system, storage
  • Must be a valid Dart identifier

Contract Class Requirements

  1. Must be abstract
  2. All methods must return Future<T>
  3. Methods are public (no underscore prefix)

Example

/// Service for managing user authentication.
(namespace: 'auth')
abstract class AuthService {
/// Logs in a user and returns a session token.
Future<Session> login(String email, String password);

/// Logs out the current user.
Future<void> logout();

/// Checks if a user is currently logged in.
Future<bool> isAuthenticated();

/// Gets the current user's profile.
Future<User?> getCurrentUser();
}

Method Signatures

Positional Parameters

Future<Result> method(String param1, int param2);

Generated as required parameters.

Named Parameters with Defaults

Future<Result> method({int count = 10, bool flag = true});

Generated as optional parameters with default values.

Nullable Parameters

Future<Result> method(String required, {String? optional});

Optional parameters can be null.

Void Return

Future<void> doSomething();

Methods can return void.

Unsupported Patterns

// ❌ Non-async methods
String syncMethod(); // Not supported

// ❌ Non-Future return types
int getValue(); // Must return Future<int>

// ❌ Sync callbacks
void registerCallback(Function cb); // Not supported

// ❌ Generic methods
Future<T> genericMethod<T>(); // Not supported

@FluttronModel

Marks a class as a serializable model for the Host-UI bridge.

Syntax

()
class YourModel {
// Fields
}

Model Class Requirements

  1. All fields must be final
  2. Must have a const constructor
  3. All non-nullable fields must be required in constructor

Example

/// User profile information.
()
class UserProfile {
final String id;
final String name;
final String email;
final int age;
final bool isActive;
final DateTime createdAt;
final String? bio;
final List<String> tags;
final Map<String, dynamic> metadata;

const UserProfile({
required this.id,
required this.name,
required this.email,
required this.age,
required this.isActive,
required this.createdAt,
this.bio,
required this.tags,
required this.metadata,
});
}

Supported Field Types

Basic Types

TypeSerializationDeserialization
StringDirectas String
intDirectas int
doubleDirect(as num).toDouble()
boolDirectas bool
numDirectas num
DateTimetoIso8601String()DateTime.parse()

Nullable Types

All basic types support ? suffix:

  • String? → null or string
  • int? → null or int
  • DateTime? → null or ISO 8601 string

Collection Types

TypeSerializationDeserialization
List<T>.map(toMap).toList().map(fromMap).toList()
Map<String, dynamic>DirectMap<String, dynamic>.from()

Nested Models

()
class Order {
final String id;
final Customer customer; // Another @FluttronModel
final List<OrderItem> items; // List of models

const Order({
required this.id,
required this.customer,
required this.items,
});
}

Generated Code

The code generator produces:

  1. fromMap factory: Creates an instance from JSON
  2. toMap method: Serializes to JSON
factory UserProfile.fromMap(Map<String, dynamic> map) {
return UserProfile(
id: map['id'] as String,
name: map['name'] as String,
email: map['email'] as String,
age: map['age'] as int,
isActive: map['isActive'] as bool,
createdAt: DateTime.parse(map['createdAt'] as String),
bio: map['bio'] == null ? null : map['bio'] as String,
tags: (map['tags'] as List).map((e) => e as String).toList(),
metadata: Map<String, dynamic>.from(map['metadata'] as Map),
);
}

Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
'email': email,
'age': age,
'isActive': isActive,
'createdAt': createdAt.toIso8601String(),
'bio': bio,
'tags': tags,
'metadata': metadata,
};
}

Documentation

Model and field documentation is preserved in generated code:

/// User profile information.
()
class UserProfile {
/// Unique identifier for the user.
final String id;

/// Display name shown in the UI.
final String name;
}

Complete Example

import 'package:fluttron_shared/fluttron_shared.dart';

// Models

/// Weather information for a specific location.
()
class WeatherInfo {
/// City name.
final String city;

/// Temperature in Celsius.
final double temperature;

/// Weather condition description.
final String condition;

/// Timestamp of the reading.
final DateTime timestamp;

const WeatherInfo({
required this.city,
required this.temperature,
required this.condition,
required this.timestamp,
});
}

/// Daily weather forecast.
()
class WeatherForecast {
/// Forecast date.
final DateTime date;

/// High temperature in Celsius.
final double high;

/// Low temperature in Celsius.
final double low;

/// Weather condition.
final String condition;

const WeatherForecast({
required this.date,
required this.high,
required this.low,
required this.condition,
});
}

// Service Contract

/// Weather service providing current conditions and forecasts.
(namespace: 'weather')
abstract class WeatherService {
/// Gets current weather for the given city.
Future<WeatherInfo> getCurrentWeather(String city);

/// Gets the weather forecast.
///
/// [city] — The city to get forecast for.
/// [days] — Number of days (default: 5).
Future<List<WeatherForecast>> getForecast(String city, {int days = 5});

/// Checks if the weather API is available.
Future<bool> isAvailable();
}

Best Practices

Namespace Naming

// ✅ Good
(namespace: 'user_auth')
(namespace: 'payment_gateway')

// ❌ Avoid
(namespace: 'AuthService') // Not snake_case
(namespace: 'file') // Reserved namespace

Model Organization

// ✅ Good: Separate models file
// models/user_models.dart
()
class User { ... }

// services/user_contract.dart
(namespace: 'user')
abstract class UserService { ... }

Documentation

// ✅ Good: Document everything
/// Service for managing user notifications.
(namespace: 'notification')
abstract class NotificationService {
/// Sends a notification to a specific user.
///
/// [userId] — The target user's ID.
/// [message] — The notification content.
/// Returns the created notification ID.
Future<String> send(String userId, String message);
}

See Also