JavaScriptのAPI呼び出しで絶対につまずく3つのポイントを解説します
API呼び出しで「なんか動かない...」と悩んだことはありませんか?
こんにちは、とまだです。
実はみんな同じところでつまずくんです。私も最初はCORSエラーで半日悩んだりしていました。
でも大丈夫です。
今回は現役のエンジニア、そして元プログラミングスクール講師としての経験から、JavaScriptのAPI呼び出しについて解説します。
そもそもAPI呼び出しって何をしているの?
簡単に言うと、API呼び出しとは「他のサーバーにお願いごとをして、結果をもらう」ことです。
日常生活で言うと、レストランで注文するようなものです。
- メニューを見る(APIドキュメントを確認)
- 注文する(リクエストを送る)
- 料理が来る(レスポンスを受け取る)
このやりとりをプログラムで行うのがAPI呼び出しです。
実際のコードで見てみましょう。
// 天気情報を取得する例
fetch('https://api.example.com/weather')
.then(response => response.json())
.then(data => console.log(data));
これだけで外部サービスから情報を取得できるんです。
なぜ非同期処理が必要なのか(同期だと困る理由)
ここで疑問に思うかもしれません。
「なんで非同期とか面倒なことするの?」
実は、もし同期処理でAPIを呼び出すと、サーバーからの返事を待っている間、画面が完全に固まってしまうんです。
例えるなら、レジで会計中に店員さんが在庫確認に行って、その間ずっと動けない状態みたいなものですね。
だから非同期処理を使って、「注文だけして、料理ができたら教えて」という仕組みにしているんです。
初心者が必ずつまずく3つのポイント
1. CORSエラー
「Access to fetch at 'xxx' from origin 'yyy' has been blocked by CORS policy」
このエラー見たことありませんか?
CORSは「別のサイトからの呼び出しを制限する」セキュリティの仕組みです。
解決方法:
- サーバー側で許可設定をする
- 開発時はプロキシを使う
- CORSが不要なAPIを選ぶ
2. async/awaitの書き方
Promiseのthen地獄から抜け出すために、async/awaitがあります。
// ❌ これだと読みにくい
fetch(url)
.then(res => res.json())
.then(data => {
fetch(url2)
.then(res2 => res2.json())
.then(data2 => {
// どんどんネストが深くなる...
});
});
// ✅ こっちの方がスッキリ
async function getData() {
const res = await fetch(url);
const data = await res.json();
const res2 = await fetch(url2);
const data2 = await res2.json();
// 見やすい!
}
3. エラーハンドリング
APIは必ず成功するとは限りません。
- サーバーが落ちているかも
- ネットワークが切れているかも
- 権限がないかも
だから必ずエラー処理を書きましょう。
async function fetchData() {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error('サーバーエラーです');
}
const data = await response.json();
return data;
} catch (error) {
console.error('エラーが発生しました:', error);
// ユーザーに分かりやすいメッセージを表示
}
}
実践的なfetchの使い方
では、実際によく使うパターンを見ていきましょう。
GETリクエスト(データを取得)
async function getUsers() {
const response = await fetch('https://api.example.com/users');
const users = await response.json();
return users;
}
POSTリクエスト(データを送信)
async function createUser(userData) {
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(userData)
});
const newUser = await response.json();
return newUser;
}
// 使い方
createUser({
name: '山田太郎',
email: 'yamada@example.com'
});
認証付きリクエスト
async function getPrivateData(token) {
const response = await fetch('https://api.example.com/private', {
headers: {
'Authorization': `Bearer ${token}`
}
});
return response.json();
}
Axiosを使うメリット
fetchも便利ですが、実務ではAxiosを使うことも多いです。
なぜか?
- エラーハンドリングが楽
- リクエスト/レスポンスの変換が簡単
- 古いブラウザでも動く
import axios from 'axios';
// fetchよりシンプル
const { data } = await axios.get('https://api.example.com/users');
// POSTも簡単
const newUser = await axios.post('https://api.example.com/users', {
name: '田中花子',
email: 'tanaka@example.com'
});
実務でよく使うパターン
API呼び出しを関数化する
同じAPIを何度も呼ぶなら、専用の関数を作りましょう。
// api.js
const API_BASE = 'https://api.example.com';
export async function getUser(userId) {
const response = await fetch(`${API_BASE}/users/${userId}`);
if (!response.ok) {
throw new Error('ユーザーが見つかりません');
}
return response.json();
}
export async function updateUser(userId, data) {
const response = await fetch(`${API_BASE}/users/${userId}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
return response.json();
}
ローディング状態の管理
async function loadData() {
setLoading(true); // ローディング開始
try {
const data = await fetchData();
setData(data);
} catch (error) {
setError(error.message);
} finally {
setLoading(false); // ローディング終了
}
}
並列でAPIを呼ぶ
複数のAPIを同時に呼びたいときは、Promise.allを使います。
async function loadDashboard() {
const [users, posts, comments] = await Promise.all([
fetch('/api/users').then(r => r.json()),
fetch('/api/posts').then(r => r.json()),
fetch('/api/comments').then(r => r.json())
]);
// 全部同時に取得できる!
}
よくあるトラブルと解決法
URLの間違い
一番多いのがこれです。スペルミスやスラッシュの付け忘れなど。
// ❌ よくあるミス
fetch('https://api.example.com/user') // usersじゃないの?
fetch('https://api.example.com//users') // スラッシュ多い
fetch('http://api.example.com/users') // httpsじゃないの?
JSONのパースエラー
レスポンスがJSONじゃないときにjson()を呼ぶとエラーになります。
const response = await fetch(url);
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
const data = await response.json();
} else {
const text = await response.text();
}
ネットワークエラー
オフラインやタイムアウトの対策も必要です。
async function fetchWithTimeout(url, timeout = 5000) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, {
signal: controller.signal
});
clearTimeout(timeoutId);
return response;
} catch (error) {
if (error.name === 'AbortError') {
throw new Error('タイムアウトしました');
}
throw error;
}
}
まとめ
JavaScriptのAPI呼び出しで重要なのは、この3つです。
- 非同期処理の理解(async/await)
- エラーハンドリング
- CORSの仕組み
まずは簡単なGETリクエストから始めてみてください。
慣れてきたらPOSTやPUT、認証付きのリクエストにも挑戦してみましょう。
API呼び出しができるようになると、作れるアプリの幅が一気に広がりますよ。
著者について

とまだ
フルスタックエンジニア
Learning Next の創設者。Ruby on Rails と React を中心に、プログラミング教育に情熱を注いでいます。初心者が楽しく学べる環境作りを目指しています。
著者の詳細を見る →