Tutorial

Vue.js REST API Consumption with Axios

Vue.js

While this tutorial has content that we believe is of great benefit to our community, we have not yet tested or edited it to ensure you have an error-free learning experience. It's on our list, and we're working on it! You can help us out by using the "report an issue" button at the bottom of the tutorial.

Quite a few frameworks have built-in HTTP APIs. Angular 2 has the http module, JQuery has $.ajax, and, up until Vue 2.0, Vue.js had vue-resource. In Vue 2.0, the developers decided that having a built-in http client module was rather redundant, and could be better serviced by third-party libraries. The alternative most frequently recommended is Axios.

Axios is a great http client library. It uses promises by default and runs on both the client and the server (which makes it appropriate for fetching data during server-side rendering). It’s also quite easy to use with Vue. Because it uses promises, you can combine it with async/await to get an amazingly concise and easy-to-use API, as I will demonstrate here.

Installation

Axios should be installed from NPM or Yarn:

# Yarn
$ yarn add axios

# NPM
$ npm install axios --save

Populating Data with a GET Request

While it’s generally poor practice, you can use Axios directly in your components to fetch data from a method, lifecycle hook, or whenever.

ExampleComponent.vue
<template>
  <ul v-if="posts && posts.length">
    <li v-for="post of posts">
      <p><strong>{{post.title}}</strong></p>
      <p>{{post.body}}</p>
    </li>
  </ul>

  <ul v-if="errors && errors.length">
    <li v-for="error of errors">
      {{error.message}}
    </li>
  </ul>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      posts: [],
      errors: []
    }
  },

  // Fetches posts when the component is created.
  created() {
    axios.get(`http://jsonplaceholder.typicode.com/posts`)
    .then(response => {
      // JSON responses are automatically parsed.
      this.posts = response.data
    })
    .catch(e => {
      this.errors.push(e)
    })

    // async / await version (created() becomes async created())
    //
    // try {
    //   const response = await axios.get(`http://jsonplaceholder.typicode.com/posts`)
    //   this.posts = response.data
    // } catch (e) {
    //   this.errors.push(e)
    // }
  }
}
</script>

Pushing Data with a POST Request

One can send POST, PUT, PATCH, and DELETE requests just as easily.

(Note, it’s a terrible idea to send requests on every input event, at the very least do some throttling or debouncing.)

ExampleComponent.vue
<template>
  <input type="text" v-model="postBody" @change="postPost()"/>
  <ul v-if="errors && errors.length">
    <li v-for="error of errors">
      {{error.message}}
    </li>
  </ul>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      postBody: '',
      errors: []
    }
  },

  // Pushes posts to the server when called.
  postPost() {
    axios.post(`http://jsonplaceholder.typicode.com/posts`, {
      body: this.postBody
    })
    .then(response => {})
    .catch(e => {
      this.errors.push(e)
    })

    // async / await version (postPost() becomes async postPost())
    //
    // try {
    //   await axios.post(`http://jsonplaceholder.typicode.com/posts`, {
    //     body: this.postBody
    //   })
    // } catch (e) {
    //   this.errors.push(e)
    // }
  }
}
</script>

A Common Base Instance

A frequently overlooked but very useful capability Axios provides is the ability to create a base instance that allows you to share a common base URL and configuration across all calls to the instance. This comes in handy if all of your calls are to a particular server, or need to share headers, such as an authorization header.

http-common.js
import axios from 'axios';

export const HTTP = axios.create({
  baseURL: `http://jsonplaceholder.typicode.com/`,
  headers: {
    Authorization: 'Bearer {token}'
  }
})

You could now use HTTP like so,

<script>
import {HTTP} from './http-common';

export default {
  data() {
    return {
      posts: [],
      errors: []
    }
  },

  created() {
    HTTP.get(`posts`)
    .then(response => {
      this.posts = response.data
    })
    .catch(e => {
      this.errors.push(e)
    })
  }
}
</script>

Reference

That’s just scratching the surface of what Axios can do. See the GitHub repository for more information and documentation.

Creative Commons License