Quickstart

Add flutter_data and dependencies to your pubspec.yaml file:

dependencies:
  flutter:
    sdk: flutter

  flutter_data: ^1.1.0

  # Highly RECOMMENDED (but not required) packages
  path_provider: ^2.0.7
  json_annotation: ^4.4.0
  flutter_riverpod: ^1.0.0

dev_dependencies:
  build_runner: ^2.0.4 # REQUIRED!

  # Highly RECOMMENDED (but not required) packages
  json_serializable: ^6.1.4

Flutter Data doesn’t require any library besides build_runner for code generation.

However, json_serializable and path_provider are highly convenient so they are recommended.

The latest flutter_data should be 1.1.0. Please check for all packages latest stable versions before copy-pasting dependencies.

Basic configuration 🔧

Annotate your models with @DataRepository() and mix DataModel<T> in.

Example:

import 'package:flutter_data/flutter_data.dart';
import 'package:json_annotation/json_annotation.dart';

part 'task.g.dart';

@JsonSerializable()
@DataRepository([])
class Task with DataModel<Task> {
  @override
  final int? id;
  final String title;
  final bool completed;

  Task({this.id, required this.title, this.completed = false});
}

The annotation takes a list of adapters.

Adapters are mixins used to customize the framework’s behavior, ranging from the very basic to the extremely powerful. They are applied on Flutter Data’s RemoteAdapter<T> base class.

Let’s start by the most common configuration: the base URL.

mixin ApplicationAdapter<T extends DataModel<T>> on RemoteAdapter<T> {
  @override
  String get baseUrl => 'https://my-json-server.typicode.com/flutterdata/demo/';
}

Next, we’ll pass it to the annotation:

@JsonSerializable()
@DataRepository([ApplicationAdapter])
class Task with DataModel<Task> {
  final int? id;
  final String title;
  final bool completed;

  Task({this.id, required this.title, this.completed = false});
}

Default serialization

Flutter Data ships with a built-in serializer/deserializer for classic JSON.

It means that the default serialized form of a Task instance looks like:

{
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}

Notice two things about our model above:

  • we used int? to represent the actual type of the id identifier field (null when new)
  • fromJson and toJson() haven’t been included as they are not required (Flutter Data will automatically use _$TaskFromJson and _$TaskToJson functions generated by json_serializable – but they can both be overridden)

We are now ready to run a build:

flutter pub run build_runner build

Flutter Data auto-generated a Repository class for Task.

It also generated a Dart library at main.data.dart which makes Flutter Data initialization effortless. It’s out-of-the-box compatible with Riverpod.

Trouble generating code? See here.

Here is how to make it work with Provider and GetIt.

Next step is to configure local storage and initialize the framework:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_data/flutter_data.dart';
import 'package:tutorial/main.data.dart';

void main() {
  runApp(
    ProviderScope(
      child: TasksApp(),
      overrides: [configureRepositoryLocalStorage()],
    ),
  );
}

class TasksApp extends HookConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: ref.watch(repositoryInitializerProvider()).when(
                error: (error, _) => Text(error.toString()),
                loading: () => const CircularProgressIndicator(),
                data: (_) => 'Hello from Flutter Data ${ref.tasks}!',
              ),
        ),
      ),
      debugShowCheckedModeBanner: false,
    );
  }
}

Once the data callback is invoked, Flutter Data is ready!

The configureRepositoryLocalStorage setup function has several optional arguments.

You will have to supply baseDirFn (a function that returns a base directory for local storage) if you do not have path_provider as a dependency.

For more information see initialization.

➡ Continue with the tutorial for a Tasks app or learn more about Repositories