基礎から学ぶJavaScript入門 90日コース | 非同期処理とAPI - Day 70:API総合制作

JavaScript 90日で身につけるJavaScript
スポンサーリンク
スポンサーリンク

Day 70:API総合制作(おまけ)

Day 70のおまけでは、前回作成した書籍検索アプリだけで終わらず、さらに別の題材でもAPIアプリを作ってみる練習を行います。今回のテーマは、天気アプリ、ニュース検索アプリ、レシピ検索アプリ、画像検索アプリ の4つです。ここまでの第5フェーズでは、非同期処理、fetch()、async / await、ローディング表示、エラー処理、検索、フィルター、DOM更新、総合制作までを学んできました。つまり、もう「APIからデータを取得して画面に表示する」という基本の土台はできています。そこで、このおまけでは、題材が変わっても同じ考え方でアプリを組み立てられるようになることを目指します。

初心者の方にとって大切なのは、「アプリの種類が変わっても、作り方の骨組みはかなり共通している」と理解することです。天気アプリでも、ニュース検索アプリでも、レシピ検索アプリでも、画像検索アプリでも、基本の流れはよく似ています。入力欄から条件を受け取り、APIへリクエストを送り、返ってきたデータを確認し、必要な項目を取り出して画面に表示し、0件やエラーにも対応する、という流れです。違うのは、どんなデータが返るか、どんな表示形式が向いているか、そしてAPIによってはキーや利用ルールがあることです。

今回のおまけでは、4つすべてを本格的に1から10まで同じ深さで作るのではなく、初心者向けに「どう考えて作ればよいか」を整理しながら、それぞれのミニ制作例を紹介していきます。特に重要なのは、単にコードを写すことではなく、「何を入力にするのか」「何を表示するのか」「どこに注意するのか」をアプリごとに理解することです。前回の書籍検索アプリで身につけた考え方を、別の題材へ広げる練習として読んでいくと、とても実践的な力がつきます。

まず最初に結論をつかむ

最初に今回の内容を一言でまとめると、Day 70のおまけでは「同じAPIアプリの基本構造を、別の題材へ応用する練習」を行います。

4つのアプリに共通する基本の流れは次の通りです。

  • 入力欄や選択欄で条件を受け取る
  • APIのURLを組み立てる
  • `fetch()` でデータを取得する
  • レスポンスの中から必要な情報を取り出す
  • 画面に見やすい形で表示する
  • ローディング、0件、エラーにも対応する

初心者の方は、まず「題材は違っても骨組みは同じ」だと理解すると、気持ちがかなり楽になります。

4つのアプリをどう学ぶべきか

いきなり4つすべてを完璧に作ろうとすると大変です。そのため、学び方の順番が大切です。おすすめは次のような考え方です。

  • まず1つ、比較的作りやすい題材を選んで完成させる
  • 次に、表示内容だけ変える感覚で別題材へ応用する
  • APIごとのデータ構造の違いに慣れる
  • 最後に、自分なりのUI改善や追加機能を試す

初心者の方は、「4つ全部を一気に覚える」のではなく、「1つの型を身につけて横展開する」と考えると取り組みやすいです。

今回の4題材の特徴を先に整理する

4つの題材には、それぞれ向いている表示形式や注意点があります。

  • 天気アプリ:都市名などを入力し、気温や天気説明を表示します。
  • ニュース検索アプリ:キーワードで記事を探し、タイトルや概要を一覧表示します。
  • レシピ検索アプリ:料理名や材料名で探し、料理名や画像、手順リンクなどを表示します。
  • 画像検索アプリ:キーワードで画像を探し、画像一覧を表示します。

初心者の方は、「どんな情報をユーザーに見せたいか」で表示方法が変わることを意識すると理解しやすいです。

まず共通テンプレートの考え方を持つ

4つのアプリすべてに共通する基本形があります。たとえば、次のような考え方です。

  • HTMLに入力欄・ボタン・メッセージ欄・結果表示欄を置く
  • JavaScriptでボタン押下を受け取る
  • 入力値をチェックする
  • APIへアクセスする
  • 成功したら表示、失敗したらエラー表示する

この「共通テンプレート」を頭に持っておくと、題材が変わっても組み立てやすくなります。初心者の方は、まず型を覚えることが何より大切です。

天気アプリの考え方

