0%

axios - 管理 API

前言

不知道大家有沒有遇過 API 已經設定好了,某天被告知 domain 有調整過,或是某些 getpost方法需要多加參數等設定,導致必須不斷地找專案內 call API 的地方,有時還會遺漏幾處產生嚴重問題呢。以下教各位如何高效率的管理專案內的 API,即便是小專案也該如此。

官方 axios 範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import axios from 'axios'; /* 依照你的專案形式引入套件 */

/* GET */
axios.get('http://api/user')
.then(res =>{
console.log(res);
}).catch(err => {
console.log(err);
})

/* POST */
axios.post('http://api/user', {
firstName: 'Cloud',
lastName: 'Su'
})
.then(res => {
console.log(response);
})
.catch(err => {
console.log(error);
});

這種作法相當直覺,針對特定功能去 call api,確實可以這樣寫,但當專案 API 超過 10 支、20支甚至更多時,這樣子的寫法就變得不好管理,如果 domain參數一改,就得一個一個找出來慢慢改,真的很麻煩。

高效率管理 API 方法

使用官方的 axios.create 方法,可以利用此方法來新增一個 axios 實體。
首先建立 api.js,之後 API 都在這支檔案內管理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import axios from 'axios';

/* 購物車 API */
const CartRequest = axios.create({
baseURL: `${process.env.API_PATH}/shopping/cart`,
headers: {
'api-caller': 'xxx',
'api-version': 1,
'api-position': 'JH',
'api-language': 'zh-TW',
cart_serial: {
toString() {
return `${localStorage.getItem('cart_serial')}`;
},
},
Authorization: {
toString() {
return `bearer ${localStorage.getItem('loginToken')}`;
},
},
},
});

/* 折價券 API */
const CouponRequest = axios.create({
baseURL: `${process.env.API_PATH}/shopping/coupon`,
headers: {
'api-caller': 'xxx',
'api-version': 1,
'api-position': 'JH',
'api-language': 'zh-TW',
cart_serial: {
toString() {
return `${localStorage.getItem('cart_serial')}`;
},
},
Authorization: {
toString() {
return `bearer ${localStorage.getItem('loginToken')}`;
},
},
},
});

/* 登入 API */
const loginRequest = axios.create({
baseURL: `${process.env.API_PATH}/login`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
});

/* 購物車 API */
export const API_CART_SERIAL = (data) => CartRequest.put('/init', data);
export const API_CART = () => CartRequest.get();
export const API_ADDTO_CART = (data) => CartRequest.post('/item', data);
/* delete 的參數必須先用 Object 包起來 */
export const API_DELETE_CART = (data) => CartRequest.delete('/item', { data });

/* 登入 API */
/* post 必須要有第一個 url 參數,都不寫的話就是指向 API 的根目錄 */
export const API_LOGIN = (data) => loginRequest.post('', data);

/* 折價券 API */
/* 還可使用傳入參數來變更 API 路徑 */
export const API_USE_COUPON = (couponCode) => CouponRequest.post(`/${couponCode}`);

要使用的話,直接 import 這支 api.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/* 只 import 要使用的 API */
import { API_LOGIN, API_USE_COUPON, API_DELETE_CART } from 'api.js';

async login() {
const loginForm = {
UserName: 'xxx',
Password: 'xxx',
};
const data = vm.Qs.stringify(loginForm);
try {
await API_LOGIN(data);
} catch (err) {
console.error(err);
}
}

async use_shopping_coupon(context, couponCode) {
try {
await API_USE_COUPON(couponCode);
} catch (error) {
console.log(error);
}
},

async delete_cart(context, id) {
const product = {
is_need_cart_data: true,
product_spec_serial: id,
};
try {
API_DELETE_CART(product);
} catch (error) {
console.log(error);
}
},

高效率的管理優點

  1. 可以確保所有的 API 都是同一進入點,即便在各元件 js 內呼叫 API,最後只需管理一支 api,對於日後 API 有需要要修改會方便很多。
  2. 使用 axios.create 產生出的實體可以透過變數的方式給予新的 API 名稱,透過團隊命名規範來清楚知道 API 的功能。
  3. 除了可以減少超長的 api url,還能大幅減少程式碼的撰寫,並搭配 axios 回傳的 Promise 特性,可以使用 Async / Await 減少 .then() 的寫法,提高程式碼可讀性

參考資料

使用Axios你的API都怎麼管理?