
のっぺらぼう、レスポンスボディが空だ!「むじな」に学ぶ、APIエラー処理の重要性
紀伊国坂の夜、顔なき女の悲鳴が響く。APIエラー?いや、それ以上の恐怖が襲いかかる!空のレスポンスボディ、混沌としたエラーコード…それは、街全体を蝕むAPIの悪夢の始まりだった。異なるシステム、異なるインターフェース、しかし同じ顔なき恐怖。逃げ出した商人を待ち受けるのは、蕎麦屋の更なる悪夢と、統一インターフェースへの絶望的な闘い!君は、この街のAPI地獄を生き延びることができるか?
紀伊国坂のAPIコール:予期せぬエラーレスポンス
日が暮れ、人気のない紀伊国坂を、商人は急いでいた。今宵の宿へAPIクライアントよろしくリクエストを送るべく、足早に歩を進める。
その時、耳障りなエラーログのような泣き声が聞こえた。「うぅ…うぅ…」。辺りを見回すが、人影はない。恐る恐る声のする方へ近づくと…
「お…お助けを…」
道の真ん中に、女がうずくまっていた。顔がない。のっぺらぼうだ!商人は肝を冷やし、後ずさりした。
function handle_kiinokizaka_api_response(response) {
if (response.status === 200) {
// 宿屋の予約情報処理…
showInnReservationInfo(response.data);
} else if (response.status === 404) {
// 宿屋が見つからない場合の処理…
showErrorMessage("宿屋が見つかりません");
} else {
// その他のエラー処理…
console.error("予期せぬエラー:", response);
// エラーメッセージを表示…
showErrorMessage("原因不明のエラーが発生しました");
}
}
let response = { status: 500, data: null }; // レスポンスボディは空、ステータスコードは500
handle_kiinokizaka_api_response(response);
「一体、何が…?」商人は混乱した。APIレスポンスがおかしい。まるでインターフェースが不統一なのだ。ステータスコードは500だが、レスポンスボディは空。エラーメッセージもない。一体何が起きたのか、全くわからない。
女、すなわちのっぺらぼうは、なおも泣き続けている。「うぅ…レスポンスボディが…空です…エラーコードも…わかりません…うぅ…」
商人は、この不可解なAPI、のっぺらぼうから逃げ出すしかなかった。紀伊国坂のAPIコールは、予期せぬエラーレスポンスを返してきたのだ。

蕎麦屋のインコンシステントAPI:想定外の挙動
息を切らしながら、商人は近くの蕎麦屋に飛び込んだ。暖簾をくぐり、カウンターに滑り込むように腰を下ろす。「お…お助けを…!」
「どうしたんだい、そんなに慌てて」と、蕎麦屋の主人が落ち着いた声で言った。「今宵の宿を探しているんだが…恐ろしい目に遭ってしまって…」
商人は、紀伊国坂での出来事を説明した。顔のない女、空のレスポンスボディ、理解不能なエラーコード…。「そいつは、こんな顔だったかい?」主人は聞き終えると、振り返った。
しかし、その顔ものっぺらぼうだった!商人は絶句した。違うシステム、違うAPIのはずなのに、同じインターフェースエラー。
function get_soba_price(soba_type, callback) {
// 非同期処理で蕎麦の価格を取得…
setTimeout(() => {
if (soba_type === "かけそば") {
callback(null, 600); // 価格情報
} else if (soba_type === "天ぷらそば") {
callback({code: "NO_TEMPURA"}, null); // 天ぷらが無いエラー
} else {
callback("Invalid soba type"); // 不明な蕎麦の種類エラー
}
}, 500);
}
get_soba_price("ざるそば", (err, price) => {
if (err) {
if (typeof err === 'string') {
console.error("文字列エラー:", err);
} else if (typeof err === 'object' && err !== null ) {
console.error("オブジェクトエラー:", err);
} else {
console.error("予期せぬエラー:", err);
}
} else {
console.log("ざるそばの価格:", price);
}
});
「うぅ…蕎麦の値段が…取得できません…エラー形式もバラバラです…うぅ…」と、主人はのっぺらぼうのまま言った。蕎麦屋のAPIも、宿屋のAPIと同じように、インターフェースが不統一で、エラーハンドリングが不十分だった。
商人は、異なるシステムのAPIが、同じような機能を提供しながら、全く異なるインターフェースを持つことに恐怖を感じた。紀伊国坂の悪夢が、形を変えて繰り返されている。一体、この街のAPIはどうなっているんだ?

