概要
request が deprecated になっており、トレンドも axios に移っているようだ。
なので、コードの置き換えを検討している。async/await にすると可読性があがるかもと試した内容を記載する。
結論
結論からいうと因果関係のある処理を async/await に置き換えると可読性が高まる。
サンプルコード: then()を使う
ユーザー認証をして得たトークンを元にリクエストをする例。
簡単すぎるコードでは検証にならないのでやや複雑なコードになっている。
'use strict'
const axios = require('axios');
axios(
{
url: 'https://httpbin.org/post?token=XXXXXXXX',
// url: 'https://httpbin.org/status/500?token=XXXXXXXX',
headers: {
'Content-Type': 'application/json'
},
method: 'post',
data: {
id: 'john.doe',
pass: '********'
}
}
).then(function (responseToken) {
console.log(`Request URI: ${responseToken.config.url}`);
const token = responseToken.data.args.token;
console.log(token);
axios(
{
url: 'https://httpbin.org/get?foo=bar',
headers: {
'Authorization': 'Bearer ' + token
},
method: 'get'
}
).then(function (response) {
console.log(`Request URI: ${response.config.url}`);
console.log(`response body: ${JSON.stringify(response.data.args)}`);
}).catch(function(error) {
console.log(`Request URI: ${error.config.url}`);
console.log(`${error.response.status} ${error.response.statusText}`);
return `${error.response.status} ${error.response.statusText}`
})
}).catch(function(error) {
console.log(`Request URI: ${error.config.url}`);
console.log(`${error.response.status} ${error.response.statusText}`);
return `${error.response.status} ${error.response.statusText}`
})
正常時の実行結果
Request URI: https://httpbin.org/post?token=XXXXXXXX
XXXXXXXX
Request URI: https://httpbin.org/get?foo=bar
response body: {"foo":"bar"}
異常時の実行結果
入れ子なので token 取得に失敗したら、 /get?foo=bar
の処理は実行はしない。期待通りの動作。
Request URI: https://httpbin.org/status/500?token=XXXXXXXX
500 INTERNAL SERVER ERROR
サンプルコード: await/asyncを使う
ちょっとわかりにくいと思うが、await axios()
await axios()
と同じレベルでコードが並んでいる。
入れ子でないので、前のリクエストの結果に依存する処理が増えても可読性が悪くはならない。
例外は二つのリクエストで共通となる。let token = undefined
というように let
を使っているのは、catch
ブロック中でどこまで進んだのか判断できるようにするため。これで、処理の進み具合によってエラー処理を変えることができるため、前述の then/catch のように細かいエラー処理も可能になる。
'use strict'
const axios = require('axios');
async function main() {
let token = undefined
let resOfGetToken = undefined
let resOfGetFoo = undefined
try {
resOfGetToken = await axios(
{
url: 'https://httpbin.org/post?token=XXXXXXXX',
// url: 'https://httpbin.org/status/500?token=XXXXXXXX',
headers: {
'Content-Type': 'application/json'
},
method: 'post',
data: {
id: 'john.doe',
pass: '********'
}
}
)
token = resOfGetToken.data.args.token;
console.log(`Request URI: ${resOfGetToken.config.url}`);
console.log(`token: ${token}`);
resOfGetFoo = await axios(
{
url: 'https://httpbin.org/get?foo=bar',
headers: {
'Authorization': 'Bearer ' + token
},
method: 'get'
}
)
console.log(`Request URI: ${resOfGetFoo.config.url}`);
console.log(`response body: ${JSON.stringify(resOfGetFoo.data.args)}`);
} catch(error) {
console.log("error.name=" + error.name);
console.log("error.toString()=" + error.toString());
console.log("Error.prototype.toString()=" + Error.prototype.toString())
if ('isAxiosError' in error) {
console.log(`Request URI: ${error.request.path}`);
console.log(`${error.response.status} ${error.response.statusText}`);
}
}
}
try {
main()
} catch(e) {
console.log(e)
}
正常時の実行結果
Request URI: https://httpbin.org/post?token=XXXXXXXX
token: XXXXXXXX
Request URI: https://httpbin.org/get?foo=bar
response body: {"foo":"bar"}
異常時の実行結果
token 取得に失敗し、後続の処理を中断できている。
error.name=Error
error.toString()=Error: Request failed with status code 500
Error.prototype.toString()=Error
Request URI: /status/500?token=XXXXXXXX
500 INTERNAL SERVER ERROR
サンプルコード3: パラメータを組み立てる処理を関数化した
'use strict'
const axiosBase = require('axios');
const axiosToBFF = axiosBase.create(
{
baseURL: 'https://httpbin.org'
}
)
async function getToken(id_, pass_) {
return axiosToBFF.request(
{
url: '/post?token=XXXXXXXX',
// url: '/status/500?token=XXXXXXXX',
headers: {
'Content-Type': 'application/json'
},
method: 'post',
data: {
id: id_,
pass: pass_
}
}
)
}
async function getFoo(val) {
return axiosToBFF.request(
{
url: `/get?foo=${val}`,
headers: {
'Accept': 'application/json',
'Cache-Control': 'no-cache'
},
method: 'get'
}
)
}
async function main() {
let accessToken = undefined
let resOfGetToken = undefined
let resOfGetFoo = undefined
try {
resOfGetToken = await getToken('john.doe', '********')
accessToken = resOfGetToken.data.args.token;
console.log(`Request URI: ${resOfGetToken.config.url}`);
console.log(`token: ${accessToken}`);
axiosToBFF.defaults.headers.common['Authorization'] = `Bearer ${accessToken}`
resOfGetFoo = await getFoo("bar")
console.log(`Request URI: ${resOfGetFoo.config.url}`);
console.log(`response body: ${JSON.stringify(resOfGetFoo.data.args)}`);
} catch(error) {
console.log("error.name=" + error.name);
console.log("error.toString()=" + error.toString());
console.log("Error.prototype.toString()=" + Error.prototype.toString())
if ('isAxiosError' in error) {
console.log(`Request URI: ${error.request.path}`);
console.log(`${error.response.status} ${error.response.statusText}`);
}
}
}
try {
main()
} catch(e) {
console.log(e)
}