LoginSignup
75
71

More than 3 years have passed since last update.

Node.js + Express でPOSTデータを取得後、WebAPIへ問い合わせる

Last updated at Posted at 2019-08-04

とある Web APIを触っていたところ

  • CORS設定により、ブラウザからのAPIリクエストが許可されていない。
  • しかし、ブラウザからの入力値を受け取り、WebAPIへリクエストを送りたい。
  • できればJavaScript(Node.js)で構築したい

というユースケースがあり、ちょっと試してみました。

やること

  • Webフォームからデータを入力
  • Node.jsのサーバーへPOSTで送信
  • Node.js サーバーからWebAPIへリクエストを送り、返り値をWebフォームへ送る

実装

  1. Node.jsでPOST値を受け取るため、Expressでサーバーを立ち上げる
  2. POSTで送られたデータをrequest モジュールでAPIへ送信
  3. 返り値をPromiseで待受け、ブラウザへ返す

という流れで実装しました。

「Webフォームから入力した書籍名を、Google Books APIへ問い合わせし、返り値を返す」というシナリオで実装します。

(※Google Books API はブラウザからもリクエストを受け付けますが、参考実装ということで)

開発環境は以下のとおりです。

  • OS
    • Ubuntu Linux (Windows Subsystem for Linux)
  • Node
    • v10.16.0
  • npm
    • 6.9.0

Express とbody-parser のインストールとサーバー起動

最初に Expressbody-parser のインストールを行う。インストールはnpmを利用

npm install express --save
npm install body-parser --save

インストール後、Expressの起動スクリプトを記述。ポート番号を3000で待ち受け。「http://127.0.0.1:3000/auth/」 のエンドポイントで、POSTリクエストを待ち受ける。
POSTで送られてきたbodyデータを、console.logで出力。

index.js

const express = require('express')
const app = express()
const bodyParser = require('body-parser')
const port = 3000
app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(bodyParser.json());
app.post('/auth/', (req, res) => {
  console.log(req.body);
  res.send("Received POST Data!");
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`))

Expressサーバーを起動後、エンドポンイト「auth」にPOSTを送ると、POSTの値が表示される。

curl でPOST送信

curl -X POST -H "Content-Type: application/json" -d '{"test":"test"}' 127.0.0.1:3000/auth

Express サーバーのコンソールに、POSTで送信されたJSON {"test": "test"} が表示されているのがわかる。

2019-08-04.png

POST送信したクライアントには、「Received POST DATA!」という値が返される

2019-08-04 (1).png

requestのインストールとWebAPIへのリクエスト

次に、request を利用した Web APIへのリクエストを実装する。
最初にrequestをインストール。

npm install request --save

次に、requestを利用して、Google Books API へ問い合わせるためのコードを記述。
Google Books API へ、ISBNコードを送信。レスポンスのJSONから、タイトルを表示する。
サンプルデータは、小説家・古川日出男さんの著書「平家物語 犬王の巻」にしてみた。

ISBNコードは
4309025447
となる。

request.js

const request = require('request')
const options = {
    method: 'GET',
    json: true,
    url: "https://www.googleapis.com/books/v1/volumes?q=isbn:4309025447",
}
request(options, function(error, response, body) {
    console.log(body.items[0].volumeInfo.title);
});

上記のコードを実行すると、Google Books API の返り値からタイトルを取得し、コンソールへ表示を行う。

2019-08-04 (3).png

フォームも含めた実装

上記の2つのコードを統合し、htmlの入力フォームを実装する。

  • フォームからISBNコードを入力して、Express サーバーへPOST送信
  • Express サーバーがPOSTデータをパースし、Google Books API へリクエスト送信
  • Google Books API からのレスポンスからBodyを抽出し、JSONデータとしてhtmlフォームへ返却
  • htmlフォーム側の console.log に書籍のタイトルを表示

という流れで実装しました。

Express で静的ファイルをホスティングする

Express では、「express.static」の指定を行うことで、静的ファイルのホスティングパスの指定ができる

Express と request のコードをまとめて実装。

index.jsは以下の通り。

「public」ディレクトリを静的ファイルの公開パスと設定。
「/public/index.html」 に保存したhtmlは

http://127.0.0.1:3000/

で表示されます。

const express = require('express')
const app = express()
const bodyParser = require('body-parser')
const request = require('request')
const port = 3000
app.use('/', express.static('public'));
app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(bodyParser.json());
app.post('/auth/', (req, res) => {
    const options = {
        method: 'GET',
        url: "https://www.googleapis.com/books/v1/volumes?q=isbn:" + req.body.number,
        json: true,
    };
    request(options, function(error, response, body) {
        console.log(body.items[0].volumeInfo.title);
        res.send(body);
    });
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`))

index.html。index.jsで指定した「auth」エンドポイントへ、POSTデータを送信。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>Node.js サンプルモック</title>
</head>
<body>
    <div>
        <h2>ISBNコード送信</h2>
        <div>
            <input id="isbn" placeholder="isbn" type="text">
        </div>
        <div>
            <button id="send">送信</button>
        </div>
    </div>
    <script>

    document.getElementById("send").onclick = function() {

      const isbn = document.getElementById("isbn").value;
      const json = {"number" : isbn};

      fetch('http://127.0.0.1:3000/auth/', {

        method: 'POST',
        headers: {
         'content-type': 'application/json',
        },
        body: JSON.stringify(json),

      }).then(response => {

       return response.json();

      }).then(res => {

       console.log(res.items[0].volumeInfo.title);

         }).catch(error => {

           console.log(error);
      });

    };

    </script>
</body>
</html>

Node.js で公開されたindex.htmlに対して、ISBNコード「4309025447」を入力後、送信すると、index.js側でGoogle Books APIに書籍情報を問い合わせ、Express サーバー、index.htmlのコンソールにそれぞれ書籍名が表示されます。

console.png

mock-form.png

参照情報

75
71
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
75
71