Show menu


  void main() => runApp(DemoApp());

  class DemoApp extends StatelessWidget {
    const DemoApp();

    Widget build(BuildContext context) {
      return MaterialApp(
          home: Scaffold(
              appBar: AppBar(
                title: const Text("Download Demo"),
              body: Center(
                child: const FetchDataPage(),


  part 'post.g.dart';

  class Post {
    final int userId;
    final int id;
    final String title;
    final String body;
    const Post(this.userId,, this.title, this.body);

    factory Post.fromJson(Map<String, dynamic> json) => _$PostFromJson(json);
    Map<String, dynamic> toJson() => _$PostToJson(this);


  part "todo.g.dart";

  @JsonSerializable(explicitToJson: true)
  class TodoObject {
    final List<Todo> data;
    const TodoObject(;

    factory TodoObject.fromJson(Map<String, dynamic> json) =>

    Map<String, dynamic> toJson() => _$TodoObjectToJson(this);

  class Todo {
    final int userId;
    final int id;
    final String title;
    final bool completed;

    const Todo(this.userId,, this.title, this.completed);

    factory Todo.fromJson(Map<String, dynamic> json) =>

    Map<String, dynamic> toJson() => _$TodoToJson(this);


  library json_parser;

  export 'post_parser.dart';
  export 'todo_parser.dart';
  export 'object_decoder.dart';

  abstract class JsonParser<T> {
    const JsonParser();

    Future<T> parseFromJson(String json);


  mixin ObjectDecoder<T> on JsonParser<T> {
    Map<String, dynamic> decodeJsonObject(String json) =>
        jsonDecode(json) as Map<String, dynamic>;

  mixin ListDecoder<T> on JsonParser<T> {
    List<dynamic> decodeJsonList(String json) =>
        jsonDecode(json) as List<dynamic>;


  class PostParser extends JsonParser<Post> with ObjectDecoder<Post> {
    const PostParser();

    Future<Post> parseFromJson(String json) async {
      final decoded = decodeJsonObject(json);
      return Post.fromJson(decoded);


  class TodoParser extends JsonParser<List<Todo>> with ListDecoder<List<Todo>> {
    const TodoParser();

    Future<List<Todo>> parseFromJson(String json) async {
      return decodeJsonList(json)
          .map((value) => Todo.fromJson(value as Map<String, dynamic>))


  class RequestREST {
    final String endpoint;
    final Map<String, String> data;
    const RequestREST({
      this.endpoint, = const {},

    /// HTTP dio client
    static final _client = Dio(
          baseUrl: "",
          connectTimeout: 3000, // 3 seconds
          receiveTimeout: 3000, // 3 seconds
          headers: <String, String>{"api-key": "add_one_if_needed", },

    Future<T> executeGet<T>(JsonParser<T> parser) async {
      final response = await _client.get<String>(endpoint);
      return parser.parseFromJson(;

    Future<T> executePost<T>(JsonParser<T> parser) async {
      final formData = FormData.fromMap(data);
      final response = await<String>(
        data: formData,

      return parser.parseFromJson(;

This website and the book are not official Google products. No affiliations are involved. Built with Java 14 and Vert.X

"Flutter and the related logo are trademarks of Google LLC. We are not endorsed by or affiliated with Google LLC"