programing

larabel 및 vue js를 사용하여 Axios 오류를 처리하는 더 나은 방법이 있습니까?

yoursource 2022. 8. 9. 21:47
반응형

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;
    }
  }
}

보시다시피 각각의 액션에는 에러 캐치가 포함되어 있으며, 에러 캐치 및 메시지만 표시됩니다.나는 이런 식으로 일을 처리하는 데 몇 가지 단점을 발견한다

이런 종류의 워크플로우를 개선하는 데 도움을 줄 수 있는 사람이 있을지도 모릅니다.모든 것이 잘 작동하고 매우 구조화되어 있습니다만, 에러 검출이 부족한 것은 다음과 같습니다.

  1. larabel을 사용하고 있기 때문에 토큰의 유효기간이 지났기 때문에(사용자가 PC를 일정기간 방치하고 있기 때문에) 인증된 에러 메시지가 사용자에게 그다지 친숙하지 않게 표시됩니다.사용자를 로그인 페이지로 리다이렉트하여 다시 로그인한 후 현재 접속하고 있는 페이지로 되돌리고 싶습니다.
  2. 여기서 코드를 반복하는 경우가 많은 것 같습니다만, 이 모든 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

반응형