larabel 및 vue js를 사용하여 Axios 오류를 처리하는 더 나은 방법이 있습니까?
그래서 저는 larabel을 백엔드로, vue js를 스파 프런트엔드 프레임워크로 사용하여 spa 웹 앱을 만들고 있습니다. 저는 larabel passport를 사용하여 api를 인증하고 있으며, vuex를 사용하여 애플리케이션 상태를 관리하고 있습니다.
먼저 api 파일을 생성하여 api와 상호 작용합니다.
import { BKCU_CONFIG } from '../config.js';
export default {
getArtikelS: function( p ){
return axios.get( BKCU_CONFIG.API_URL + '/artikel' + `?column=${p.column}&direction=${p.direction}&per_page=${p.per_page}&page=${p.page}&search_column=${p.search_column}&search_operator=${p.search_operator}&search_query_1=${p.search_query_1}&search_query_2=${p.search_query_2}`);
},
getArtikelCUS: function( p, id ){
return axios.get( BKCU_CONFIG.API_URL + '/artikel/indexCU/' + id + `?column=${p.column}&direction=${p.direction}&per_page=${p.per_page}&page=${p.page}&search_column=${p.search_column}&search_operator=${p.search_operator}&search_query_1=${p.search_query_1}&search_query_2=${p.search_query_2}`);
},
getArtikel: function( id ){
return axios.get(BKCU_CONFIG.API_URL + '/artikel/' + id);
},
createArtikel: function(){
return axios.get(BKCU_CONFIG.API_URL + '/artikel/create');
},
storeArtikel: function ( form ){
return axios.post(BKCU_CONFIG.API_URL + '/artikel/store', form);
},
editArtikel: function( id ){
return axios.get(BKCU_CONFIG.API_URL + '/artikel/edit/' + id);
},
updateArtikel: function ( id, form ){
return axios.post(BKCU_CONFIG.API_URL + '/artikel/update/' + id, form);
},
updateTerbitkan: function( id ){
return axios.post(BKCU_CONFIG.API_URL + '/artikel/updateTerbitkan/' + id);
},
updateUtamakan: function( id ){
return axios.post(BKCU_CONFIG.API_URL + '/artikel/updateUtamakan/' + id);
},
deleteArtikel: function( id ){
return axios.delete(BKCU_CONFIG.API_URL + '/artikel/' + id);
}
}
그런 다음 각 모델에 대해 vuex 모듈을 만듭니다. 예를 들어 다음과 같습니다.
import ArtikelAPI from '../../api/artikel.js';
export const artikel = {
state: {
artikelS: [],
artikelLoadStatS: '',
artikel: {},
artikelLoadStat: '',
artikelUpdate: '',
artikelUpdateStat: '',
artikelRules: [],
artikelOption: [],
},
actions: {
// load all
loadArtikelS( { commit }, p ){
commit('setArtikelLoadStatS', 'loading');
ArtikelAPI.getArtikelS( p )
.then( function( response ){
commit('setArtikelS', response.data.model);
commit('setArtikelLoadStatS', 'success');
})
.catch( error => {
commit('setArtikelS', error.response);
commit('setArtikelLoadStatS', 'fail');
});
},
// load by cu
loadArtikelCUS( { commit }, [p, id] ){
commit('setArtikelLoadStatS', 'loading');
ArtikelAPI.getArtikelCUS( p, id )
.then( function( response ){
commit('setArtikelS', response.data.model);
commit('setArtikelLoadStatS', 'success');
})
.catch( error => {
commit('setArtikelS', error.response);
commit('setArtikelLoadStatS', 'fail');
});
},
// load single data
loadArtikel( {commit}, id ){
commit('setArtikelLoadStat', 'loading');
ArtikelAPI.getArtikel( id )
.then( function( response ){
commit('setArtikel', response.data );
commit('setArtikelLoadStat', 'success');
})
.catch( error => {
commit('setArtikelS', error.response);
commit('setArtikelLoadStatS', 'fail');
});
},
// create page
createArtikel( {commit} ){
commit('setArtikelLoadStat', 'loading');
ArtikelAPI.createArtikel()
.then( function( response ){
commit('setArtikel', response.data.form );
commit('setArtikelRules', response.data.rules);
commit('setArtikelOption', response.data.option)
commit('setArtikelLoadStat', 'success');
})
.catch( function(){
commit('setArtikel', []);
commit('setArtikelRules', []);
commit('setArtikelOption', [])
commit('setArtikelLoadStat', 'fail');
});
},
// store data
storeArtikel( {commit, state, dispatch}, form ){
commit('setArtikelUpdateStat', 'loading');
ArtikelAPI.storeArtikel( form )
.then( function( response ){
if(response.data.saved){
commit('setArtikelUpdate', response.data);
commit('setArtikelUpdateStat', 'success');
}else{
commit('setArtikelUpdateStat', 'fail');
}
})
.catch(error => {
if (error.response.status) {
this.errors = error.response.data;
commit('setArtikelUpdate', this.errors);
}else{
commit('setArtikelUpdate', 'Oops terjadi kesalahan :(');
}
commit('setArtikelUpdateStat', 'fail');
});
},
// edit page
editArtikel( {commit}, id ){
commit('setArtikelLoadStat', 'loading');
ArtikelAPI.editArtikel( id )
.then( function( response ){
commit('setArtikel', response.data.form );
commit('setArtikelRules', response.data.rules);
commit('setArtikelOption', response.data.option)
commit('setArtikelLoadStat', 'success');
})
.catch( function(){
commit('setArtikel', []);
commit('setArtikelRules', []);
commit('setArtikelOption', [])
commit('setArtikelLoadStat', 'fail');
});
},
// update data
updateArtikel( {commit, state, dispatch}, [id, form] ){
commit('setArtikelUpdateStat', 'loading');
ArtikelAPI.updateArtikel( id, form )
.then( function( response ){
if(response.data.saved){
commit('setArtikelUpdate', response.data);
commit('setArtikelUpdateStat', 'success');
}else{
commit('setArtikelUpdateStat', 'fail');
}
})
.catch(error => {
if (error.response.status) {
this.errors = error.response.data;
commit('setArtikelUpdate', this.errors);
}else{
commit('setArtikelUpdate', 'Oops terjadi kesalahan :(');
}
commit('setArtikelUpdateStat', 'fail');
});
},
updateArtikelTerbitkan( {commit, state, dispatch}, id ){
commit('setArtikelUpdateStat', 'loading');
ArtikelAPI.updateTerbitkan( id )
.then( function( response ){
if(response.data.saved){
commit('setArtikelUpdate', response.data);
commit('setArtikelUpdateStat', 'success');
}else{
commit('setArtikelUpdateStat', 'fail');
}
})
.catch(error => {
if (error.response.status) {
this.errors = error.response.data;
commit('setArtikelUpdate', this.errors);
}else{
commit('setArtikelUpdate', 'Oops terjadi kesalahan :(');
}
commit('setArtikelUpdateStat', 'fail');
});
},
updateArtikelUtamakan( {commit, state, dispatch}, id ){
commit('setArtikelUpdateStat', 'loading');
ArtikelAPI.updateUtamakan( id )
.then( function( response ){
if(response.data.saved){
commit('setArtikelUpdate', response.data);
commit('setArtikelUpdateStat', 'success');
}else{
commit('setArtikelUpdateStat', 'fail');
}
})
.catch(error => {
if (error.response.status) {
this.errors = error.response.data;
commit('setArtikelUpdate', this.errors);
}else{
commit('setArtikelUpdate', 'Oops terjadi kesalahan :(');
}
commit('setArtikelUpdateStat', 'fail');
});
},
// delete data
deleteArtikel( {commit, state, dispatch}, id ){
commit('setArtikelUpdateStat', 'loading');
ArtikelAPI.deleteArtikel( id )
.then( function( response ){
if(response.data.saved){
commit('setArtikelUpdate', response.data);
commit('setArtikelUpdateStat', 'success');
}else{
commit('setArtikelUpdateStat', 'fail');
}
})
.catch(error => {
if (error.response.status) {
this.errors = error.response.data;
commit('setArtikelUpdate', this.errors);
}else{
commit('setArtikelUpdate', 'Oops terjadi kesalahan :(');
}
commit('setArtikelUpdateStat', 'fail');
});
},
// reset status
resetArtikelUpdateStat( {commit} ){
commit('setArtikelUpdateStat', '');
}
},
mutations: {
setArtikelS ( state, artikelS ){
state.artikelS = artikelS;
},
setArtikelLoadStatS( state, status ){
state.artikelLoadStatS = status;
},
setArtikel ( state, artikel ){
state.artikel = artikel;
},
setArtikelLoadStat( state, status ){
state.artikelLoadStat = status;
},
setArtikelUpdateStat( state, status ){
state.artikelUpdateStat = status;
},
setArtikelUpdate( state, data ){
state.artikelUpdate = data;
},
setArtikelRules( state, rules ){
state.artikelRules = rules;
},
setArtikelOption( state, option ){
state.artikelOption = option;
}
},
getters: {
getArtikelS( state ){
return state.artikelS;
},
getArtikelLoadStatS ( state ){
return state.artikelLoadStatS;
},
getArtikel( state ){
return state.artikel;
},
getArtikelLoadStat ( state ){
return state.artikelLoadStat;
},
getArtikelUpdateStat ( state ){
return state.artikelUpdateStat;
},
getArtikelUpdate ( state ){
return state.artikelUpdate;
},
getArtikelRules ( state ){
return state.artikelRules;
},
getArtikelOption ( state ){
return state.artikelOption;
}
}
}
보시다시피 각각의 액션에는 에러 캐치가 포함되어 있으며, 에러 캐치 및 메시지만 표시됩니다.나는 이런 식으로 일을 처리하는 데 몇 가지 단점을 발견한다
이런 종류의 워크플로우를 개선하는 데 도움을 줄 수 있는 사람이 있을지도 모릅니다.모든 것이 잘 작동하고 매우 구조화되어 있습니다만, 에러 검출이 부족한 것은 다음과 같습니다.
- larabel을 사용하고 있기 때문에 토큰의 유효기간이 지났기 때문에(사용자가 PC를 일정기간 방치하고 있기 때문에) 인증된 에러 메시지가 사용자에게 그다지 친숙하지 않게 표시됩니다.사용자를 로그인 페이지로 리다이렉트하여 다시 로그인한 후 현재 접속하고 있는 페이지로 되돌리고 싶습니다.
- 여기서 코드를 반복하는 경우가 많은 것 같습니다만, 이 모든 Axios 요청에 대해 하나의 에러 처리를 할 수 있을까요?
이 보일러 플레이트를 없애기 위해 악시의 특징을 사용할 수 있습니다.
가로채기 사용
axios.interceptors.response.use(response => {
return response.data;
}, error => {
if (error.response && error.response.data) {
// handle your errors here.
handleServerErrors(error.response.data);
}
return Promise.reject(error);
});
Axios 기본값 사용
axios.defaults.timeout = 5000;
axios.defaults.baseURL = BKCU_CONFIG.API_URL
URL을 더 이상 연결하지 마십시오.기본 URL을 이미 설정했으므로 다음을 수행할 수 있습니다.
getArtikel: function( id ){
return axios.get('/artikel/' + id);
}
ES6 기능 및 악시오 파라미터를 사용하여 이 기능을 전환할 수 있습니다.
getArtikelS: function( p ){
return axios.get( BKCU_CONFIG.API_URL + '/artikel' + `?column=${p.column}&direction=${p.direction}&per_page=${p.per_page}&page=${p.page}&search_column=${p.search_column}&search_operator=${p.search_operator}&search_query_1=${p.search_query_1}&search_query_2=${p.search_query_2}`);
},
이렇게 더 좋은 곳으로
getArtikelS(p){
return axios.get(`/artikel`, {params: p})
}
Axios는 오브젝트로 파라미터를 지원하므로 이상한 쿼리 문자열을 쓸 필요가 없습니다.
마지막 힌트:모든 것을 vuex에 저장하지 마십시오.두 개 이상의 컴포넌트에 해당 데이터가 필요하지 않은 경우 컴포넌트에 있는 api를 직접 호출합니다.
요격기를 사용할 수 있습니다.단, 백엔드는 오류를 고려하여 대응하는 메시지를 프런트엔드로 전송해야 합니다.
request.interceptors.response.use(response => {
return response
}, error => {
//Put your logic here to manage the error message coming from BE
return Promise.reject(error )
})
완전한 예에 대해서는, 앱에 Axios 인스턴스 전체를 실장하고 있는 방법을 참조해 주세요.
(Vuetify 스낵바 컴포넌트를 사용하여 에러 메시지를 표시)
import axios from 'axios'
import { store } from "../../store/store"
import { eventBus } from "../main";
const request = axios.create({
baseURL: 'http://localhost:8000'
})
request.interceptors.request.use(request => {
const token = store.state.token
if (token) {
request.headers.Authorization = 'Bearer ' + token
}
return request
}, error => {
return Promise.reject(error)
})
request.interceptors.response.use(response => {
return response
}, error => { //getting error from backend and display it with snackbar(vuetify component)
eventBus.$emit('snackBar', {
text: error.response.data.message,
snackbarColor: 'red darken-4'
})
return Promise.reject(error )
})
export default request
Larabel 오류 메시지 예시:
return response()->json(["message" => "You have not access to perform this action"],403);
언급URL : https://stackoverflow.com/questions/49262353/is-there-any-better-way-to-handling-axios-error-with-laravel-and-vue-js
'programing' 카테고리의 다른 글
플러그인을 사용해도 babel이 확산 연산자를 전치하도록 가져올 수 없습니다. (0) | 2022.08.09 |
---|---|
파일을 지우지 않고 스코프 형식의 태그로 Import하려면 어떻게 해야 합니까? (0) | 2022.08.09 |
이미지가 Vue.js 2에 로드되지 않는 이유는 무엇입니까? (0) | 2022.08.09 |
C에서는 시프트 연산자(<, >)가 산술입니까 논리입니까? (0) | 2022.08.07 |
정수의 제곱근이 정수인지 확인하는 가장 빠른 방 (0) | 2022.07.17 |