Getting Started

2020/03/05

Node.js API通信

どうも、こんにちは!JellyWareです。

Getting Started!! Riiiver tutorialの第8弾となります。

このシリーズは、Riiiverやプログラミングを学び、初心者の方でもEco-Drive Riiiverを活用したオリジナルアプリを理解して作れるようになることを目指します。

第8弾では、API通信を行います。前回まではJavaScriptの内容を扱っていましたが、今回は Node.js の特徴である「通信」を扱います。「API通信」については、第4弾をご参照ください。

引き続きglitchを使用します。glitchについては、第6弾をご参照ください。


目次


モジュールをインポート

今回もモジュールを活用します。前回はモジュールをアップロードしましたが、今回はインストールします。

まずは、プロジェクトを作成します。

package.jsonをクリックします。


Add Pacakageというボタンをクリックすると、このような検索フォームが現れます。

ここで、使用したいモジュールを検索してインストールすることができます。request-promiseというモジュールを試しにインストールしてみます。

検索フォームにrequest-promiseと打ち込むと、自動で検索されます。あとは、クリックするだけです。


念の為、インストールできたかどうかを確認したい方はpacage.jsonをチェックしてください。request-promiseが追加されていれば問題ありません。


以下、今回の通信相手となるサービスのまとめです。

通信相手

  • ZipCloud
    郵便番号に対する住所を取得できる
  • OpenWeather
    各地の天気情報を取得できる

使用するモジュール

  • request
  • request-promise

使用するのはrequest-promiseだけですが、requestというモジュールもセットでインストールをする必要があります。これは、request-promiserequestを拡張して作られたモジュールで、requestモジュールに依存しているためです。

大まかな手順

  1. API通信に必要なモノを確認
  2. Node.jsでAPI通信を行うコードを作成

必要なモノというのは、以下の3つのです。(第4弾のREST APIの復習です。)

  • URL
  • 送信データ
  • 通信方法(主にGET,POST)

「URL」,「送信データ」がどういうものなのかはサービスによって異なるため、サービス毎に調べる必要があります。

調べ方としては、各サービスのサイト内ドキュメントを確認することをお勧めします。

また、「Node.js サービス名」などで検索すると、そのサービスを活用したJavaScript のコードを参考にできます。

今回は、あらかじめ調べているため調査不要です。


URLクエリパラメータ

API通信の前にURLクエリパラメータについて解説します。クエリ文字列とも呼ばれ、GETで通信する際に使用されます。

URLクエリパラメータとは、データを送るためにURLの最後に追加する文字列のことです。単純に値だけを追加するのではなく、変数名とセットになっているのが特徴です。
(変数名は、ユーザーが決めることはできません。サービス側が決めます。)

例としてhttps://www.google.com/searchに、URLクエリパラメータを追加してみましょう。
追加するデータは下記の2つです。

変数名 役割
q riiiver 検索する文字列
hl en 検索する言語

次のようになります。

https://www.google.com/search?q=riiiver&hl=en

追加した箇所を確認しましょう。

?q=riiiver&hl=en

まず、URLクエリパラメータの特徴として頭に?をつけます。その後に変数名=値とデータを追加していき、複数のデータを追加する場合は&を使用します。

実際にhttps://www.google.com/search?q=riiiver&hl=enをクリックして開くと、英語のGoogleサイトで「riiiver」と検索されたページが開かれます。

このようにURLクエリパラメータを使用することで、「URL」と「送信データ」を1つにまとめることができます。

つまり、GETの場合は必要なモノは以下の2つと言い換えられます。

  • URL + URLクエリパラメータ(送信データ)
  • 通信方法:GET

request-promise

API通信を行う前にrequest-promiseについて説明します。
request-promiseは、非同期処理でAPI通信を行うモジュールです。

const requestPromise = require("request-promise");

モジュールのため、require()を使用して読み込む必要があります。

前回は「モジュールのパス」を引数としていましたが、request-promiseはインストールしたモジュールのため、引数は「モジュール名」となっています。(引数についての説明は、第6弾をご参照ください。)

requestPromise({
    uri: "URL",
    method: "通信方法"
})

request-promiseには、上記のように{ }で囲った値を引数として渡します。「オブジェクト」と呼ばれるデータ形式で、次回学ぶ JSON というデータ形式とほとんど同じ形式です。