統一インターフェースへの転換:抽象化の重要性
蕎麦屋ののっぺらぼうの店主がカウンターに突っ伏し、すすり泣いている。商人は、先刻の紀伊国坂での出来事を思い出し、身震いした。「どちらも…顔がない。そして、どちらも…エラーがわかりにくい…」
「もし…もし、宿屋と蕎麦屋が同じAPIを使っていたら…」商人は独り言ちた。「いや、同じAPIでなくてもいい。エラーレスポンスの形式が統一されていれば…!」
「どういうことです…?」カウンターの中のっぺらぼうが顔を上げた。いや、顔はないのだが、そののっぺらぼうがこちらを見ているのがわかった。
「たとえば、こういうことだ」商人は懐から小さな手帳を取り出し、書き始めた。
class APIError {
constructor(code, message) {
this.code = code;
this.message = message;
}
}
function getInnInfo(innName) {
// ... (宿屋の情報を取得する処理) ...
if (/* 宿屋が見つからない */) {
throw new APIError("INN_NOT_FOUND", "宿屋が見つかりません");
}
// ...
}
function getSobaPrice(sobaType) {
// ... (蕎麦の価格を取得する処理) ...
if (/* 天ぷらが無い */) {
throw new APIError("NO_TEMPURA", "天ぷらがありません");
}
// ...
}
try {
const innInfo = getInnInfo("むじな亭");
console.log(innInfo);
const sobaPrice = getSobaPrice("天ぷらそば");
console.log(sobaPrice);
} catch (error) {
if (error instanceof APIError) {
console.error(`エラーコード: ${error.code}, メッセージ: ${error.message}`);
// エラーコードに基づいて適切な処理を行う
if (error.code === "INN_NOT_FOUND"){
// 別の宿を探す処理
}
} else {
console.error("予期せぬエラー:", error);
}
}
「エラーを共通のクラスで表現し、エラーコードとメッセージを明確に定義する。こうすれば、どんなAPIでも同じようにエラー処理ができる!」
蕎麦屋ののっぺらぼうは、相変わらず顔がないまま、しかし、どこか納得したように頷いた。「なるほど…エラー処理が楽になりますね…うぅ…でも、APIごとに具体的な処理は変わるのでは…?」
「もちろん、具体的な処理は変わる。しかし、エラーの『型』を統一することで、少なくともエラーの種類を判別し、共通のロジックで処理できる部分が必ず出てくるはずだ。これが抽象化の力だ!」
商人は、異なるAPIでも共通のインターフェースを持つことの重要性を改めて実感した。この経験は、今後のAPI設計にとって貴重な教訓となるだろう。そして、この街の奇妙なAPIの謎を解く鍵となるかもしれない、と商人は密かに思った。

APIドキュメントの恩恵:二度と遭遇しないために
蕎麦屋ののっぺらぼう店主が、一枚の紙切れを差し出した。「APIドキュメント…?」商人は訝しげに受け取った。
「うぅ…これを読めば…二度と…私のような…のっぺらぼうAPIには…遭遇しないでしょう…うぅ…」店主はすすり泣いていた。その紙には、整然とした記述でAPIの仕様が記されていた。
/**
* @api {get} /soba/price/{sobaType} Get soba price
* @apiName GetSobaPrice
* @apiGroup Soba
*
* @apiParam {String} sobaType 蕎麦の種類.
*
* @apiSuccess {Number} price 蕎麦の価格.
*
* @apiError NO_TEMPURA 天ぷらがありません.
* @apiError INVALID_SOBA_TYPE 不明な蕎麦の種類です.
*/
function getSobaPriceDocumented(sobaType) {
// ...(蕎麦の価格を取得する処理)...
return { price: 600 };
}
「なるほど…!」商人は目を輝かせた。「エラーコードだけでなく、パラメータやレスポンスのフォーマットまで詳細に書いてある!これさえあれば、どんなAPIでも安心してコールできる!」
「うぅ…APIドキュメントは…開発者にとっての…顔のようなもの…うぅ…」店主は、さらに一枚の紙を差し出した。「RESTful API設計ガイドライン…?」
「これは…?」商人は尋ねた。
「うぅ…統一されたインターフェースを持つ…APIを設計するための…ベストプラクティス集です…うぅ…」
商人は、ドキュメントとガイドラインを丹念に読み込んだ。ステータスコードの適切な使い方、エラーレスポンスの標準化、バージョン管理の重要性…。すべてが、これまでの悪夢を払拭する光明のように思えた。
「もう大丈夫だ」商人は力強く言った。「これでもう、のっぺらぼうAPIに悩まされることはない!」
店主は、静かに頷いた。そして、にっこり…いや、顔がないので表情はわからないが、どこか満足げな雰囲気を醸し出しながら、商人に一杯の蕎麦を差し出した。「ざるそば…サービスです…」
商人は、蕎麦をすすりながら、これからのAPIコールに満ちた旅路に、静かな自信を漲らせていた。しかし、ふと、思い出した。「むじな亭」のAPIドキュメントは読んでいなかった…。一抹の不安がよぎったが、まぁ、なんとかなるだろう。きっと。
