How can I properly organize my API calls in Flutter per view models?

1,713

Great question, @gamofe.

As far as file structure goes, Flutter is still a bit of the wild west. That being said, in my projects, and in the large majority of tutorials I've read, folder structure looks like this:

lib/src
lib/src/repositories
lib/src/repositories/common
lib/src/repositories/user
lib/src/repositories/user/user_repository.dart
lib/src/repositories/item/item_repository.dart
lib/src/blocs
lib/src/blocs/user
lib/src/blocs/user/barrel.dart
lib/src/blocs/user/user_state.dart
lib/src/blocs/user/user_events.dart
lib/src/blocs/user/user_bloc.dart
lib/src/models/user.dart
lib/src/screens/login_screen.dart
lib/src/screens/item_feed.dart
lib/src/widgets

Additionally, I would say it is exceptionally rare that you should be making an API call directly from your view layer. I would recommend reading up on the BLoC pattern. It is the commonly accepted (and recommended by Google) method of managing state in Flutter apps.

Basically, a BLoC is a stream. In your view, you listen for new state events from the stream. If you want to update data, you "dispatch" a new event to the stream, which is ultimately transformed into a state output.

Implementing the Bloc pattern in your application will help you achieve the separation and DRY code you are looking for.

Flutter Bloc is a helper library that will get you up and running with the Bloc pattern. The documentation is quite good, and the examples are numerous. There are docs that give overviews of how to manage the relationship between views, state, and network requests quite well.

FWIW, I've put together an example Flutter application that implements all these concepts. I use copy it for each new project to help me get rocking and rolling fast. Feel free to poke around. I've done my best to follow best practices, so it should hopefully serve as a decent model.

Share:
1,713
fermoga
Author by

fermoga

Updated on December 17, 2022

Comments

  • fermoga
    fermoga over 1 year

    I have started studying Flutter around a month ago, and I have read and watched some good tutorials, the best of them being a responsive architecture with Provider and view models to prevent code repetition when creating apps.

    Now I am writing my very first app for my work and I have some API calls to do. I haven't found a good article or video yet teaching a good way to organize my API requests into separate files properly to prevent repetition, so I come here to ask for your guidance regarding this.

    Here is how I did it. I thought about creating an api.dart service that implements the methods of http package. So far it's only get(), but I can already see the others will end up repeating the condition too much.

    class Api {
      Future<dynamic> get(String url) async {
        final response = await http.get('$kBaseUrl/$url');
    
        if (response.statusCode != 200) {
          throw Exception(json.decode(response.body)[0]['mensagem']);
        }
    
        return json.decode(response.body);
      }
    }
    

    Then, in the only view model I have so far, I implement the get() from the api.dart on a button click, for example. The model within the button is how the architecture I mentioned above is done.

    Future<void> submit() async {
      print('Email: $email, password: $password');
      get();
    }
    
    Future get() async {
      _setBusy(true); // loading status on
      _setError(''); // clean errors
    
      try {
        await _api.get('clientes');
      } catch (e) {
        _setError(e.message);
      }
    
      _setBusy(false); // loading status off
    }
    
    PrimaryButton(
      onTap: () {
        model.submit();
      },
      disabled: model.busy, // the loading state to modify the styling of the button
    ),
    

    And this is it. I have the feeling it could be much better, and I would prefer to have the best way possible from the beginning so I can learn more about structuring my files and also keeping it clean as the app grows. I will appreciate any guidance, code, article, video and/or repository.

  • fermoga
    fermoga over 4 years
    Hello, thank you. I will read about it now, but meanwhile, I want to drop this question, too. Have you seen the responsive architecture I had mentioned? Do you think I could continue using that with BLoC pattern?
  • Spencer Stolworthy
    Spencer Stolworthy over 4 years
    Ah, I apologize! No, I didn't. Let me take a look through it
  • fermoga
    fermoga over 4 years
    This structure seems very nice to me. I'd really like to continue making use of it with a different architecture such as BLoC. I am new to Flutter and all this information is confusing.
  • fermoga
    fermoga over 4 years
    I'm not enjoying the ways BLoC is implemented. I read a login tutorial and I find it too messy to my liking.
  • Spencer Stolworthy
    Spencer Stolworthy over 4 years
    Understood. If you don't mind me recommending a course, Stephen Grider's on udemy is exceptional, in my opinion. I find his explanations very clear, and not overly laborious. udemy.com/user/sgslo
  • Spencer Stolworthy
    Spencer Stolworthy over 4 years
    In regards to your question about the Provider/Consumer architecture that is referenced in the medium tutorial you talked about (for others reading: medium.com/flutter-community/…), the Provider/Consumer implementation is certainly supported in Flutter. In fact, even the bloc pattern implements provider/consumer to a degree. In my personal opinion, it can be challenging to implement Provider/Consumer well and maintain intuitive code. But I digress :)
  • fermoga
    fermoga over 4 years
    I am having a hard time here. There iss too much information and I don't know how to proceed. I do not like messy code, and I need to write things nicely. But every time I find a tutorial it is almost completely different than the previous one and complicated to me, making me feel lost. Also, I have the responsive architecture and all of the tutorials I read, when I think about merging both, I simply get stuck. I know, I am only starting out with Flutter and in our world, things are like this... This is why I prefer opinionated frameworks over those you're free to mess up.
  • fermoga
    fermoga over 4 years
    Hello. I have read more calmly about BLoC, and I kind of like it now. Little by little I'm getting used to it and being able to see things clearly, so I marked your answer as the correct one. Thanks.