最初に天気アプリです。天気アプリでは、都市名を入力してその場所の天気情報を取得するのが基本です。たとえば、「Tokyo」と入力すると、現在の気温や天気の説明を表示するような形です。

天気アプリで考えるべき流れは次の通りです。

  • 都市名を入力する
  • 都市名を使ってAPIのURLを作る
  • 気温、天気、湿度など必要な情報を取り出す
  • 見やすく表示する

ただし、天気APIは多くの場合APIキーが必要です。そのため、学習時は「仮のキーを入れる場所」を理解しつつ、実際には自分で登録して取得する必要があることを知っておくとよいです。

天気アプリのミニテンプレート

ここでは構造理解のための例を示します。

<h3>天気アプリ</h3>
<input type="text" id="cityInput" placeholder="都市名を入力">
<button id="weatherButton">天気を調べる</button>
<p id="weatherMessage">都市名を入力してください。</p>
<div id="weatherResult"></div>
const cityInput = document.getElementById("cityInput");
const weatherButton = document.getElementById("weatherButton");
const weatherMessage = document.getElementById("weatherMessage");
const weatherResult = document.getElementById("weatherResult");

async function searchWeather() {
  const city = cityInput.value.trim();

  if (city === "") {
    weatherMessage.textContent = "都市名を入力してください。";
    weatherResult.innerHTML = "";
    return;
  }

  try {
    weatherMessage.textContent = "天気を取得中です...";
    weatherResult.innerHTML = "";

    // ここに実際の天気APIのURLを入れる
    const url = `https://api.example.com/weather?q=${encodeURIComponent(city)}&appid=YOUR_API_KEY`;

    const response = await fetch(url);

    if (!response.ok) {
      throw new Error("天気データの取得に失敗しました。");
    }

    const data = await response.json();

    // 仮の表示例
    weatherResult.innerHTML = `
      <p>都市名: ${data.name}</p>
      <p>気温: ${data.main.temp}</p>
      <p>天気: ${data.weather[0].description}</p>
    `;

    weatherMessage.textContent = "天気情報を取得しました。";
  } catch (error) {
    weatherMessage.textContent = "天気情報の取得に失敗しました。";
    console.log(error);
  }
}

weatherButton.addEventListener("click", function () {
  searchWeather();
});
JavaScript

初心者の方は、ここで「天気アプリも検索アプリの一種」だと気づけると理解しやすいです。違うのは、結果が一覧ではなく1件の詳細表示になりやすいことです。

天気アプリで特に注意したいこと

天気アプリでは、気温の単位や都市名の表記、存在しない都市を入力した場合のエラーなどに注意が必要です。また、APIによってはレスポンス構造が少し深いので、data.main.temp や data.weather[0].description のような取り出しに慣れる必要があります。

初心者の方は、天気アプリでは「1件の詳細表示」を丁寧に組み立てる練習になると考えるとよいです。

ニュース検索アプリの考え方

次にニュース検索アプリです。ニュース検索アプリでは、キーワードを入力して関連するニュース記事を一覧表示する形が基本です。書籍検索アプリとかなり近い考え方で作れます。

ニュース検索アプリの基本の流れは次の通りです。

  • 検索語を入力する
  • APIへリクエストする
  • 記事タイトル、概要、公開日などを取り出す
  • 一覧表示する

初心者の方は、ニュース検索アプリを「書籍検索アプリの応用版」と考えるとかなり取り組みやすいです。

ニュース検索アプリのミニテンプレート

<h3>ニュース検索アプリ</h3>
<input type="text" id="newsKeywordInput" placeholder="ニュースのキーワードを入力">
<button id="newsSearchButton">検索</button>
<p id="newsMessage">キーワードを入力してください。</p>
<div id="newsResult"></div>
const newsKeywordInput = document.getElementById("newsKeywordInput");
const newsSearchButton = document.getElementById("newsSearchButton");
const newsMessage = document.getElementById("newsMessage");
const newsResult = document.getElementById("newsResult");

