avatarLiu Ting Chun

Summary

The web content discusses three common approaches to organizing API calls in Vue.js applications: centralizing calls in Vuex actions, managing calls with plain JavaScript objects, and keeping API calls within components using boilerplate callers.

Abstract

The article "Vue.js — Three common approaches to organize your API calls" outlines methods for structuring API interactions within single-page Vue.js applications. The first approach involves using Vuex actions to centralize all API calls, promoting a clean separation of concerns and encapsulation of data flow and business logic, which is particularly beneficial for applications with shared and concurrent data. The second method advocates for the use of plain JavaScript objects to manage API calls, offering flexibility and simplicity, making it suitable for a variety of applications without being tied to a specific data model. The third approach suggests embedding API calls directly into components with reusable boilerplate code, which is deemed efficient for short-term projects with stable endpoints. The article emphasizes that the choice of method depends on the project's requirements and scale, and it encourages readers to share other effective strategies for API call organization in Vue.js.

Opinions

  • Centralizing API calls in Vuex actions is considered very organized, encapsulating endpoints and logic, and is ideal for applications with shared data, but may be overkill for apps with distinct, localized states.
  • Managing API calls with plain JavaScript objects is praised for its simplicity, ease of learning, and adaptability, but criticized for potentially creating issues when Vue-specific actions need to be triggered from outside the Vue instance.
  • Keeping APIs in components with boilerplate callers is seen as a casual and straightforward approach, best for projects where scalability is not a primary concern and endpoints are stable.
  • The article suggests that there is no one-size-fits-all solution; the best approach depends on the specific needs and context of the Vue.js application being developed.
  • Readers are invited to contribute to the discussion by sharing alternative methods for handling API calls in Vue.js, indicating an open-ended and community-driven perspective on the topic.

Vue.js — Three common approaches to organize your API calls

When building a single page application, it is very common to make API calls to communicate with the server side, such as fetching data, submitting form, etc. Yet, Vue doesn’t provide an official practice for making API calls. Hence, I have summarized three common ways people are using to organize their APIs.

Concept of Programming and Software Development — by Andrey Suslov

1. Centralize all API calls in Vuex action

This approach is heavily inspired by the React-Redux model. Instead of having separated API calls in different components, you keep everything in Vuex action. Components know only actions but not endpoints. After the API call is returned, you do some data massage and business logic. After that, you update the state and notify components about the state change.

export default new Vuex.store({
  state: {
    account: null
  },
  mutations: {
    setAccount(state, account) {
      state.account = account;
    }
  },
  actions: {
    async signin({ commit }, { username, password }) {
      let data = await axios.get('/api/signin', { 
        username, 
        password
      });
      commit('setAccount', data)
    }
  }
}

Then somewhere in your component:

export default {
  computed: {
    account() {
      return this.$store.state.account
    }
  },
  ...
  methods: {
    submit(username, password) {
      this.$store.dispatch('signin', { username, password })
    },
    ...
  },
  ...
}

The major advantage is that this is probably one of the most organized approach so far. You encapsulate not only the endpoints, but also the logic. It is extremely clean for components as they only need to care about the state change. Yet, the drawback is also quite obvious. It relies on the model of single direction of data flow from the store to components. It works well on project with concurrent and shared data. Yet, for application that is consisted of many different pages with totally different functionalities and local states, you may find this approach a bit crunky.

2. Manage API calls with plain JavaScript objects

This approach is more straight forward comparing with the previous one. You just make a file with one or more objects, and put all your API calls there. Here is a simplest example:

const signin = async (username, password) => {
  let data = await axios.get('/api/signin', { 
    username, 
    password
  });
  let massageData = .... //Some data massage
  return massageData
}
export {
  signin
}

Then somewhere in your component:

import { signin } from '@/api';
export default {
  ...
  methods: {
    submit(username, password) {
      signin(username, password).then(account => {
        ...do something
      })
    },
    ...
  },
  ...
}

The major pros of this approach is that it is not coupled with any data model. It is easy to learn and flexible enough to work in almost any application. It provides good readability without a great impact on your application architecture. The drawback is things happen outside the Vue instance. It can be quite messy when you need to trigger some Vue actions inside your isolated objects instead of the components, such as changing states, pushing routes, etc.

3. Keep APIs in components with boilerplate caller

This is the most casual one. You define some boilerplate callers and keep the endpoints in your components. You may use a separated file to store those callers:

const postForm = (url, params = {}) => {
  let formData = new FormData();
  Object.entries(params).forEach(([key, value]) => {
    formData.set(key, value);
  });
  return axios({
    method: 'post',
    url: url,
    data: formData,
    headers: {'Content-Type': 'multipart/form-data' }
  })
}
export default { postForm };

And somewhere in your component:

import { postForm } from '@/api';
export default {
  ...
  methods: {
    submit(username, password) {
      postForm('/api/signin', { username, password })
        .then(account => {
          ...do something
        })
    },
    ...
  },
  ...
}

Or you may even use a mixin:

export default {
  methods: {
    $_apiCaller_postForm(url, params = {}) => {
      ...
    })
  }
}

The rationale behind is that scalability is not always the major concern. Sometimes you know you are working on a short term project, and the endpoints are very unlikely to have change. This approach suits best for these kind of one-off developments.

This article aims to provide a short introduction on some common approaches people use to make API calls in Vue. There is no right or wrong answer. No approach is definitely better than the others. It totally depends on the situation. Also, I believe there are many other approaches that are not listed in this article. Please feel free to leave a comment and let me know if you know something interesting. :)

Vue
Vuejs
Js
API
Recommended from ReadMedium