簡単に説明すると、「変数」と「値」をコロンで対応させる形式です。今回の場合だと、uri"URL"を、method"通信方法"を対応させています。

ここに「送信データ」を追加することで、サービスとAPI通信を行うことができます。「GET」と「POST」で書き方が少し異なります。

GETの場合

requestPromise({
    uri: "URL + URLクエリパラメータ",
    method: "GET"
})

GET の場合は、先ほど学んだ「URLクエリパラメータ」を使用してもらえれば問題ありません。uriに対応する値として"URL + URLクエリパラメータ"を設定します。

POSTの場合

requestPromise({
    uri: "URL",
    method: "POST",
    form: {
      変数名:,
      ...
    }
})

POST の場合、form に対応する値として送信データを設定します。データの形式がオブジェクトになっているので気を付けてください。

また、オブジェクト内の変数名は、URLクエリパラメータ同様、サービス側が決めるものです。


API通信

それではAPI通信を行います。

ZipCloud

まずは、ZipCloudと通信してみましょう。

必要なモノ

通信方法がGETのため、URLクエリパラメータを使用することができます。
ZipCloudの場合は、zipcodeが変数名となります。

https://zip-cloud.appspot.com/api/search?zipcode={郵便番号}

という形が最終的に使用するURLとなります。試しに下記のURLをクリックしてみましょう。

https://zip-cloud.appspot.com/api/search?zipcode=1310045

クリックするとこのような画面が表示されます。こちらがAPI通信を行って取得したデータです。

見慣れないデータ形式ですが、住所情報であることが分かると思います。(こちらのデータ形式については次回解説します。)

コード

それでは、JavaScriptでAPI通信を行います。
まずは、以下のコードを実行しましょう。API通信を行うコードです。

// request-promiseの読み込み const requestPromise = require("request-promise"); // URL let url = "https://zip-cloud.appspot.com/api/search"; // 送信データ const zipCode = "1310045"; // 最終URL作成 url = `${url}?zipcode=${zipCode}`; // API通信 const doApi = async () => { try { const result = await requestPromise({ uri: url, method: "GET" }); console.log(result); } catch (error) { console.log("Error message: " + error.message); } }; // 実行 doApi();

実行すると次のような結果が出力されます。

{
	"message": null,
	"results": [
		{
			"address1": "東京都",
			"address2": "墨田区",
			"address3": "押上",
			"kana1": "トウキョウト",
			"kana2": "スミダク",
			"kana3": "オシアゲ",
			"prefcode": "13",
			"zipcode": "1310045"
		}
	],
	"status": 200
}

先ほどの画面に映っているデータと同じものが表示されます。

それでは、具体的にコードを解説していきます。

// request-promiseの読み込み const requestPromise = require("request-promise"); // URL let url = "https://zip-cloud.appspot.com/api/search"; // 郵便番号 const zipCode = "1310045"; // 最終URL url = `${url}?zipcode=${zipCode}`;

前半は、API通信のための準備です。順に以下のことを行っています。

  • request-promiseの読み込み
  • URLの設定
  • 送信データである郵便番号の設定
  • 最終URLの作成

また、URLと送信データを文字連結して、最終的に活用するURLを作成しています。(別の郵便番号を使用する場合は、1310045のところを差し替えてください。)

// API通信 const doAPI = async () => { try { const result = await requestPromise({ uri: url, method: "GET" }); console.log(result); } catch (error) { console.log(`Error message: ${error.message}`); } }; // 実行 doAPI();

後半は、API通信を行うdoAPI関数を作成し実行しています。

この関数は、async functionで try…catch構文 を行っています。

try {
    const result = await requestPromise({
      uri: url,
      method: "GET"
    });

    console.log(result);
} catch (error) {
    console.log(`Error message: ${error.message}`);
}

復習となりますが、try…catch構文はtry内で実行した処理にエラーが起きるとcatchに処理が移ります。

今回であれば、tryでAPI通信を行い、もしエラーが起きるとcatchでそのエラー内容を出力するようにしています。

const result = await requestPromise({
    uri: url,
    method: "GET"
});

try内では、request-promiseを使用し、非同期処理でAPI通信を行っています。非同期処理のためawaitを追加しています。