async function searchNews() {
  const keyword = newsKeywordInput.value.trim();

  if (keyword === "") {
    newsMessage.textContent = "キーワードを入力してください。";
    newsResult.innerHTML = "";
    return;
  }

  try {
    newsMessage.textContent = "ニュースを検索中です...";
    newsResult.innerHTML = "";

    // ここに実際のニュースAPIのURLを入れる
    const url = `https://api.example.com/news?q=${encodeURIComponent(keyword)}&apiKey=YOUR_API_KEY`;

    const response = await fetch(url);

    if (!response.ok) {
      throw new Error("ニュースデータの取得に失敗しました。");
    }

    const data = await response.json();

    if (!data.articles || data.articles.length === 0) {
      newsMessage.textContent = "該当するニュースが見つかりませんでした。";
      return;
    }

    data.articles.forEach(function (article) {
      const card = document.createElement("div");

      const title = document.createElement("h4");
      title.textContent = article.title || "タイトル不明";

      const description = document.createElement("p");
      description.textContent = article.description || "概要なし";

      card.appendChild(title);
      card.appendChild(description);
      newsResult.appendChild(card);
    });

    newsMessage.textContent = `${data.articles.length}件のニュースが見つかりました。`;
  } catch (error) {
    newsMessage.textContent = "ニュース検索に失敗しました。";
    console.log(error);
  }
}

newsSearchButton.addEventListener("click", function () {
  searchNews();
});
JavaScript

初心者の方は、ニュースアプリでは「一覧表示の作り方」と「概要文の扱い」が重要だと意識するとよいです。

ニュース検索アプリで特に注意したいこと

ニュースデータは、記事によって説明文がないことや、画像がないことがあります。また、配信日時や記事URLの扱いも考えられるとより実践的です。ただし初心者のうちは、まずタイトルと概要の表示が安定してできれば十分です。

レシピ検索アプリの考え方

次にレシピ検索アプリです。レシピ検索アプリでは、料理名や材料名で検索し、ヒットした料理一覧を表示します。料理名、画像、カテゴリ、レシピへのリンクなどを表示する形がよくあります。

初心者の方は、レシピ検索アプリを「書籍検索アプリに画像が加わったもの」と考えると理解しやすいです。

レシピ検索アプリのミニテンプレート

<h3>レシピ検索アプリ</h3>
<input type="text" id="recipeKeywordInput" placeholder="料理名や材料名を入力">
<button id="recipeSearchButton">検索</button>
<p id="recipeMessage">キーワードを入力してください。</p>
<div id="recipeResult"></div>
const recipeKeywordInput = document.getElementById("recipeKeywordInput");
const recipeSearchButton = document.getElementById("recipeSearchButton");
const recipeMessage = document.getElementById("recipeMessage");
const recipeResult = document.getElementById("recipeResult");

async function searchRecipes() {
  const keyword = recipeKeywordInput.value.trim();

  if (keyword === "") {
    recipeMessage.textContent = "キーワードを入力してください。";
    recipeResult.innerHTML = "";
    return;
  }

  try {
    recipeMessage.textContent = "レシピを検索中です...";
    recipeResult.innerHTML = "";

    // ここに実際のレシピAPIのURLを入れる
    const url = `https://api.example.com/recipes?search=${encodeURIComponent(keyword)}&apiKey=YOUR_API_KEY`;

    const response = await fetch(url);

    if (!response.ok) {
      throw new Error("レシピデータの取得に失敗しました。");
    }

    const data = await response.json();

    if (!data.meals || data.meals.length === 0) {
      recipeMessage.textContent = "該当するレシピが見つかりませんでした。";
      return;
    }

    data.meals.forEach(function (meal) {
      const card = document.createElement("div");

      const title = document.createElement("h4");
      title.textContent = meal.strMeal || "料理名不明";

      const category = document.createElement("p");
      category.textContent = "カテゴリ: " + (meal.strCategory || "不明");

      card.appendChild(title);
      card.appendChild(category);
      recipeResult.appendChild(card);
    });

    recipeMessage.textContent = `${data.meals.length}件のレシピが見つかりました。`;
  } catch (error) {
    recipeMessage.textContent = "レシピ検索に失敗しました。";
    console.log(error);
  }
}

recipeSearchButton.addEventListener("click", function () {
  searchRecipes();
});
JavaScript

初心者の方は、レシピアプリでは「タイトルだけでなくカテゴリや画像も相性がよい表示情報」だと考えるとイメージしやすいです。

レシピ検索アプリで特に注意したいこと

