Search code examples
vue.jsaxiosvuex

Vue - Do API calls belong in Vuex?


I am struggling with finding answer for where to ideally put API calls in vue modules. I am not building an SPA. For example my auth block has several components for login, password reset, account verifiction etc. Each block uses axios for API calls. Axios already provides promises, which are async.

The question is about the best pracitces. Do API calls belong in a Vuex actions? Are there any pros/cons of such approach?

Is there any drawback of keeping axios calls within the components they belong to?


Solution

  • I do API calls in services, not Vuex or components. Basically, mixing the API calls in with the store code is a bit too multi-responsibility, and components should be about providing for the view not fetching data.

    As an example of a simple service (using Vue.http but same for an Axios call),

    FileService .js

    import Vue from 'vue'
    
    export default {
      getFileList () {
        return Vue.http.get('filelist.txt')
          .then(response => {
            // massage the response here
            return filelist;
          })
          .catch(err => console.error('getFileList() failed', err) )
      },
    }
    

    I use it in another service as below (the number of layers is up to you).
    Note, the outer service is checking the store to see if the fetch already happened.

    DataService.js

    import FileService from './file.service'
    
    checkFiles (page) {
      const files = store.state.pages.files[page]
      if (!files || !files.length) {
        return store.dispatch('waitForFetch', {
          resource: 'files/' + page,
          fetch: () => FileService.getFileList(),
        })
      } else {
        return Promise.resolve()  // eslint-disable-line no-undef
      }
    },
    

    waitForFetch is an action that invokes the fetch function passed in to it (as provided by FileService). It basically provides wrapper services to the fetch, like timeout and dispatching success and failure actions depending on the outcome.

    The component never knows about the API result (although it may initiate it), it just waits on data to appear in the store.


    As for drawback of just calling the API in the component, it depends on testability, app complexity. and team size.

    • Testability - can mock out a service in unit tests.
    • App complexity - can handle timeout / success / failure orthogonally to the API call.
    • Team size - bigger teams, dividing up the task into smaller bites.