iT邦幫忙

2021 iThome 鐵人賽

DAY 13
1
Modern Web

Vue.js 進階心法系列 第 13

處理 API 層次感之地基篇

先重新封裝 axios 的用法。並且一開始先不打算開放使用 axios 原生功能。

希望可以讓

GET: API.GET(url, params)

其它的就照 axios 原本的寫法,DELETE 不能用 body

有一次,案子還是在 DELETE 的 API 帶 body。就把 DELETE 另外用 fetch 實作,而不是用 axios 。但也因為有下面這樣的寫法,所以可以共用 host 或 header。

下面的程式碼,放在同一個檔案src/utitlity/backendAPI.js

定義 API 發送的基本規定

axios - github

src/utitlity/backendAPI.js

  • 決定 host
  • API 的版本
  • 可能要儲存 token
  • 最常見的 request 的 header
import axios from 'axios';

const backendAPI = axios.create({
  baseURL: `http://127.0.0.1`,
  headers: {
    'Content-Type': 'application/json',
    Accept: 'application/json'
  }
});

const token = null;

interceptors

在此是 request 的 interceptors。
負責處理「在送出 API 之前」的事,要添加 token

backendAPI.interceptors.request.use(
  config => {
    // Do something before request is sent
    if (token) {
      config.headers['Authorization'] = `Bearer ${token}`;
    }
    return config;
  },
  function(error) {
    // Do something with request error
    return Promise.reject(error);
  }
);

處理 response 的部份,會放在 new Vue()created() 的 lifecycle 處理。

本體

大致上分成兩個部份。

  • CRUD 型 (一定要有)
    • GET
    • POST
    • PUT, PATCH
    • DELETE
  • 其它特殊型
    • login 或處理 token 相關
    • multipart/form-data 的 POST
export default {
  async login({ user, password }) {
    const res = await backendAPI.post('/login', {
      user,
      password
    })
    token = res.data.token
    return Promise.reject(res.data);
  },
  async formDataPOST(url, data, config) {
    try {
      const form = new FormData();
      for (let key in data) {
        form.append(key, data[key]);
      }
      const res = await backendAPI.post(url, form, {
        headers: {
          'Content-Type': 'multipart/form-data'
        },
        ...config
      });
      return res.data;
    } catch (res) {
      return Promise.reject(res.data);
    }
  },
  async GET(url, params) {
    try {
      const res = await backendAPI.get(url, {
        params
      });
      return res.data;
    } catch (res) {
      return Promise.reject(res.data);
    }
  },
  async POST(...arge) {
    try {
      const res = await backendAPI.post(...arge);
      return res.data;
    } catch (res) {
      return Promise.reject(res.data);
    }
  },
  async PUT(...arge) {
    try {
      const res = await backendAPI.put(...arge);
      return res.data;
    } catch (res) {
      return Promise.reject(res.data);
    }
  },
  async DELETE(url, params) {
    try {
      const res = await backendAPI.delete(url, {
        params
      });
      return res.data;
    } catch (res) {
      return Promise.reject(res.data);
    }
  }
};

基本的錯誤(導流)導流

在此會處理 API 回覆不是 200 的錯誤,初步處理將程式流程導到處理錯誤的流程。並且回傳適合的資料層次。

有些後端,會在出錯時給這種格式,不知道是不是框架預設值

{
  "data": ""
}

有些後端,會在出錯時給另一種格式

{
  "detail": "",
  "code": 123
}

為了適應各種後端,所以希望可以處理各種後端送過來的資料。
不過同一個後端應該會送相同的錯誤處理格式。


上一篇
Vuex 的使用偏好
下一篇
讓程式碼化為 API Doc
系列文
Vue.js 進階心法30

尚未有邦友留言

立即登入留言