今回は、GET でURLクエリパラメータとして送信データをURLに追加しているため

  • URL + URLクエリパラメータ(送信データ)
  • 通信方法

の2種類を引数に渡しています。

console.log(result);

そして、返ってきたデータをresult変数に代入して、出力しています。

今回は受け取ったデータをそのまま出力しただけですが、このデータを元に色々な処理を行うこともできます。


OpenWeather

次にOpenWeatherを使って天気情報を取得します。

必要なデータ

通信方法がGETのため、同様にURLクエリパラメータを使用できます。
都市名に対応する変数がqで、API Key に対応する変数がAPPIDです。

http://api.openweathermap.org/data/2.5/weather?q={都市名}&APPID={API Key}

という形が最終的に使用するURLとなります。

また、OpenWeather を使用するにはAPI Key と呼ばれるパスワードのようなものが必要です。

無料で取得することができます。以下の手順に従って取得しましょう。

API Key

まずはOpenWeatherにアクセスします。

次に、赤枠のSign Upボタンを押します。

必要な項目を入力して、Create Accountのボタンを押します。

そのままサインインをすると、このページに飛びます。赤枠のAPI keysを押します。

こちらのページの赤枠内にAPI Keyが記載されています。(画像では、黒く塗りつぶして見えないようにしています。)

コード

API Key を扱うため、まずは glitch のプロジェクトを非公開にします。

左上のプロジェクト名が書かれているボタンを押し、メニューを開きます。(プロジェクト名は人によって異なります。)
次に、Make This Project Privateにチェックマークをつけます。

それでは、JavaScriptを使ってAPI通信を行いますが、使用するコードは先ほどとあまり変わっていないことに注目してください。

// request-promiseの読み込み const requestPromise = require("request-promise"); // URL let url = "https://api.openweathermap.org/data/2.5/weather"; // 都市名 const cityName = "Tokyo"; // API Key const apikey = "xxxxxxxxx"; // みなさんのAPI Keyに差し替える // 最終URL url = `${url}?q=${cityName}&APPID=${apikey}`; // API通信 const doAPI = async () => { try { const result = await requestPromise({ uri: url, method: "GET" }); console.log(result); } catch (error) { console.log(`Error message: ${error.message}`); } }; // 実行 doAPI();

変更した点は、API通信の準備となる4~14行目です。

// URL
let url = "https://api.openweathermap.org/data/2.5/weather";

// 都市名
const cityName = "Tokyo";

// API Key 
const apikey = "xxxxxxxxx"; // みなさんのAPI Keyに差し替える

// 最終URL
url = `${url}?q=${cityName}&APPID=${apikey}`;
  • URLを変更
  • 送信データを変更
  • 最終URLの変更

の3点を行っているだけです。
後半のdoAPI関数には変更はありません。

実行すると、同様にデータが返ってきます。

{
	"coord": {
		"lon": 139.69,
		"lat": 35.69
	},
	"weather": [{
		"id": 803,
		"main": "Clouds",
		"description": "broken clouds",
		"icon": "04d"
	}],
	"base": "stations",
	"main": {
		"temp": 286.43,
		"feels_like": 285.65,
		"temp_min": 284.82,
		"temp_max": 288.15,
		"pressure": 1020,
		"humidity": 71
	},
	"visibility": 10000,
	"wind": {
		"speed": 0.5,
		"deg": 150
	},
	"clouds": {
		"all": 75
	},
	"dt": 1579847078,
	"sys": {
		"type": 1,
		"id": 8077,
		"country": "JP",
		"sunrise": 1579816028,
		"sunset": 1579852721
	},
	"timezone": 32400,
	"id": 1850144,
	"name": "Tokyo",
	"cod": 200
}

実行する日や時間によって、天気に関するデータの中身が変わると思いますが、上記のようなデータが表示されていれば問題ありません。


以上で、API通信は終わりです。

API通信に対して難しい印象を持たれていた方もいらっしゃるかと思いますが、モジュールを使用するとシンプルに行えます。

また、API通信を行う処理自体は共通で、必要なURLなどが異なっているだけなので、上記コードを使い回して他のサービスでも練習してもらえればと思います。

ご覧くださいましてありがとうございました。