レシピAPIは、サービスによって返ってくる項目名がかなり違うことがあります。そのため、console.log() でレスポンス全体を必ず確認することが大切です。初心者の方は、APIごとにプロパティ名が違うことに慣れる練習になります。

画像検索アプリの考え方

最後に画像検索アプリです。画像検索アプリでは、キーワードで画像を探し、サムネイル一覧を表示します。これは見た目の変化が大きいため、初心者の方にとって達成感が高い題材です。

基本の流れは次の通りです。

  • キーワードを入力する
  • APIで画像一覧を取得する
  • 画像URLを取り出す
  • `img` 要素を作って並べる

初心者の方は、画像検索アプリを「テキスト中心だった表示から、画像中心の表示へ進む練習」と考えるとわかりやすいです。

画像検索アプリのミニテンプレート

<h3>画像検索アプリ</h3>
<input type="text" id="imageKeywordInput" placeholder="画像のキーワードを入力">
<button id="imageSearchButton">検索</button>
<p id="imageMessage">キーワードを入力してください。</p>
<div id="imageResult"></div>
const imageKeywordInput = document.getElementById("imageKeywordInput");
const imageSearchButton = document.getElementById("imageSearchButton");
const imageMessage = document.getElementById("imageMessage");
const imageResult = document.getElementById("imageResult");

async function searchImages() {
  const keyword = imageKeywordInput.value.trim();

  if (keyword === "") {
    imageMessage.textContent = "キーワードを入力してください。";
    imageResult.innerHTML = "";
    return;
  }

  try {
    imageMessage.textContent = "画像を検索中です...";
    imageResult.innerHTML = "";

    // ここに実際の画像APIのURLを入れる
    const url = `https://api.example.com/images?q=${encodeURIComponent(keyword)}&apiKey=YOUR_API_KEY`;

    const response = await fetch(url);

    if (!response.ok) {
      throw new Error("画像データの取得に失敗しました。");
    }

    const data = await response.json();

    if (!data.results || data.results.length === 0) {
      imageMessage.textContent = "該当する画像が見つかりませんでした。";
      return;
    }

    data.results.forEach(function (image) {
      const img = document.createElement("img");

      // APIによって画像URLの場所は変わる
      img.src = image.urls.small;
      img.alt = keyword;
      img.width = 200;
      img.style.marginRight = "8px";
      img.style.marginBottom = "8px";

      imageResult.appendChild(img);
    });

    imageMessage.textContent = `${data.results.length}件の画像が見つかりました。`;
  } catch (error) {
    imageMessage.textContent = "画像検索に失敗しました。";
    console.log(error);
  }
}

imageSearchButton.addEventListener("click", function () {
  searchImages();
});
JavaScript

初心者の方は、画像アプリでは「img 要素の src にどのURLを入れるか」がポイントだと理解するとよいです。

画像検索アプリで特に注意したいこと

画像APIは、サイズ違いのURLを複数返すことがあります。そのため、どのサイズを使うかを決める必要があります。また、画像が多すぎると画面が重くなりやすいので、最初は件数を絞るとよいです。初心者の方は、画像検索では表示の見た目だけでなく、読み込み量にも少し意識を向けられると実践的です。

4つのアプリに共通する重要ポイント

ここまで4つの題材を見てきましたが、共通してとても大切なポイントがあります。

  • 入力値は `trim()` で整える
  • URLに埋め込む値は `encodeURIComponent()` を使う
  • 検索前に空欄チェックをする
  • APIレスポンスは `console.log()` で必ず確認する
  • 0件時とエラー時を分けて考える
  • 表示前に前回の結果を空にする
  • 欠けているデータへの対策を入れる

初心者の方は、「アプリごとに違うところ」ばかりに注目するより、「いつも同じように気をつけるべきところ」を意識すると、かなり力がつきます。

APIキーが必要な場合の注意

ここは非常に大切です。天気、ニュース、レシピ、画像系のAPIでは、APIキーが必要になることが多いです。初心者の方は、学習中にコードへ直接書いてしまいがちですが、本来はAPIキーは大切な情報です。そのため、公開場所へそのまま載せない、学習用でも無制限に共有しない、といった意識が重要です。

また、無料プランでは利用回数制限があることも多いです。そのため、何度も連打してAPIを呼びすぎないように注意することも大切です。初心者の方は、「APIは無料でも無限ではない」という感覚を持つと、より実践的です。

