一覧へ

fetch APIで実験データを取得する

fetch APIでサーバーから遺伝子・実験データを取得する方法。Ajax非同期通信とJSONデータ処理をバイオの例で学びます。

入門
|
75
|
検証済み (2026-06)
Ajaxfetch API非同期通信JSONSPAサーバー通信
進捗0/19 (0%)

fetch APIで実験データを取得する

これまでJavaScriptで実験データの計算を行い、Node.jsでサーバー環境のファイル読み書きを学びました。しかしそのデータはすべてコード内に直接書き込むか、ローカルファイルから読み込んだものでした。実際の研究ではデータはネットワークの向こうのサーバーにあります — NCBIで遺伝子情報を検索し、社内のLIMSから試料リストを取得し、公開APIからタンパク質構造を取得します。

このプロセスがまさにAjaxです。外部シーケンシング業者にサンプルを送るのと同じです — 結果が届くまで実験室でぼーっと待たずに、他の実験を続けて、結果が届いたらその時確認します。Webも同じです。サーバーにデータをリクエストしておき、ブラウザは止まらずに動き続け、レスポンスが届いたら画面を更新します。

fetch:サーバーにデータをリクエストする

fetch()はサーバーに「このデータをください」とリクエストする関数です。NCBIに遺伝子名を入力して検索ボタンを押すのと同じです。

javascript
fetch("https://api.example.com/gene/TP53")
  .then(function(response) {
    return response.text();
  })
  .then(function(data) {
    console.log(data);
  });

console.log("リクエスト送信完了、他の作業を続行");

このコードは3つのステップで動作します:

  1. fetch(url) — サーバーにリクエストを送る
  2. .then(function(response) { ... }) — レスポンスが届いたら実行する処理を予約する
  3. .then(function(data) { ... }) — データを受け取って処理する

キーワードは予約です。fetchはレスポンスを待たずにすぐ次の行に進みます。だから"リクエスト送信完了、他の作業を続行"が先に出力され、サーバーレスポンスが届いた後にようやく.then内のコードが実行されます。

非同期:AjaxのA

Ajaxで最も重要な文字は先頭のAAsynchronous(非同期)です。

遺伝子解析の依頼を例えにしてみましょう:

javascript
// 同期(Synchronous)方式なら:
// 1. シーケンシング業者にサンプルを送る
// 2. 結果が届くまで5日間、実験室で何もせず待機
// 3. 結果到着、ようやく次の実験開始
// → 実験室の稼働率:最悪

// 非同期(Asynchronous)方式 — 実際にこうします:
// 1. シーケンシング業者にサンプルを送る
// 2. 待っている間に細胞培養、バッファー調製、論文を読む
// 3. 結果到着通知 → その時確認して次のステップへ
// → 実験室の稼働率:最適

コードで確認してみましょう:

javascript
function showGeneInfo() {
  console.log("遺伝子情報の受信完了");
}

fetch("https://api.example.com/gene/BRCA1").then(showGeneInfo);

console.log(1);
console.log(2);

実行結果:

text
1
2
遺伝子情報の受信完了

12が先に出力されます。fetchはサーバーにリクエストを送るだけですぐ次の行に進むからです。後からサーバーレスポンスが届いた時にようやくshowGeneInfoが実行されます。ブラウザがデータをダウンロードしている間も、スクロール、クリック、入力はすべて正常に動作します。これが非同期の力です。

無名関数でコードを短縮する

先ほどshowGeneInfoと名前をつけた関数は.thenの中で1回しか使いません。こういう場合、名前なしでそのまま入れることができます:

javascript
// 名前付き関数
function showResult() {
  console.log("結果到着");
}
fetch("https://api.example.com/gene/TP53").then(showResult);

// 無名関数で短縮 — 同じ動作
fetch("https://api.example.com/gene/TP53").then(function() {
  console.log("結果到着");
});

.then内の関数にはサーバーが送り返した結果物が自動的に渡されます。この結果を受け取る変数名は自由につけられます — 慣例としてresponseと書きます:

javascript
fetch("https://api.example.com/gene/TP53")
  .then(function(response) {
    console.log(response);
  });

実験報告書が封筒に入って届くのを思い浮かべてください。responseはその封筒です — 中には実際のデータだけでなく「配送が成功したかどうか」などのメタ情報も入っています。

Responseオブジェクト:封筒を開ける

responseには通信結果に関する詳細情報が含まれています:

javascript
fetch("https://api.example.com/gene/TP53")
  .then(function(response) {
    console.log(response.status); // 200(成功)
    console.log(response.ok);     // true
  });

主要プロパティ:

  • status — HTTPステータスコード。200なら成功、404ならデータなし
  • ok — ステータスコードが200〜299の範囲ならtrue

QC検査のようにレスポンスの状態を先に確認してから処理できます:

javascript
fetch("https://api.example.com/gene/TP53")
  .then(function(response) {
    if (response.status === 404) {
      console.log("該当する遺伝子が見つかりません");
    } else if (response.status === 200) {
      console.log("データ受信成功");
    }
  });

console.assert(200 >= 200 && 200 <= 299, "200は成功範囲内");
console.assert(404 < 200 || 404 > 299, "404は成功範囲外");

JSON:実験データの標準フォーマット

サーバーから受け取るデータは通常JSON(JavaScript Object Notation)形式です。実験室ですべての試料情報を決まった書式で記録するように、WebではJSONがその標準書式です。

javascript
// JSON形式の遺伝子データ
const geneDataJson = '{"name": "TP53", "chromosome": "17p13.1", "function": "tumor suppressor", "length_bp": 19149}';

// JSON文字列 → JavaScriptオブジェクトに変換
const gene = JSON.parse(geneDataJson);

