Node.jsでAysnc/Awaitを使ってHTTPリクエストを行う5つの方法 by Sam Agnew

March 19, 2020
執筆者
Sam Agnew
Twilion
レビュー担当者
Aya Shiomi
Twilion

この記事はデベロッパーエバンジェリストのSam Agnewがこちらで執筆した記事を日本語化したものになります。

HTTPリクエストはモダンなプログラミング言語におけるコアとなる機能であり、多くの開発者が新しい環境に慣れる際に学習する項目の1つです。Node.jsではもともとの言語にこの機能が備わっており、また開発者コミュニティでも多くのソリューションが開発されています。最も人気のあるものをいくつか見ていきましょう。

数年前、同じような記事をこちらで執筆しています。しかし、その後JavaScriptではaync/awaitを用いた非同期プログラミング手法が普及し主流となったため、ネットワークリクエストがこれまで以上に簡単になりました。このことに加え、HTTPライブラリとしてこれまで多くのNodeプロジェクトで利用されてきたRequestが非推奨となりました。まさにこのガイドを更新する良いタイミングです。

他の投稿と同様に、コード例ではNASAのAstronomy Picture of the Day API をJSON APIとして使用しています。

Pizza GIF

実際に試される場合は次に進む前に最新バージョンのNode.jsおよびnpmがインストールされていることをご確認ください。

HTTP - 標準ライブラリ

比較のためにPromiseとasync/awaitを使わない標準のHTTPモジュールを見てみましょう。このモジュールは、依存するパッケージやライブラリがないという利点がありますが、ほかのソリューションに比べて開発者フレンドリーとは言えません。

以下のコードは、NASAのAPIエンドポイントにGETリクエストを送り、毎日の天体写真のURLと解説を出力させます。

const https = require('https'); 
https.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY', (resp) => { 
    let data = ''; 
  
    // A chunk of data has been received. 
    resp.on('data', (chunk) => { 
        data += chunk; 
    }); 

    // The whole response has been received. Print out the result. 
    resp.on('end', () => { 
        console.log(JSON.parse(data).explanation); 
    }); 

}).on("error", (err) => { 
    console.log("Error: " + err.message); 
});

Httpとhttpsモジュールが持つ機能は、大半がかなり低レベルです。レスポンスデータを大きな塊として受信する必要があり、すべてのデータを受信したという状態を明示的に待つ必要があります。また、レスポンスデータを手動で解析する必要があります。

さらに、httpモジュールは標準でHTTPSをサポートしていないので、使用しているAPIがHTTPSで通信する場合は代わりにhttpsモジュールを使用しなければなりません。このライブラリで行われるHTTPリクエストではasync/await機能を使用できませんが、データを特定の塊単位で受信したい場合は、非同期ストリームを使用できます。

用途によってはコードを追加する必要が出てきますが、コードベースに依存関係を追加したくない場合や、低レベルの機能にアクセスしたい場合にはすばらしいユーティリティです。

Got

Gotは、より軽量なライブラリが欲しい場合に最適です。人が使いやすいように設計されており、Twilio Functionsでもデフォルトで使用できます。

Gotをnpmでインストール:

npm install got@9.6.0

GotはPromiseを利用するため先ほどと同じタスクを完了するにもコードを少なくできます。また、asyncおよびawaitキーワードを利用できます。

const got = require('got'); 

(async () => { 
    try { 
        const response = await got('https://api.nasa.gov/planetary/apodapi_key=DEMO_KEY', { json: true }); 
        console.log(response.body.url); 
        console.log(response.body.explanation); 
    } catch (error) { 
        console.log(error.response.body); 
    } 
})();

このライブラリはデフォルトでJSONをパースしないため、リクエストを行う際に引数として{ json: true }を追加する必要があります。正常系のHTTPリクエストを処理する使いやすいライブラリとしてGotはすばらしいオプションです。

Axios

Axiosは、Node.jsと同様にブラウザで動作するPromiseベースのHTTPクライアントです。

npmからAxiosをインストールするには、ターミナルに以下のコマンドを入力します:

npm install axios@0.19.2

次のコードは先ほどと同様に、毎日の天体写真のURLをログに記録し、解説を出力します。

 

const axios = require('axios'); 

(async () => { 
    try { 
        const response = await axios.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY') 
        console.log(response.data.url); 
        console.log(response.data.explanation); 
    } catch (error) { 
        console.log(error.response.body); 
    } 
})();

AxiosはデフォルトでJSONレスポンスも解析します。かなり便利ですね。2つの異なる日の画像を一度に取得したいなど複数のリクエストを同時に行いたい場合は、`axios.all`を使うことで可能です。

const axios = require('axios'); 

(async () => { 
    try { const [response1, response2] = await axios.all([ 
       axios.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&date=2020-03-18'), 
        axios.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&date=2020-03-17') 
    ]); 
    console.log(response1.data.url); 
    console.log(response1.data.explanation); 
    console.log(response2.data.url); 
    console.log(response2.data.explanation); 
    } catch (error) { 
        console.log(error.response.body); 
    } 
})();

SuperAgent

Axiosと同様に、SuperAgentもまたブラウザで非同期リクエストを行うために使用される人気のあるライブラリであり、Node.jsでも利用できます。

以下のコマンドでSuperAgentをインストールできます:

npm install superagent@5.2.2

SuperAgentのすばらしいところはoptionsオブジェクトを渡すのではなく、リクエストにパラメータを追加するquery()のように、メソッドチェインができる便利な関数を持っていることです。前の例ではURLに手動でパラメータを追加していましたが、SuperAgentは同じ処理を実現するために関数を追加していることに注目してください。

const superagent = require('superagent'); 

(async () => { 
    try { 
        const queryArguments = { 
            api_key: 'DEMO_KEY', 
            date: '2020-03-18' 
        } 
        const response = await superagent.get('https://api.nasa.gov/planetary/apod').query(queryArguments) 
        console.log(response.body.url); 
        console.log(response.body.explanation); 
    } catch (error) { 
        console.log(error.response.body); 
    } 
})();

また、Axiosと同じように自分でJSONレスポンスを解析する必要がありません。

node-fetch

node-fetchは、最小限のコードでブラウザライブラリwindow.fetchをNode.jsにもたらす軽量モジュールです。

先ほどの例と同様に、以下のようにnode-fetchをインストールします:

npm install node-fetch@2.6.0

最近のバージョンではPromiseを使用しているので、async/await構文も使用できます。

const fetch = require('node-fetch'); 

(async () => { 
    try { 
        const response = await fetch('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY') 
        const json = await response.json() 

        console.log(json.url); 
        console.log(json.explanation); 
    } catch (error) { 
        console.log(error.response.body); 
    } 
})();

このライブラリにはレスポンスをJSONに変換する機能が組み込まれていますが、AxiosやSuperAgentのような自動変換のしくみはありません。ただし、Fetch APIの使用に慣れている人には最適なライブラリです。

最後に

今回の例ではすべてのソリューションを網羅しているわけではありませんが、Nodeの中で人気のあるいくつかのHTTPライブラリの基本的な機能がどのように動作するかをご理解いただけたと思います。

他の言語にも、さまざまなライブラリがあります。Swift、PythonRubyなど、ほかのチュートリアルをチェックしてみてください。また、新しいスキルを獲得するためには、ぜひNode.jsクイックスタートをチェックしてみてください。

みなさんがHTTPリクエストを送信するお気に入りの方法はどれでしょうか。ぜひ、教えてください。