どのアプリから作るのがおすすめか

初心者の方には、次の順番がおすすめです。

  • ニュース検索アプリ
  • レシピ検索アプリ
  • 画像検索アプリ
  • 天気アプリ

ニュース検索とレシピ検索は、書籍検索アプリに近い構造なので応用しやすいです。画像検索は表示方法が少し変わります。天気アプリは1件の詳細表示で、APIキーやレスポンス構造の理解が少し必要です。

そのまま使える共通開発テンプレート

4つの題材すべてに応用しやすい共通の考え方として、次のテンプレートを頭に入れておくと便利です。

async function searchData() {
  const keyword = input.value.trim();

  if (keyword === "") {
    message.textContent = "キーワードを入力してください。";
    result.innerHTML = "";
    return;
  }

  try {
    message.textContent = "データを取得中です...";
    result.innerHTML = "";

    const url = `APIのURL${encodeURIComponent(keyword)}`;
    const response = await fetch(url);

    if (!response.ok) {
      throw new Error("データ取得に失敗しました。");
    }

    const data = await response.json();
    console.log(data);

    // 0件チェック
    // 表示処理
  } catch (error) {
    message.textContent = "取得に失敗しました。";
    console.log(error);
  }
}
JavaScript

初心者の方は、この基本形を1つ持っておくだけで、別のAPIアプリに挑戦しやすくなります。

情報セキュリティの観点での注意

今回のおまけでは、特にAPIキーの扱いと外部データの表示方法が重要です。APIキーは個人情報そのものではなくても、サービス利用の認証情報として大切なものです。そのため、コードを公開するときにそのまま含めない意識が必要です。また、取得したデータは外部由来であるため、文字表示には textContent を使い、むやみにHTMLとして埋め込まない基本姿勢を守ることが大切です。初心者の方は、「APIアプリは便利な反面、外から来る情報と認証情報を扱う」という意識を少しずつ持つと、堅実な開発感覚が育ちます。

初心者が特に注意したいポイント

Day 70のおまけでは、次の点を特に意識すると理解が深まりやすいです。

  • 題材が変わっても、作り方の骨組みはかなり共通しています。
  • まずは1つのアプリをしっかり完成させることが大切です。
  • APIごとにレスポンスの形が違うので、まず `console.log()` で確認します。
  • APIキーが必要な場合は扱いに注意します。
  • 表示形式は、データの性質に合わせて選ぶと見やすくなります。

特に重要なのは、「コードを丸暗記する」のではなく、「どういう流れでアプリが動いているか」を理解することです。

Day 70(おまけ)のゴールを整理する

Day 70のおまけでは、次のことができるようになっていれば十分です。

  • 書籍検索アプリ以外のAPIアプリにも挑戦できる
  • 天気、ニュース、レシピ、画像の違いを理解できる
  • 題材が変わっても共通の開発パターンを使える
  • APIレスポンス構造の違いに対応する意識を持てる
  • APIキーや外部データの扱いに注意できる

ここまでできれば、第5フェーズで学んだ「非同期処理とAPI」はかなりしっかり定着しています。

まとめ

Day 70のおまけでは、書籍検索アプリで学んだ総合制作の考え方を、天気アプリ、ニュース検索アプリ、レシピ検索アプリ、画像検索アプリへ広げる練習を行いました。題材は違っていても、入力を受け取り、APIへリクエストし、レスポンスを確認し、必要な情報を取り出して画面へ表示し、0件やエラーへ対応するという基本の流れは共通しています。そのため、1つのアプリをしっかり理解できると、ほかのAPIアプリにもかなり応用しやすくなります。

特に大切なのは、アプリごとに表示したい情報や向いている表示形式が違うこと、そしてAPIごとに返ってくるデータ構造や必要な認証情報が異なることです。つまり、「同じ型で作れる部分」と「題材ごとに調べて合わせる部分」の両方があると理解することが重要です。

次に進む前に、今回紹介した4つの中から1つ選び、まずは検索結果を console.log() で確認し、そのあとタイトルや画像など一部だけを画面表示するところまで試してみるのがおすすめです。そして、「どこが共通で、どこが題材ごとに違うのか」を自分の言葉で説明できるようになると、Day 70のおまけの理解がかなり深まっています。

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