console.log(gene.name);        // "TP53"
console.log(gene.chromosome);  // "17p13.1"
console.log(gene.length_bp);   // 19149

console.assert(gene.name === "TP53", "遺伝子名を確認");
console.assert(typeof gene.length_bp === "number", "長さは数値型");

fetchでJSONデータを受け取る時はresponse.json()を使います:

javascript
fetch("https://api.example.com/gene/TP53")
  .then(function(response) {
    return response.json();
  })
  .then(function(gene) {
    console.log(gene.name);       // "TP53"
    console.log(gene.chromosome); // "17p13.1"
  });

response.text()はレスポンスをプレーン文字列で、response.json()はJSONをパースしてJavaScriptオブジェクトで返します。実験データのような構造化された情報を受け取る時はほぼ常に.json()を使います。

複数の試料データを配列で受け取ることも一般的です:

javascript
const samplesJson = '[{"id": "S001", "od": 0.85, "pass": true}, {"id": "S002", "od": 0.12, "pass": false}, {"id": "S003", "od": 1.23, "pass": true}]';

const samples = JSON.parse(samplesJson);

for (let i = 0; i < samples.length; i++) {
  const status = samples[i].pass ? "PASS" : "FAIL";
  console.log(`${samples[i].id}: OD=${samples[i].od} → ${status}`);
}
// S001: OD=0.85 → PASS
// S002: OD=0.12 → FAIL
// S003: OD=1.23 → PASS

console.assert(samples.length === 3, "試料3個");
console.assert(samples[1].pass === false, "S002はFAIL");

SPA:ページ全体を再読み込みしないアプリ

学んだfetchを活用すればSPA(Single Page Application)が作れます。1つのHTMLページの中で必要な部分だけを差し替える方式です。

LIMS(Laboratory Information Management System)を思い浮かべてください。左メニューで「DNA抽出」をクリックすると右側の領域にそのプロトコルが表示され、「PCR」をクリックすると同じ場所にPCRプロトコルが表示されます。ページ全体は再読み込みされず、コンテンツ領域だけが変わります。

javascript
function loadProtocol(name) {
  fetch("https://api.example.com/protocols/" + name)
    .then(function(response) {
      return response.text();
    })
    .then(function(content) {
      document.querySelector("#protocol-content").innerHTML = content;
    });
}

// ボタンクリック時にプロトコルを読み込み
// loadProtocol("dna-extraction");
// loadProtocol("pcr");

document.querySelector("#protocol-content")で特定の領域をピンポイントで選び、innerHTMLでその中身だけを差し替えます。残り(ヘッダー、メニュー、フッター)はそのまま維持されます。これがSPAの本質です。

1つ注意点 — innerHTMLを使う時は変更する領域だけを正確に選択する必要があります。親要素を選んでしまうと、その中の他の子要素まですべて消えてしまいます。ゲル画像で特定のレーンだけを切り貼りしようとして、隣のレーンまで消してしまうミスと同じです。

データとロジックの分離

良いコードはデータロジックを分離します。実験プロトコル(手順)と試料リスト(データ)を同じ文書に混在させると、試料が変わるたびにプロトコル文書をいじることになります。うっかり手順を壊してしまうリスクが生じます。

コードも同じです。遺伝子リストのようなデータは別ファイル(またはサーバー)に置き、コードはそのデータをfetchで取得して処理する構造が理想的です:

javascript
// データ:サーバーのJSONファイルに保存
// [{"name": "TP53", "type": "tumor suppressor"},
//  {"name": "BRCA1", "type": "DNA repair"},
//  {"name": "EGFR", "type": "receptor tyrosine kinase"}]

// ロジック:JavaScriptでデータを取得して画面に表示
fetch("https://api.example.com/genes")
  .then(function(response) {
    return response.json();
  })
  .then(function(genes) {
    let listHtml = "";
    for (let i = 0; i < genes.length; i++) {
      listHtml += "<li>" + genes[i].name + " — " + genes[i].type + "</li>";
    }
    document.querySelector("#gene-list").innerHTML = listHtml;
  });

遺伝子が100個に増えてもJavaScriptコードは1行も変える必要がありません。サーバーのJSONデータを更新するだけです。

やってみよう(Faded Example)

空欄を埋めてサーバーから遺伝子情報を取得して画面に表示するコードを完成させてください。

穴埋め問題javascript
fetch("https://api.example.com/gene/TP53")
.then(function() {
return response.json();
})
.then(function(gene) {
const info = gene.name + " (" + gene. + ")";
document.querySelector("#result").innerHTML = ;
});

よくあるエラーと解決法

Q: .then内で作った変数を外で使いたいです

responsegene.then関数の中でのみ存在します。外からアクセスするとundefinedになります。データを使うすべてのコードは.thenの中に入れてください。非同期の結果は「届いた時に」処理しなければなりません。

Q: response.json()でエラーが出ます

サーバーレスポンスが有効なJSON形式でない時に発生します。まずresponse.text()で受け取ってconsole.logで実際の内容を確認してください。HTMLエラーページや空のレスポンスの場合があります。

Q: fetchリクエストが動きません(CORSエラー)

ブラウザコンソールに「CORS」関連のエラーが出ていれば、サーバーが外部アクセスを許可していないということです。ローカル開発サーバー(npx serve)を立ち上げて同じサーバーのファイルをfetchするか、CORSを許可している公開APIを使ってください。

Q: ======の違いがわかりません

=は代入(値を入れる)、===は厳密比較(型と値が両方同じか)、==は緩い比較(型変換後に比較)です。if (response.status === 200)のように条件文では常に===を使ってください。

💬 質問・コメント

0件のコメント

ログインせずに投稿できます。ゲスト投稿は投稿者自身で編集・削除できません。

0/2000

読み込み中...