Express.jsで内部APIと外部APIを実行する方法

Express.jsにおけるAPI連携の例を解説します。

概要

Express.jsは、Node.jsの軽量なWebアプリケーションフレームワークで、APIとの連携によく使用されます。APIとの連携を実現するためには、リクエストの送信やレスポンスの処理が必要となります。

ここでは、以下バージョンを使用した、Express.jsでAPIとの連携を行う方法を説明します。

Express.js v4.17.1
nodejs v19.7.0

また、今回作成するコードは全て、GitHubに掲載しています。

もちろんです。フロントエンドからAPIを実行する例として、JavaScriptを使用してFetch APIを使う方法について追記します。


フロントエンドからAPIを実行する方法

フロントエンドでAPIを使用することは一般的なシナリオで、JavaScriptのFetch APIを使うと簡単に実装できます。Fetch APIはブラウザがネイティブで提供するAPIで、非同期HTTP(Ajax)リクエストを行うことができます。

以下の例では、Express.jsで作成した/usersエンドポイントにPOSTリクエストを送信し、新しいユーザーを作成します。

index.html

<!DOCTYPE html>
<html>
<body>
  <!-- ボタンを追加 -->
  <button onclick="createUser()">Create User</button>

  <script>
    async function createUser() {
      const response = await fetch('http://localhost:3000/users', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ name: 'John', age: 25 })
      });

      if (!response.ok) {
        const message = await response.text();
        throw new Error(`An error has occurred: ${message}`);
      }

      const user = await response.json();

      console.log(user);
    }
  </script>
</body>
</html>

解説

このソースコードは、ユーザーを作成するためのHTMLページを生成します。

  • HTMLドキュメントの定義とボタンの追加:
<!DOCTYPE html>
<html>
<body>
    <!-- ボタンを追加 -->
    <button onclick="createUser()">Create User</button>

この部分では、HTML文書の基本的な構造を定義し、ユーザーを作成するためのボタンを追加しています。ボタンがクリックされるとcreateUser関数が実行されます。

  • createUser関数の定義:
<script>
async function createUser() {
    const response = await fetch('http://localhost:3000/users', {
        method: 'POST',
        headers: {
        'Content-Type': 'application/json'
        },
        body: JSON.stringify({ name: 'John', age: 25 })
    });

この部分で非同期関数createUserを定義しています。この関数は、fetchAPIを使用して、指定したURL(この場合はhttp://localhost:3000/users)に対してPOSTリクエストを送信します。リクエストボディには、作成するユーザーの情報をJSON形式で指定します。

  • エラーハンドリング:
    if (!response.ok) {
        const message = await response.text();
        throw new Error(`An error has occurred: ${message}`);
    }

response.okプロパティは、レスポンスが成功したかどうか(HTTPステータスコードが200~299の範囲かどうか)を判断します。成功していない場合、エラーメッセージを生成してエラーをスローします。

  • レスポンスの処理とログ出力:
const user = await response.json();

response.json()メソッドを使用して、レスポンスボディをJSONとして解析します。

server.js

// モジュールをインポートします
const express = require("express");
const app = express();
const path = require("path");

// HTMLファイルをホストするディレクトリを指定します。
app.use(express.static(path.join(__dirname, "views")));
app.use(express.json());

// ユーザーを保存するための仮のデータストア
let users = [];

app.get("/", (req, res) => {
  res.sendFile(path.join(__dirname, "views", "index.html"));
});

app.get("/users", (req, res) => {
  // ユーザーデータをレスポンスとして返す
  res.json(users);
});

app.post("/users", (req, res) => {
  // リクエストボディからユーザーデータを取得
  const user = req.body;
  // ユーザーをデータストアに追加
  users.push(user);
  // 新しく作成されたユーザーをレスポンスとして返す
  res.json(user);
});

app.listen(3000, () => {
  console.log("Server is running on port 3000");
});

解説

このコードは、ユーザーの一覧と作成をサポートする基本的なExpressサーバーを構築します。以下に、それぞれの部分の詳細な説明を示します。

  • モジュールをインポート
const express = require("express");
const app = express();
const path = require("path");

この部分では、expresspathという2つのモジュールをインポートします。

  • HTMLファイルをホストするディレクトリを指定
app.use(express.static(path.join(__dirname, "views")));
app.use(express.json());

ここでは、express.staticミドルウェアを使って、“views"というディレクトリの静的ファイルをホストします。また、express.jsonミドルウェアを使って、JSON形式のリクエストボディを解析できるようにします。

  • ユーザーデータを保存するための仮データストア
let users = [];

この部分では、作成されたユーザーを保存するための配列を定義します。

  • ルーティング
app.get("/", (req, res) => {
  res.sendFile(path.join(__dirname, "views", "index.html"));
});

app.get()メソッドを使って、ルートURL(”/")へのGETリクエストをハンドリングします。リクエストが来ると、“index.html"ファイルをレスポンスとして返します。

  • ユーザーデータの取得
app.get("/users", (req, res) => {
  res.json(users);
});

/usersへのGETリクエストが来たときに、保存されている全ユーザーの一覧をJSON形式でレスポンスとして返します。

  • ユーザーの作成
app.post("/users", (req, res) => {
  const user = req.body;
  users.push(user);
  res.json(user);
});

/usersへのPOSTリクエストが来たときに、リクエストボディからユーザーデータを取得し、それをデータストアに追加します。新しく作成されたユーザーをJSON形式でレスポンスとして返します。

  • サーバーの起動
app.listen(3000, () => {
  console.log("Server is running on port 3000");
});

最後に、サーバーを起動し、ポート3000でリッスンします。サーバーが起動すると、“Server is running on port 3000"というメッセージがコンソールに表示されます。

最終的に以下のようなディレクトリ構成になります。

integration
├── node_modules
│   └── (依存関係のパッケージ)
├── views
│   └── index.html
├── server.js
├── package.json
└── package-lock.json

ここまで完成したら、以下のコマンドを実行してサーバーを起動します。

node server.js

実行が完了したら、ブラウザでhttp://localhost:3000にアクセスしてみましょう。 ボタンをクリックすると、ユーザーが作成されます。 ユーザーが作成された、http://localhost:3000/usersにアクセスすると、作成されたユーザーの一覧が表示されます。

外部APIへのリクエストを送信する

外部APIへのリクエストを送信するためには、通常、HTTPクライアントライブラリが使用されます。ここでは、その一つであるaxiosを使用します。まず、npmを使ってaxiosをインストールします。

npm install axios

external.js

const express = require('express');
const axios = require('axios');

const app = express();

app.get('/data', async (req, res) => {
  try {
    const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
    res.send(response.data);
  } catch (error) {
    res.status(500).send({ message: 'Error occurred' });
  }
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

解説

このコードは、JSONプレースホルダーAPIからデータを取得し、そのデータをレスポンスとして送信するExpressサーバーを作成します。

  • モジュールのインポート:
const express = require('express');
const axios = require('axios');

この部分で、expressaxiosという2つのモジュールをインポートします。expressはWebサーバーフレームワーク、axiosはHTTPクライアントライブラリです。

  • Expressアプリケーションの作成:
const app = express();

ここでExpressアプリケーションを作成します。

  • ルートの定義:
app.get('/data', async (req, res) => {
  try {
    const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
    res.send(response.data);
  } catch (error) {
    res.status(500).send({ message: 'Error occurred' });
  }
});

/dataエンドポイントにGETリクエストが来たときのハンドラーを定義します。非同期関数内でaxios.getを使って外部APIからデータを取得し、そのデータをレスポンスとして送信します。エラーが発生した場合は、ステータスコード500とエラーメッセージを含むレスポンスを送信します。

  • サーバーの起動:
app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

最後に、サーバーを起動し、ポート3000でリッスンします。サーバーが起動すると、“Server is running on port 3000"というメッセージがコンソールに表示されます。

テスト

curl http://localhost:3000/data

まとめ