1日目のゴールと今日やること
Datamuse API 中級編 1 日目のテーマは
「単語を入力すると、関連する単語や類義語を API から取得して表示するミニアプリを作る」
ことです。
キーワードはこの 3 つです。
- fetch
- Promise / async-await
- エラーハンドリング
実装としては、まずこのレベルを目指します。
- テキストボックスに英単語を入力
- 「検索」ボタンを押す
- Datamuse API から関連語(似た意味の単語など)を取得
- 取得中は「読み込み中…」を表示
- 成功したら単語一覧を表示
- 失敗したらエラーメッセージを表示
「ニュース」や「天気」と違って、
今日は「単語遊び」がテーマです。
でも、使う技術はまったく同じ——fetch・async/await・エラーハンドリングです。
Datamuse API のざっくり概要
Datamuse API って何をしてくれるの?
Datamuse API は、
「単語に関するいろいろな情報を返してくれる無料の API」 です。
例えば:
- 類義語(似た意味の単語)
- 連想語(その単語から連想される単語)
- 韻を踏む単語
- 前方一致・後方一致の単語
などを簡単に取得できます。
今日使うのは、まず一番シンプルなエンドポイントです。
https://api.datamuse.com/words?ml=word
ml は「means like(〜のような意味)」の略で、ml=happy とすると「happy に意味が近い単語」が返ってきます。
今日作るミニアプリのイメージ
画面構成
まずは、超シンプルな UI を考えます。
- 単語入力欄(英単語)
- 「関連語を検索」ボタン
- ステータス表示(読み込み中・成功・エラー)
- 結果表示(関連語の一覧)
HTML のイメージはこんな感じです。
<input id="wordInput" placeholder="英単語を入力 (例: happy)" />
<button id="searchButton">関連語を検索</button>
<div id="status"></div>
<div id="result"></div>
status は「ローディングやエラー表示」用、result は「関連語一覧の表示」用です。
fetch を「サーバーにお願いしに行く関数」として理解する
fetch の基本形
fetch は、
「この URL にアクセスして、結果をちょうだい」
とブラウザに頼む関数です。
一番シンプルな形はこうです。
fetch("https://api.datamuse.com/words?ml=happy")
.then((response) => {
console.log("レスポンスが返ってきた", response);
})
.catch((error) => {
console.error("通信に失敗した", error);
});
JavaScriptここで大事なのは、
- fetch は「すぐに結果」ではなく「Promise(あとで結果がわかる箱)」を返す
- then は「成功したときにやること」
- catch は「失敗したときにやること」
ということです。
Promise と async/await をかみ砕いて理解する
Promise は「未来の結果の箱」
fetch を呼ぶと、
「今はまだ結果がないけど、終わったら教えるね」という
Promise が返ってきます。
const promise = fetch(url);
// promise は「いつか結果が入る箱」
JavaScriptthen で「終わったらこれをしてね」と予約します。
promise.then((response) => {
console.log("終わったよ", response);
});
JavaScriptasync/await は「同期っぽく書ける魔法の文法」
Promise を then でつなぐと、
ネストが深くなりがちなので、
よく使われるのが async/await です。
async function getData() {
try {
const response = await fetch(url);
console.log("レスポンス", response);
} catch (error) {
console.error("エラー", error);
}
}
JavaScriptawaitは「この Promise が終わるまでここで待つ」asyncは「この関数の中で await を使いますよ」という宣言
この 2 つはセットで使います。
Datamuse API のレスポンス形式を知る
どんな JSON が返ってくるのか
例えば、https://api.datamuse.com/words?ml=happy にアクセスすると、
ざっくりこんな JSON が返ってきます。
[
{ "word": "glad", "score": 1234 },
{ "word": "joyful", "score": 1100 },
{ "word": "cheerful", "score": 980 }
]
ポイントは:
- 配列(
[])で返ってくる - 各要素はオブジェクト(
{}) wordに単語、scoreに関連度のような数値
つまり、
「配列をループして word を取り出して表示する」
という構造になります。
イベントの準備と「中心となる async 関数」
DOM 要素を取得する
まずは JavaScript で HTML 要素を取ってきます。
const wordInput = document.getElementById("wordInput");
const searchButton = document.getElementById("searchButton");
const statusDiv = document.getElementById("status");
const resultDiv = document.getElementById("result");
JavaScriptボタンにクリックイベントを付ける
searchButton.addEventListener("click", () => {
const word = wordInput.value.trim();
if (!word) {
statusDiv.textContent = "単語を入力してください。";
resultDiv.textContent = "";
return;
}
fetchRelatedWords(word);
});
JavaScriptここまでは「きっかけ作り」です。
本番は fetchRelatedWords の中身です。
ローディング表示を入れて「ちゃんと待っている」ことを伝える
通信前にローディング状態にする
ユーザーは「押したのに何も起きない」と不安になります。
なので、通信前に必ず「今取りに行ってますよ」と伝えます。
async function fetchRelatedWords(word) {
statusDiv.textContent = "関連語を取得中です…";
resultDiv.textContent = "";
searchButton.disabled = true;
try {
const url = `https://api.datamuse.com/words?ml=${encodeURIComponent(word)}`;
const response = await fetch(url);
// ここからレスポンスのチェック
} catch (error) {
// 通信レベルのエラー
} finally {
// 最後に必ずボタンを戻す
}
}
JavaScriptここで重要なのは、
- ローディング表示は fetch の前に出す
- ボタンを無効化して「連打による多重起動」を防ぐ
という 2 点です。
エラーハンドリングの 2 段階を意識する(Datamuse 版)
NewsAPI や WeatherAPI と違って、
Datamuse は「status: ‘error’」のようなフィールドを返しません。
その代わり、次の 2 段階を意識します。
段階 1:fetch 自体の失敗(ネットワークエラー)
try {
const response = await fetch(url);
} catch (error) {
statusDiv.textContent = "通信に失敗しました。ネットワークを確認してください。";
console.error(error);
searchButton.disabled = false;
return;
}
JavaScriptここでの失敗は、
「サーバーにたどり着けなかった」などのレベルです。
段階 2:HTTP ステータスコードのチェック
Datamuse は基本的に 200 を返しますが、
一般的なパターンとして response.ok をチェックする癖をつけます。
const response = await fetch(url);
if (!response.ok) {
statusDiv.textContent = `サーバーエラーが発生しました。(${response.status})`;
searchButton.disabled = false;
return;
}
JavaScriptresponse.ok はステータスコードが 200〜299 のとき true になります。
成功時の関連語一覧表示を作る
JSON をパースして配列を扱う
const data = await response.json();
JavaScriptdata は配列です。
中身が空かどうかをチェックします。
if (!Array.isArray(data) || data.length === 0) {
statusDiv.textContent = "関連する単語が見つかりませんでした。";
resultDiv.textContent = "";
searchButton.disabled = false;
return;
}
JavaScript単語一覧を HTML に変換する
function renderWords(data) {
let html = "<h3>関連する単語</h3>";
data.forEach((item) => {
const word = item.word;
const score = item.score;
html += `<p>${word}(スコア: ${score})</p>`;
});
resultDiv.innerHTML = html;
}
JavaScriptfetchRelatedWords の中で呼び出します。
statusDiv.textContent = "関連語の取得に成功しました。";
renderWords(data);
JavaScript通信失敗時の分岐を「ユーザー目線」で設計する
失敗パターンをざっくり分ける
1 日目で意識してほしいのは、
「全部まとめて“エラーです”で終わらせない」ことです。
Datamuse の場合、ざっくりこう分けられます。
- ネットワークエラー(オフラインなど)
- HTTP エラー(500 番台など)
- データは返ってきたが、配列が空(該当なし)
それぞれメッセージを変えます。
- 「通信に失敗しました。ネットワークを確認してください。」
- 「サーバーエラーが発生しました。(ステータスコード)」
- 「関連する単語が見つかりませんでした。」
これだけで、ユーザーの安心感がかなり変わります。
1日目の完成コード(重要部分をまとめて)
const wordInput = document.getElementById("wordInput");
const searchButton = document.getElementById("searchButton");
const statusDiv = document.getElementById("status");
const resultDiv = document.getElementById("result");
function renderWords(data) {
let html = "<h3>関連する単語</h3>";
data.forEach((item) => {
const word = item.word;
const score = item.score;
html += `<p>${word}(スコア: ${score})</p>`;
});
resultDiv.innerHTML = html;
}
async function fetchRelatedWords(word) {
statusDiv.textContent = "関連語を取得中です…";
resultDiv.textContent = "";
searchButton.disabled = true;
try {
const url = `https://api.datamuse.com/words?ml=${encodeURIComponent(word)}`;
const response = await fetch(url);
if (!response.ok) {
statusDiv.textContent = `サーバーエラーが発生しました。(${response.status})`;
return;
}
const data = await response.json();
if (!Array.isArray(data) || data.length === 0) {
statusDiv.textContent = "関連する単語が見つかりませんでした。";
resultDiv.textContent = "";
return;
}
statusDiv.textContent = "関連語の取得に成功しました。";
renderWords(data);
} catch (error) {
statusDiv.textContent = "通信に失敗しました。ネットワークを確認してください。";
console.error(error);
} finally {
searchButton.disabled = false;
}
}
searchButton.addEventListener("click", () => {
const word = wordInput.value.trim();
if (!word) {
statusDiv.textContent = "単語を入力してください。";
resultDiv.textContent = "";
return;
}
fetchRelatedWords(word);
});
JavaScript今日いちばん深く理解してほしいこと
1 日目で本当に押さえてほしいのは、この 3 つです。
- fetch は「Promise を返す非同期処理」である
- async/await で「同期っぽく書きつつ、try-catch でエラーを扱う」
- エラーハンドリングは「通信エラー」「HTTP エラー」「該当なし」を分けて考える
そしてもうひとつ大事なのは、
「API が返す JSON の形をちゃんと理解してからコードを書く」
という姿勢です。
Datamuse は「配列で返す」「word と score を持つ」
NewsAPI は「オブジェクトで返す」「articles を持つ」
WeatherAPI は「location や current を持つ」
API ごとに形は違うけれど、
fetch・async/await・エラーハンドリングの“型”は同じです。
ここまでできたあなたは、
もう「API を触ってみている人」ではなく、
“API のレスポンス構造を理解して設計できる人” の入り口に立っています。
2 日目以降は、この Datamuse アプリに
- 検索モードの切り替え(類義語 / 連想語 / 韻を踏む単語)
- ローディング表示の改善
- 簡単なバリデーションや UI 調整
などを足して、
「言葉遊びができる便利ツール」に育てていきましょう。


