Serialization & Code Generation
Fasq Serializer Generator is a powerful companion package for FASQ that automates the registration of serializers for your TypedQueryKey declarations.
While FASQ’s TypedQueryKey provides excellent compile-time type safety, complex data types like nested lists or custom classes still require manual JSON serialization (via fromJson/toJson) to be correctly cached and persisted. This package eliminates that boilerplate.
Features
Section titled “Features”- 🤖 Automated Detection: Automatically finds all
TypedQueryKeydeclarations in your annotated classes. - 📦 Boilerplate-Free: Generates the
CodecRegistrywiring needed for theQueryClientto handle your custom types. - 🏗️ Build Runner Integration: Works with standard Flutter code generation tools.
Installation
Section titled “Installation”Add the generator and build_runner to your dev_dependencies:
flutter pub add -d fasq_serializer_generator build_runnerSetup & Usage
Section titled “Setup & Usage”1. Annotate Your Keys
Section titled “1. Annotate Your Keys”Organize your query keys into a class and annotate it with @AutoRegisterSerializers(). Ensure your data models (e.g., Product, User) have standard fromJson factory methods.
import 'package:fasq/fasq.dart';import 'package:fasq_serializer_generator/fasq_serializer_generator.dart';import 'models/product.dart';import 'models/user.dart';
// 1. Add the part directive for the generated filepart 'query_keys.serializers.g.dart';
@AutoRegisterSerializers()class QueryKeys { static const products = TypedQueryKey<List<Product>>('products', List<Product>); static const currentUser = TypedQueryKey<User>('user', User);}2. Run the Generator
Section titled “2. Run the Generator”Execute the standard build command:
dart run build_runner build3. Initialize the Registry
Section titled “3. Initialize the Registry”The generator creates a registerQueryKeySerializers function. Use it to initialize your QueryClient.
import 'query_keys.serializers.g.dart';
void main() { // 1. Create a registry and pipe it through the generated helper final registry = registerQueryKeySerializers(CacheDataCodecRegistry());
// 2. Pass the registry to your QueryClient configuration final client = QueryClient( config: CacheConfig( codecRegistry: registry, ), );
runApp(QueryClientProvider(client: client, child: MyApp()));}Why use the Serializer Generator?
Section titled “Why use the Serializer Generator?”Without the generator, you would have to manually register a Codec for every single type you use in a TypedQueryKey:
// The manual way (Avoid this!)final registry = CacheDataCodecRegistry() ..registerCodec( 'Product', (json) => Product.fromJson(json), (data) => data.toJson(), ) ..registerCodec( 'List<Product>', (json) => (json as List).map((e) => Product.fromJson(e)).toList(), (data) => data.map((e) => e.toJson()).toList(), );The generator handles all of this—including complex types like List<T>, Map<K, V>, and nested generics—automatically.
Next Steps
Section titled “Next Steps”- Type Safety Essentials - Learn more about
TypedQueryKey. - Encrypted Persistence - How serialization helps secure disk storage.