🎸
ポストaxiosのky
kyとは
kyはブラウザとDenoのためのhttp clientです。
最近ではNuxt.jsのhttp moduleに使用されるなど、人気が高まりつつあります。
名前の由来は特にないみたいだが、日本語のKYも意識されているみたい?
A form of text-able slang, KY is an abbreviation for 空気読めない (kuuki yomenai),
which literally translates into “cannot read the air.”
It's a phrase applied to someone who misses the implied meaning.
axiosとの違い
- axiosはXMLHttpRequestで実装されているのに対し、kyはfetchで実装されているので、Service Workerに対応可能
- axiosはfetchにある機能も独自に実装しているので、より安定しているfetch apiをベースにしているkyの方がバグが少ない(本人談)
- 軽量(axiosは4.6KB、kyは2.8KB)
- リクエストのリトライ機能がある。
特にaxiosと比べて欠点はなさそう。
使い方
GET
import ky from 'ky';
(async () => {
const res = await ky.get('https://reqres.in/api/users/1').json();
})();
POST
import ky from 'ky';
(async () => {
const res = await ky
.post('https://reqres.in/api/users/', {
json: {
name: 'Luke Skywalker',
job: 'Jedi',
},
})
.json();
})();
第一引数にリクエストのurl、第二引数にoptionのオブジェクトを渡します。
optionはfetchと同じ項目に加えて、いくつか独自の項目があります。
json
jsonを送信するときはbodyの代わりに、このjsonオプションにオブジェクトを設定できる。上のPOSTの例でも使いました。
searchParams
クエリパラメーターの設定
import ky from 'ky';
(async () => {
const res = await ky
.get('https://reqres.in/api/users/', {
searchParams: {
page: 2
},
})
// /api/users?page=2
.json();
})();
prefixUrl
リクエストurlのprefixを指定します。prefixの文字列の最後に/
を付けなくても自動的に追加されます。
import ky from "ky";
(async () => {
const res = await ky
.post('users', {
prefixUrl: 'https://reqres.in/api',
json: {
name: 'Luke Skywalker',
job: 'Jedi',
},
})
// https://reqres.in/api/users
.json();
})();
retry
リクエストが失敗した際にリトライする設定。
- limit: リトライできる最大回数
- methods: http methodの配列
- statusCodes: リトライを行うhttp statusの配列
- maxRetryAfter: Retry-Afterの上限を設定。
単に数値を設定した場合はlimitの値が設定される。
import ky from "ky";
(async () => {
const res = await ky
.post('https://reqres.in/api/login', {
retry: 10
})
.json();
})();
(async () => {
const res = await ky
.post('https://reqres.in/api/login', {
retry: {
limit: 10,
methods: ['post'],
statusCodes: [503],
},
})
.json();
})();
timeout
defaultでは10000ms。
falseにするとtimeoutなしにもできる。
hooks
リクエストのライフサイクルで実行する関数を配列で設定する。ライフサイクル一覧とそれぞれの関数の型を以下の通り。
- beforeRequests リクエストを送信する前
beforeRequests: BeforeRequestHook[]
export type BeforeRequestHook = (
request: Request,
options: NormalizedOptions,
) => Request | Response | void | Promise<Request | Response | void>;
- beforeRetry リトライする前
公式の例にもあるが、リトライ前にapi tokenをリフレッシュするときに便利そう。
beforeRetry: BeforeRetryHook[]
export type BeforeRetryHook = (options: {
request: Request;
response: Response;
options: NormalizedOptions;
error: Error;
retryCount: number;
}) => void | Promise<void>;
- afterResponse レスポンスを受け取った後
レスポンスのstatusによって、その後の処理を変えたいなど
afterResponse: AfterResponseHook[]
export type AfterResponseHook = (
request: Request,
options: NormalizedOptions,
response: Response,
) => Response | void | Promise<Response | void>;
onDownloadProgress
ダウンロードの進捗状況を取得できる。
onDownloadProgress: (progress: DownloadProgress, chunk: Uint8Array) => void;
interface DownloadProgress {
percent: number;
transferredBytes: number;
totalBytes: number;
}
例えば、Reactでプログレスバーを表示するときはこんな感じ。
import React, {FC, useEffect, useState} from 'react';
import ky from 'ky';
import {Progress} from 'semantic-ui-react';
const Home: FC = () => {
const [percent, setPercent] = useState<number>(0);
useEffect(() => {
const fetch = async () => {
await ky(
'https://fetch-progress.anthum.com/30kbps/images/sunrise-baseline.jpg',
{
onDownloadProgress: (progress, _) => {
setPercent(progress.percent * 100);
},
},
);
};
fetch();
}, []);
return (
<>
<h1>{Math.floor(percent)}%</h1>
<div>
<Progress percent={percent} color="orange" />
</div>
</>
);
};
export default Home;
よく使うoptionはこんな感じかなと思います。
最後に
新規のプロジェクトはaxiosではなく、kyの採用をご検討ください。
参照
sampleで使用したapiやダウンロード画像は以下の物を使用しました。
Discussion