How to use Vue with REST API
Using Vue with REST APIs enables dynamic data interaction through HTTP requests for creating, reading, updating, and deleting data in modern web applications. As the creator of CoreUI with extensive Vue experience since 2014, I’ve built numerous enterprise applications that consume REST APIs for data management, user interfaces, and real-time updates. The most effective approach involves creating reusable composables that handle API requests, loading states, and error management using Vue 3’s Composition API. This method provides clean separation of concerns while ensuring reactive data updates and consistent error handling across your application.
Create reusable composables with Vue 3 Composition API to handle REST API interactions with proper error handling and loading states.
import { ref, computed } from 'vue'
import axios from 'axios'
// API composable for user management
export function useUserAPI() {
const users = ref([])
const currentUser = ref(null)
const isLoading = ref(false)
const error = ref(null)
const api = axios.create({
baseURL: '/api/v1',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${localStorage.getItem('token')}`
}
})
const fetchUsers = async () => {
try {
isLoading.value = true
error.value = null
const response = await api.get('/users')
users.value = response.data.data
} catch (err) {
error.value = err.response?.data?.message || 'Failed to fetch users'
} finally {
isLoading.value = false
}
}
const fetchUser = async (id) => {
try {
isLoading.value = true
error.value = null
const response = await api.get(`/users/${id}`)
currentUser.value = response.data.data
} catch (err) {
error.value = err.response?.data?.message || 'Failed to fetch user'
} finally {
isLoading.value = false
}
}
const createUser = async (userData) => {
try {
isLoading.value = true
error.value = null
const response = await api.post('/users', userData)
users.value.push(response.data.data)
return response.data.data
} catch (err) {
error.value = err.response?.data?.message || 'Failed to create user'
throw err
} finally {
isLoading.value = false
}
}
const updateUser = async (id, userData) => {
try {
isLoading.value = true
error.value = null
const response = await api.put(`/users/${id}`, userData)
const index = users.value.findIndex(user => user.id === id)
if (index !== -1) {
users.value[index] = response.data.data
}
return response.data.data
} catch (err) {
error.value = err.response?.data?.message || 'Failed to update user'
throw err
} finally {
isLoading.value = false
}
}
const deleteUser = async (id) => {
try {
isLoading.value = true
error.value = null
await api.delete(`/users/${id}`)
users.value = users.value.filter(user => user.id !== id)
} catch (err) {
error.value = err.response?.data?.message || 'Failed to delete user'
throw err
} finally {
isLoading.value = false
}
}
return {
users: computed(() => users.value),
currentUser: computed(() => currentUser.value),
isLoading: computed(() => isLoading.value),
error: computed(() => error.value),
fetchUsers,
fetchUser,
createUser,
updateUser,
deleteUser
}
}
This code demonstrates a complete REST API integration using a reusable composable that handles CRUD operations with proper error handling, loading states, and reactive data management. The composable uses Axios for HTTP requests with authentication headers and provides computed properties for reactive state access. Each API method handles loading states and errors consistently while updating the local data store, ensuring your Vue components stay synchronized with server data.
Best Practice Note:
This is the REST API integration pattern we use in CoreUI dashboard applications for robust data management and user experience. Implement request interceptors for authentication token refresh and response interceptors for global error handling to enhance reliability and security.



