【JavaScript】fetch APIの基本:外部データを取得する方法

javascript-icon JavaScript

こんにちは、かつコーチです。

前回は「コピーボタン(Clipboard API)を実装する」で、ブラウザの便利な機能をJavaScriptから操作する方法を紹介しました。

今回からは、Webサイト作りで避けて通れない「外部データの取得」について解説していきます。

その第一歩として、fetch という関数の基本の使い方を押さえていきましょう。

fetch APIとは?

そもそも「外部データを取得する」とはどういうことか

WebサイトやWebアプリは、表示するデータを毎回自分のページの中だけに書いているわけではありません。

天気予報アプリなら気象情報のサーバーから、ニュースサイトなら記事データを管理しているサーバーから、必要な情報を取ってきて画面に表示しています。

このように「別の場所(サーバー)にあるデータを、こちらから取りに行く」処理のことを、API通信と呼びます。

API(Application Programming Interface)とは、あるプログラムが別のプログラムとやり取りするための「窓口」のようなものだと考えてください。

fetch関数の役割

fetch は、このAPI通信をJavaScriptから簡単に行うためのブラウザ標準の関数です。

以前はAPI通信のために XMLHttpRequest という少し書き方が複雑な仕組みを使っていましたが、fetch の登場でぐっとシンプルに書けるようになりました。

特別なライブラリを読み込まなくても、ブラウザで動くJavaScriptなら基本的にそのまま使えます。

fetchが返す「Promise」という考え方

fetch を理解するうえで欠かせないのが、Promise(プロミス)という概念です。

Promiseとは、「今すぐには終わらないけど、いつか結果が返ってくる処理」を表すオブジェクトのことです。

サーバーとの通信は、返事が返ってくるまでに一瞬〜数秒かかります。

その「待っている間」を表現する仕組みがPromiseだとイメージしてください。

fetchの基本の書き方

最小限のコード例

まずは、実際に外部のAPIからデータを取得する一番シンプルな形を見てみましょう。

fetch("https://jsonplaceholder.typicode.com/users/1")
  .then((response) => response.json())
  .then((data) => {
    console.log(data);
  });

このコードは次の3ステップで動いています。

  1. fetch(url) で指定したURLにリクエストを送る
  2. 返ってきた response(レスポンス)を .json() でJavaScriptが扱えるデータ形式に変換する
  3. 変換されたデータ(data)をコンソールに出力する

.then() は「この処理が終わったら、次にこれをやってね」という意味のメソッドです。

Promiseの結果を受け取って、次の処理につなげる役割を持っています。

async/awaitで書き換える

.then() を連鎖させる書き方に加えて、async/awaitを使うとより読みやすいコードになります。

async function getUser() {
  const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
  const data = await response.json();
  console.log(data);
}

getUser();

await は「Promiseの結果が返ってくるまで、ここで一旦待つ」という意味の書き方です。

.then() を並べるより、上から下に処理を読める分、初心者にとっては理解しやすいことが多いです。

この記事では、async/await形式を中心に解説していきます。

fetchが実行する処理の順番を確認する

fetchは「非同期処理」なので、コードの見た目の順番と、実際に処理が終わる順番が一致しないことがあります。

console.log("1: リクエスト開始前");

async function getUser() {
  console.log("2: fetch実行");
  const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
  const data = await response.json();
  console.log("4: データ取得完了", data.name);
}

getUser();

console.log("3: getUser呼び出し直後(awaitの結果を待たずに実行される)");

このコードを実行すると、コンソールには「1」「2」「3」「4」の順番で出力されます。

await が付いている行の処理が終わるのを待っている間も、それ以外のコードはどんどん先に進んでしまう、というのがポイントです。

つまずきやすいポイント

awaitを付け忘れる

私が最初にfetchを触ったとき、一番混乱したのが「awaitの付け忘れ」でした。

❌ Before:awaitを付けずにデータを使おうとする

async function getUser() {
  const response = fetch("https://jsonplaceholder.typicode.com/users/1"); // awaitがない
  const data = response.json(); // ここでエラーになる
  console.log(data);
}

getUser();
// TypeError: response.json is not a function

await を付けないと、response には「まだ結果が返ってきていないPromiseそのもの」が入ってしまいます。

Promiseオブジェクトには .json() というメソッドがないため、response.json is not a function というエラーになります。

私はこのエラーメッセージを見たとき、最初は「json()が壊れてる?」と勘違いしてしまい、原因を探すのに時間がかかりました。

実際には「awaitを書き忘れて、まだ届いていない結果を使おうとしていた」というのが真相でした。

✅ After:await を正しく付ける

async function getUser() {
  const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
  const data = await response.json(); // 結果を待ってから使う
  console.log(data);
}

getUser();

fetchも .json() も、どちらもPromiseを返す処理なので、両方に await を付ける必要がある、と覚えておきましょう。

async関数の外でawaitを使おうとする

もう一つよくあるつまずきが、await を使う場所です。

❌ Before:async関数の外でawaitを書いてしまう

const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
// SyntaxError: await is only valid in async functions

await は、async が付いた関数の中でしか使えません。

いきなりファイルの一番上(トップレベル)で書くとエラーになることがあります。

✅ After:async関数の中に処理をまとめる

async function main() {
  const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
  const data = await response.json();
  console.log(data);
}

main();

「awaitを使いたいときは、まずasync関数を作る」という順番をセットで覚えておくと迷いにくくなります。

fetchで取得したデータを画面に表示する

HTML要素にデータを反映させる

fetchの本当の使いどころは、取得したデータを実際に画面へ表示するところにあります。

<div id="user-name"></div>
async function showUserName() {
  const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
  const data = await response.json();

  const target = document.getElementById("user-name");
  target.textContent = data.name;
}

showUserName();

取得したデータの data.name を、textContent を使って画面の要素に反映しています。

外部から取ってきたデータを画面に流し込む、という一連の流れがこれで体感できたかと思います。

通信中であることを意識する

ここで注意したいのは、fetchが完了するまでの間、画面には何も表示されていない時間がある、という点です。

一瞬で終わることも多いですが、通信環境によっては数秒かかることもあります。

「読み込み中です」といった表示を出す方法については、後の記事(ローディング表示の実装)で詳しく扱う予定です。

まずは今回、「データを取得して表示する」という基本の流れをしっかり体に馴染ませておきましょう。

まとめ

この記事のポイント

  • fetch はブラウザ標準のAPI通信の仕組みで、外部のデータを取得できる
  • fetchはPromiseを返す非同期処理で、async/awaitを使うと読みやすく書ける
  • await の付け忘れや、async関数の外でのawait使用はよくあるエラーの原因になる
  • 取得したデータは .json() で変換してから、textContent などで画面に反映する

次に読むべき記事

fetchの基本が分かったところで、次は実際に外部APIからデータを取得して、リスト表示するところまで踏み込んでいきます。

→ 次の記事:外部APIからデータを取得して表示する

タイトルとURLをコピーしました