title: How can I properly organize my API calls in Flutter per view models?
body: <p>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.</p>
  
  <p>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.</p>
  
  <p>Here is how I did it. I thought about creating an <code>api.dart</code> service that implements the methods of <code>http</code> package. So far it's only <code>get()</code>, but I can already see the others will end up repeating the condition too much.</p>
  
  <pre class="lang-dart prettyprint-override"><code>class Api {
    Future&lt;dynamic&gt; 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);
    }
  }
  </code></pre>
  
  <p>Then, in the only view model I have so far, I implement the <code>get()</code> from the <code>api.dart</code> on a button click, for example. The <code>model</code> within the button is how the <a href="https://github.com/mfgabriel92/flutter_responsive_architecture/tree/master/lib" rel="nofollow noreferrer">architecture</a> I mentioned above is done.</p>
  
  <pre class="lang-dart prettyprint-override"><code>Future&lt;void&gt; 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
  }
  </code></pre>
  
  <pre class="lang-dart prettyprint-override"><code>PrimaryButton(
    onTap: () {
      model.submit();
    },
    disabled: model.busy, // the loading state to modify the styling of the button
  ),
  </code></pre>
  
  <p>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.</p>