denoでkyを使ってみる
Fetchを使いやすくしたnpmライブラリ、Denoでも使える
極楽要求(しなさい)
Fetchとの違いは
- HTTPメソッドを
{method:"POST"}
のようにオプションで指定するのではなくky.post()
のようにメソッドとして指定できる - bodyに合わせた
Content-Type
ヘッダーを自動的につけてくれる -
response.json()
をメソッドチェーンで書ける - その他便利なメソッドが定義されていたりいろんなオプションを使えたりする
LINE通知したときのmain.ts
を書き換えてみる
+ import { ky } from "./deps.ts";
import { LINE_ACCESS_TOKEN } from "./env.ts";
import { Logger } from "./logger.ts";
const url = "https://notify-api.line.me/api/notify";
const body = new URLSearchParams({
message: "hello from ky!",
});
- const res = await fetch(url, {
- method: "POST",
+ const json = await ky.post(url, {
headers: {
Authorization: `Bearer ${LINE_ACCESS_TOKEN}`,
- "Content-Type": "application/x-www-form-urlencoded",
},
body,
- });
+ }).json();
- const json = await res.json()
Logger.info(json);
修正前と同様に疎通できた
感想
- 今回は
URLSearchParams
で送る必要があったのでそこまで大きく行数を減らせたわけではない - でもcontent-typeを書かなくて良くなるのは楽、視覚的ストレスが減少する
- 今後は使っていこう
- なんで
URLSearchParams
にしているの?- LINEの仕様上、
Content-Type
をmultipart/form-data
またはapplication/x-www-form-urlencoded
で送信する必要がある - READMEのtipsに記載のある通り、
-
body
の型がFormData
ならmultipart/form-data
が、型がapplication/x-www-form-urlencoded
ならURLSearchParams
が、Content-Type
に自動的に設定される
- LINEの仕様上、
-
ky
って何?
It's just a random short npm package name I managed to get. It does, however, have a meaning in Japanese:
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.
「npmパッケージ用に適当な短い名前をつけたんだけど、日本語では『空気読めない』の略なんだ」
ちょっとこれだけだと面白くないので他のプログラムをkyで書き換えてみる
ちょうどURLSearchParamsを使ってリクエストを送っている例が見つかったので使わせていただく
…と思ったけどこのZennのAPI自体が閉鎖されているみたい?残念
tweet-with-iftttならもっと簡単にできる
import { ky } from "./deps.ts";
const url = "https://maker.ifttt.com/trigger/send_tweet/with/key/";
const sendTweet = async (params: { message: string; key: string }) => {
const { message, key } = params;
try {
return await ky.post(`${url}${key}`, { json: { value1: message } }).text();
} catch (error) {
return await error.response.text();
}
};
export { sendTweet };
import { sendTweet } from "./tweet_with_ifttt.ts";
import { IFTTT_WEBHOOK_KEY } from "./env.ts";
import { Logger } from "./logger.ts";
const json = await sendTweet({
message: "Denoからツイート",
key: IFTTT_WEBHOOK_KEY,
});
Logger.info(json);
IFTTTのレスポンスは返り値をtext()
で展開する必要があることに注意
また、エラーハンドリングはこちらのissueで
IFTTTのWebhook URLはエンドポイントの末尾にキーが付加される形なので${url}${key}
のように書いている
prefixUrl
を使うと文字列連結をしなくて良くなる
動きは同じだがよりクリーンな見た目になる印象
import { ky } from "./deps.ts";
- const url = "https://maker.ifttt.com/trigger/send_tweet/with/key/";
+ const prefixUrl = "https://maker.ifttt.com/trigger/send_tweet/with/key/";
const sendTweet = async (params: { message: string; key: string }) => {
const { message, key } = params;
try {
- return await ky.post(`${url}${key}`, { json: { value1: message } }).text();
+ return await ky.post(key, { prefixUrl, json: { value1: message } }).text();
} catch (error) {
return await error.response.text();
}
};
export { sendTweet };
これはなかなか極楽要求みを感じる
published