1. はじめに
みなさんフロー書いてますかぁ!(去年と同じ)
Node-REDから外部のAPIを呼び出すのに使う http request ノード、外部サービス連携の基本のキですよね。なのに、公式のドキュメントはcookbookの項目 と、あとはノードのヘルプだけ。不親切すぎません?(偏見)
本稿では、Deep Diveと称してこのhttp requestノードのほぼ全機能を順に紹介していくことにします。なお、2023/12現在最新のNode-RED 3.1.3を基に記述しますが、以降のリリースでの仕様変更については、本稿もなるべく追従して更新していきたいと思います。
2. http requestノードの基本のキ
http requestノードは、Node-RED導入時にもれなくデフォルト導入されてる「コアノード(標準ノード)」の一つで、入力と出力を1つもつ、ンプルなノードです。入力したmsgオブジェクトの内容とプロパティの設定に基づいてhttp requestを同期的に実施し、レスポンスをmsgオブジェクトとして出力する機能を持っています。
もっともシンプルな使い方は、入力にInjectノード、出力にDebugノードを接続し、
プロパティダイアログ内のURL欄にアクセスしたいURLだけを指定し、
デプロイし、Injectするだけで、URLに指定したURLにhttp/httpsでアクセスしてレスポンスを得ることができます。
Debugノードの[対象]を[msgオブジェクト全体]とすることで、
出力オブジェクトの全部のプロパティを参照することができるようになります。
WebサイトをURLに指定すると、レスポンスにはHTMLが入ります。Debugノードはデバッグサイドバーに表示できる文字列のサイズに限界がありますが、表示できない部分も取得しています。
標準ノードのHTMLパーサノードを併用することで、CSSセレクタを指定して特定の要素を取り出すことができます。たとえば、https://nodered.org/ の .node-red-latest-version を指定することで、Node-REDのサイトから現在のNode-REDの最新バージョンを取得することができます。
なお、CSSセレクタで指定する要素は、Edge/Chromeブラウザの開発者ツールを使うと確認することができます。
3. http requestノードのユースケース例
Webサイト情報取得
前項に記述のようにHTMLパーサノードを併用することで、WebサイトのHTMLページから情報を取得することができます。APIが提供されていないWebページに定期的にアクセスし、動的要素の変更を自動処理のトリガとしてフローにて自動処理できます。
WebAPIにアクセス
GET/PUT/POSTメソッドを活用して、HTTPベースのWebAPIにアクセスして外部サービスと連携することができます。
APIへのデータ入力はmsg.payload プロパティやmsg.payloadオブジェクトでクエリパラメータやリクエストボディに指定できます。APIの認証に必要な情報はノードプロパティでbasic/digest/bearer形式で指定、もしくはmsg.headersにオブジェクト形式で指定することもできます。
出力は文字列、Buffer、JSONオブジェクト形式で取得することができます。JSON以外の形式でレスポンスを得られるAPIを使う場合、標準ノードのyamlパーサノード、xmlパーサノード、csvパーサノードなどを使ってレスポンス形式を変換してデータを活用することができます。
Node-REDで書いたAPIのデバッグ
Node-REDのhttp-inノードで作成したAPIサーバ自身にアクセスしてテストするのに用いることができます。Node-RED自身URLは環境によって異なるため、http://localhost:1880/ などと指定せず、プロパティや環境変数にて設定しておくといいでしょう。
4. http requestノード機能の詳細
本稿はDeep Diveと銘打っています。これ以降はhttp requestノードが持つ機能を順番に解説していきます。
http requestノードの動作を指定する入力情報は、ノードのプロパティダイアログで指定する方法と、ノードに入力するmsgオブジェクト内で指定する方法があります。混在できますが、ノードのプロパティダイアログでの指定のほうが優先度が高いので、msgオブジェクトで指定する場合はプロパティダイアログはチェックしない、もしくは空欄にしておく必要があります。メソッドだけは「-msg.method-で定義」としておく必要があります。
なお、必須項目はメソッドとURLの2つですが、メソッドはデフォルトでGETなので、URLのみ必須で設定する必要があります。
4.1 http requestノードのプロパティダイアログ
ノードをダブルクリックして開くと、ノードの詳細設定をすることができるプロパティダイアログが開きます。
この項で各項目を順次説明していきます。
メソッド
httpリクエストに使うhttp methodを指定します。
デフォルトはGETメソッドが選択されています。標準では、GET/POST/PUT/DELETE/HEADメソッドを指定することができます。それ以外のメソッド(OPTIONS/TRACE/PATCH/LINK/UNLINKなど)を使いたい場合や、フロー入力から動的で指定したい場合は、「-msg.methodに定義-」を選択した上で、入力オブジェクトのmsg.methodプロパティで文字列で指定します。(「-msg.method-で定義」を選択していない場合はプロパティダイアログで選択したメソッドで上書きされます。「-msg.method-で定義」を選択してmsg.methodが与えられない場合はエラーになります。
URL
http requestする先のURLを文字列で指定します。入力オブジェクトのmsg.urlで指定することもできます。必須項目なのでどちらも指定してない場合はエラーになります。
URLの指定にはmustache形式のタグを含めることができます。これにより、URLの一部をmsgオブジェクト内のプロパティで動的に指定することができるようになります。
なお、mustache形式はURLエンコードされてしまいますが、中カッコを3つ使うとURLエンコードされないので、URLのパスやクエリパラメータをそのまま文字列で指定したい場合は使えます。
以下の例は、msg.sitepathでWebサーバ配下のサイトパスを動的に指定するものです。パスにはスラッシュが含まれるため、中かっこ3つで囲むことでURLエンコードされることを防いでいます。
(templateノードのmustacheと違い、flowコンテキスト/globalコンテキスト/環境変数は指定できません)
ペイロード
メソッドをGETメソッドに指定した場合だけペイロードメニューが表示されます。
デフォルトは[無視]となっており、msg.payloadで入力された情報はhttp requestには使用されません。
[クエリパラメータに追加]を選択するとmsg.payloadオブジェクトにKey:Value形式で指定された情報がURLのクエリパラメータとして利用されます。
[リクエストボディとして送信]を指定した場合は、msg.payloadプロパティで指定された情報がそのまま、リクエストボディとして利用されます。msg.payloadオブジェクトの場合は、JSON文字列に変換され、さらにContent-Typeヘッダを指定してない場合は[application.json]が付加されます。
入力オブジェクトで設定する場合はmsg.paytoqsで指定できます。
SSL/TLS設定
ここでは、リクエストに使うSSL/TLSのサーバ/クライアント証明書設定を行います。チェックを入れると、TLS設定フォームが現れます。
http requestノードで使うSSL/TLSの設定は、Node-REDの設定ノード「tls-config」として保存されます。詳細は後述の設定ノードの項で解説します。なお、URLがhttpsで始まる際、SSL/TLS設定を設定していない場合はOSの標準設定が使われますので、SSL/TLSによるクライアント認証を行わない場合や、サイト独自の証明書を使わない場合は、このSSL/TLS設定を設定しなくてもhttp requestを行うことができます。
認証を使用
アクセス先サイトに認証情報が必要な場合、ここで指定します。プロパティダイアログの[認証を使用]のチェックを入れると、認証設定画面のフォームが現れます。
標準では、Basic認証/Digest認証/Bearer認証を選択できます。
Basic認証/Digest認証の際はユーザ名とパスワードを文字列で指定します。
Bearer設定の場合は、認証トークン文字列を指定します。
なお、[認証を使用]で設定した内容は、http requestのAuthorizationヘッダ内に設定されますので、後述のヘッダ を使って、Authorization内に直接記述することも可能です。
入力オブジェクトで設定する場合は、msg.authType、msg.credentialsで指定することもできます。msg.headers内で直接指定することもできます。その場合、[認証を使用]のチェックを入れてしまうとフォームの設定が優先されるので、入力オブジェクトから設定する場合はチェックを入れないようにします。
コネクションkeep-aliveを有効化
連続してサイトにアクセスする場合、リクエストが終了してもhttpサーバとの接続を維持することで、httpやTLSの接続時のオーバヘッドを減らすことができます。サーバ側にkeep-aliveの機能がある場合、この「コネクションkeep-aliveを有効化」にチェックを入れることで、http requestノードの処理が終わってもサーバとの接続を切断せず維持することができます。
この設定を有効にした場合、一つのhttp requestノードから複数回数、msgオブジェクトが出力されることがあります。
サーバから「connection: close」のレスポンスがあった場合や、タイムアウトした場合に接続が切断されます。
プロキシを使用
Node-REDがイントラネットなどの内部ネットワーク内ホストで動作していて、接続先へのアクセスにproxyサーバを経由するする必要がある場合に指定します。チェックを入れるとプロキシ設定フォームが現れます。
http requestノードでつかうプロキシ設定は、Node-REDの設定ノード「http-proxy」として保存されます。詳細は後述の設定ノードの項で解説します。なお、設定ノードで指定しない場合、Node-REDが動作しているホストのネットワーク設定が使われます。
2xx以外の応答をcatchノードへ送信
チェックすると、2xx以外のHTTP レスポンスコードが得られた場合はエラーとみなしCatchノードに送信します。2xx以外のレスポンスを例外処理したい場合にチェックします。
厳密なHTTPパース処理を無効化
不正なHTTPレスポンスヘッダを返すサーバにアクセスするために、node.jsのinsecureHTTPParserフラグを有効にします。通常はチェックしないほうがいいでしょう。(厳格なパース処理が有効になりセキュリティが向上します)
出力形式
http requestノードからの出力の形式を指定します。
UTF-8文字列、バイナリバッファ、JSONオブジェクトより選択できます。デフォルトでは文字列に設定されています。JSONオブジェクトを指定した場合、レスポンスがJSON形式のパースができない文字列の場合は警告表示され、文字列型で返されます。
ヘッダ
リクエストのHTTPヘッダをKey-Valueオブジェクト形式で指定します。入力オブジェクトのmsg.headerでオブジェクトでフローから指定することもできます。
標準では空ですが、下部の[+追加]ボタンを押すことでヘッダ情報の入力欄が追加されます。
いくつでも追加できます。右端の[x]で削除でき、右端の三本線の部分をドラッグして順番を入れ替えることができます。http request時には記述した順番にヘッダが設定されます。
左側のKey部はメニューになっており、よく使うリクエストヘッダを選択できます。文字列で指定する場合は、[その他]を選択して文字列入力します。http requestのヘッダはcase-insensitiveなので大文字小文字は区別されません。また入力されるmsgオブジェクトのプロパティで指定することもできます。
右側のValue部も文字列に加えて入力されるmsgオブジェクトのプロパティで指定することもできます。
名前
http requestノード自体の名前を指定することができます。http requestノードの機能を示す名前を指定すると、フローのノード欄に表示されます。名前を指定しない場合はhttp requestと表示されます。
4.2 http-requestノードで使用される設定ノード
Node-RED設定ノードを使うことで、複数のノードで共通に使える設定を永続化することができます。http requestノードはNode-RED標準のSSL/TLS設定ノード、Proxy設定ノードを使うことができます。これらの設定ノードはNode-REDのシステムワイドに保存され、http-inノードやwebsocketノード、mqttノードなどでも同じ設定を使うことができます。
新しく設定する場合は、たとえばSSL/TLS設定ではプロパティダイアログより「新規にtls-configノードを追加...」を選択し、左側の鉛筆アイコンで設定ノードのプロパティを設定します。
ほかのノードで設定したものを使う場合は、作成時に名前として指定した設定をメニューから選択します。
不要になった設定ノードは、設定ノード左上の「削除」で削除することができます。どのノードにも使用していない設定ノードがある場合、「デプロイ」時に警告されます。またサイドバーの「設定ノード」タブの「未使用」を選択することでどのノードにも使用されていない設定ノードが表示されますので、必要に応じて削除するとよいでしょう。
SSL/TLS設定(tls-configノード)
HTTPサーバへのアクセスに個別のサーバ証明書、もしくはクライアント証明書が必要な場合に設定します。URLの先頭が「https://」であっても、ホスト標準の証明書でサーバ認証が行える場合はこの設定は不要です。
証明書の指定方法
http request時に必要なクライアント証明書はNode-REDのサイト内に永続化しておく必要があります。
SSL/TLSのクライアント証明書(公開鍵/秘密鍵/CA証明書)が手元のPCにある場合、プロパティダイアログの「ファイル」クリックするとブラウザのファイル選択ダイアログが表示されますので、ファイルを選択してアップロードすることができます。
アップロードできるファイル形式は、.PEM形式、もしくは.p12形式になります。.p12形式で公開鍵と秘密鍵が両方含まれる場合は、両方の欄に同じファイルをアップロードします。
アップロードしたファイルはNode-REDの.node-redディレクトリ内にあるflow-credential.jsonファイル内に暗号化して保存されます。
また、Node-REDが動作しているホスト内に証明書がある場合は、ホスト内のファイルのパスを指定することもできます。(「ローカルファイルの秘密鍵と証明書を使用」にチェックを入れます)
パスフレーズ
秘密鍵にパスフレーズが必要な場合は、パスフレーズ欄に文字列で指定します。
CA証明書
通常はNode-REDが動作しているホストに設定されたCA局証明書が使われますが、クライアント証明書利用時に独自のサイト証明書が必要な場合はここで指定します。
サーバ証明書を確認
SSL/TLSが必要なサイトへのアクセスは、通常はNode-REDが動作するホストに設定されたサーバ証明書でサーバ証明書を確認し、確認できない場合はコネクションエラーを返します。しかし、例えば開発用サイトなどでTLSサイト自己証明書を使っている場合などは、「サーバ証明書を確認」のチェックを外すことで証明書エラーを無視してアクセスすることができるようになります。(後述のmsg.rejectUnauthorizedと同じものです)
サーバ名
ひとつのホストで複数のホスト名に対応したhttpsサーバにアクセスする場合、SNI(Server Name Indication)という仕組みをつかってTLS接続時に暗号化せずホスト名を指定する必要がある場合があります。その際には、接続したいシステムのURL内のホスト名(FQDN)をこの欄に文字列で設定します。通常はURLのホスト部から適切に抽出されますので不要です。
ALPNプロトコル
HTTP/2をサポートするホストにアクセスする場合、ALPNプロトコル(Application-Layer Protocol Negotiation)の指定が必要な場合があります。RFC6961に指定された文字列 で指定します。http requestノードでは通常指定しません。(WebSocketで接続するアプリケーションを指定するのが主なユースケースです)
なお、指定時はURLエンコーディングされた文字列で指定する必要があります。
名前
SSL/TLS設定ノードは複数のhttp-in/http-request/websocketなどで共通に使うことができます。名前を設定しないときは、メニュー上では[TLS設定]となります。再利用するときにわかりやすいよう、適切な名前を付けておくことをお勧めします。
Proxy設定(http-proxyノード)
Node-REDが動作しているホストがイントラネットに接続している場合などに、Node-REDからhttp requestする際にプロキシを経由する必要がある場合があります。ホストのネットワーク設定を使えば個別設定が必要ない場合がほとんどですが、特定の接続先にアクセスするためにホストのネットワーク設定とは独立した設定が必要な場合にこの設定ノードを使うことができます。
名前
プロキシ設定ノードは複数のhttp-in/http-request/websocketで共通に使うことができます。再利用するときにわかりやすいよう、適切な名前を付けておくことをお勧めします。
URL
プロキシホストのURLを設定します。http/httpsのURL(ポート番号付き)を指定することができます。
プロキシ認証
プロキシを使う際に認証が必要な場合はここで指定します。チェックを入れると設定UIが表示されます。
例外ホスト
イントラネット内部ホストなど、特定のホストにアクセスする際にプロキシを使いたくない場合があります。下部の[+追加]をクリックして、ホスト名を登録することで、リストされた例外ホストに接続する場合はプロキシを経由しなくなります。
4.3 入力オブジェクト仕様
http requestノードの動作を、入力オブジェクトmsgを通じて指定することができます。msgオブジェクト内の複数のプロパティに設定することで、プロパティダイアログで設定できる以上の機能を使うことができます。
msgオブジェクトとプロパティダイアログで同じ設定をした場合、プロパティダイアログの設定が優先されますので、msgオブジェクトで指定する場合はプロパティダイアログはチェックしない、もしくは空欄にしておく必要があります。msg.methodでメソッドを指定する場合、プロパティダイアログ で「-msg.method-で定義」としておく必要があります。
入力オブジェクトの作り方
msgオブジェクトはInject/Change/Template/Functionノードなどで作ることができます。
Injectノード
Injectノードは一番単純にmsgオブジェクトを作成する方法です。
最近のInjectノードはmsg.payload/msg.topic以外の複数のプロパティを同時に設定できるので、http requestノードの動作に必要なmsgオブジェクトのプロパティを一度に設定することができます。
プロパティをオブジェクトにしたい場合は、JSONメニューを選択し、
左側の3点アイコンをクリックすることでJSONエディタが開いてオブジェクト内のプロパティを編集することができます。
Changeノード
Changeノードでもmsgオブジェクトを設定することができます。
Changeノードを使うと、[値の置換]をつかってのプロパティの合成なども可能です。
Changeノードの詳細は、拙作「Node-REDのChangeノードDeep Dive」を参照いただければ幸いです。
Functionノード
FunctionノードはJavaScriptで処理を記述することができますので、JavaScript言語で記載することでmsgオブジェクトも作成することができます。msgオブジェクトはFunctionノードには渡されているので、msgオブジェクトに直接プロパティを追加することができます。
ドット演算子をつかって追加する方法でも、ブラケット記法(文字列引数の配列)でも記述できます。Key部を定数にする場合、ハイフンを含むKeyがある場合はエラーになることがあり、その場合はブラケット記法で指定する必要があります。
msg.headers.content-type="abcd";
# これはエラーになる
msg.headers["content-type"]="abcd";
# ブラケット記法で指定
Templateノード
Templateノードでもmsgオブジェクトを作れますが、1つのTemplateノードでプロパティをひとつづつ設定できます。出力形式をJSONに設定することで、指定したプロパティがオブジェクトとして生成できます。
mustache形式のタグを含めることができます。ほかのmsgオブジェクト中のプロパティを使ったり、flow/globalコンテキストや環境変数を指定して値を使うことができます。下の例では、認証ヘッダに環境変数TOKENで指定した文字列を組み合わせています。
入力オブジェクトの詳細解説
msgオブジェクトにプロパティを指定することで、プロパティダイアログで設定できる以上の項目を動的に設定することができます。(一部の項目についてはドキュメントにはありませんが、ソースコードを確認して記述しています)
msg.url
http request接続先のURLを文字列で設定します。プロパティダイアログの指定時と同様、mustache形式のタグを含めることができます。
msg.method
httpのメソッドを文字列で指定します。文字列でGET/POST/PUT/DELETE/HEADと指定します。(内部でtoUpperCaseされているので小文字でも大丈夫です) msg.methodで指定する場合は、プロパティダイアログで「-msg.method-で定義」を指定しておく必要があります。
msg.headers
http request時にサーバに送信するリクエストヘッダを指定します。Key-Value形式のオブジェクトで指定する必要があります。Keyに指定した文字列がそのまま送信されますが、HTTPヘッダはRFC7230 に記述されているようにcase-insencitiveなので、大文字小文字は区別されません。また一部のヘッダにはハイフンが含まれるため、Functionノードで指定する場合は文字列引数の配列で指定する必要があります。
なお、一部のプロパティダイアログ の項目の一部(「認証を使用 」「ヘッダ 」など)は、msg.headersを生成しますので、それらを設定するとmsg.headersで指定した内容が上書きされてしまいます。入力のmsg.headersでリクエストヘッダを指定する際には、プロパティダイアログではチェックしないようにしましょう。
msg.cookies
http request時にサーバに送信するCookie情報を指定します。Cookieは、同一ブラウザからWebページへのアクセスする際の、複数セッション間で情報を共有する仕組みです。一部のWebページのアクセス時に、Cookieに情報を指定していないと正しくアクセスできないことがあり、その際に指定されます。
Key-Value形式のオブジェクトで指定する必要があります。Keyに指定した文字列がそのまま送信されます。Cookieは、HTTPヘッダはちがい、大文字小文字は区別されるので指定時には注意が必要です。また一部のCookieのKeyにはハイフンが含まれるため、Functionノードで指定する場合は文字列引数の配列で指定する必要があります。Valueには文字列を指定します。送信時に内部でURLエンコードされますので、Valueに指定する場合はURLエンコードする必要はありません。
msg.payload
http request時のリクエストボディを指定します。メソッドとコンテンツタイプ、msg.payloadで指定する型で挙動が変化します。
メソッドがGETの場合
後述のmsg.paytoqsの指定によって、無視/クエリストリング/リクエストボディに挙動が変化します。
メソッドがHEADの場合
msg.payloadは無視されます。
メソッドがGET/HEAD以外の場合
content-typeが'multipart/form-data'の場合は、msg.payloadオブジェクトがマルチパート形式に変換されます。パートごとにKEYを複数設定できます。詳細は後述 します。
content-typeが'application/x-www-form-urlencoded'の場合、msg.payloadはクエリストリングに変換されてリクエストボディに付加されます。
それ以外のcontent-typeの場合は文字列に変換され、リクエストボディに付加します。content-tyoeが指定されておらず、msg.payloadがオブジェクトの場合は、content-typeに"application/json"が付加されます。
msg.paytoqs
GETメソッドの場合のmsg.payloadの扱いを指定します。設定しない場合、もしくはFalseの場合は無視されます。Trueもしくは文字列"query"の場合、msg.payloadはクエリストリングとして変換されURLに統合されます。文字列"body"の場合は、msg.payloadが文字列に変換され、リクエストボディに付加されます。
msg.rejectUnauthorized
SSL/TLSが必要なサイトへのアクセスは、通常はNode-REDが動作するホストに設定されたサーバ証明書でサーバ証明書を確認し、確認できない場合はコネクションエラーを返します。しかし、例えば開発用サイトなどでTLSサイト自己証明書を使っている場合などは、msg.rejectUnauthorizedをFalseに設定することで、証明書エラーを無視してアクセスすることができるようになります。
msg.followRedirects
HTTP リダイレクトは、サイトからのレスポンスに3xxのステータスコードがあった場合、サイトが指定する新たなURLにアクセスしなおす機能です。http requestノードは標準でリダイレクトに対応していますが、なんらかの理由でリダイレクト先にアクセスしない場合は、 msg.followRedirectsをFalseに設定することでリダイレクトを抑制することができます。
msg.requestTimeout
http requestのタイムアウトをミリ秒の整数で設定することができます。詳細は後述のタイムアウト設定の項目を参照してください。
msg.authType
認証タイプを指定します。文字列で basic/digest/bearer で指定します。
msg.credentials
認証情報を指定します。
msg.authTypeがbasic/digestの際には、msg.credentials.userにユーザ名、msg.credentials.passwordにパスワードを文字列で設定します。
msg.authTypeがbearerの際には、認証トークンを文字列でmsg.credentials.passwordに設定します。
4.4 出力オブジェクト仕様
http requestノードでリクエストを実行したのち、レスポンスはmsgオブジェクトに格納され出力されます。
msg.payload
http requestのレスポンスが格納されます。プロパティダイアログで設定した出力形式 によって、文字列、Buffer、オブジェクトで設定されます。
msg.statusCode
サーバが返したHTTPレスポンスコード が数値型で格納されます。
msg.headers
サーバが返したHTTPレスポンスヘッダ がオブジェクト形式で格納されます。含まれる情報は接続先のHTTPサーバの仕様によって異なります。「content-length」のようにパラメータにハイフンが入る場合は、msg.headers["content-type"]のように、配列の引数のを文字列で指定して取得します。
msg.responseUrl
レスポンスを返したサーバのURLが文字列で格納されます。リクエスト後にリダイレクトされた場合などに、プロパティダイアログのURL や、入力オブジェクトのmsg.url と異なるURLが返ることがあります。
msg.responseCookies
レスポンスがCookieを含む場合にオブジェクト形式で格納されます。Key:Value形式のオブジェクトです。
msg.redirectList
リクエストが複数回リダイレクトされることがあり、このプロパティに配列として格納されます。'location'ヘッダがリダイレクトされた先、'cookies'にリダイレクト元から返されたCookieが格納されます。
msg.retry
過去のNode-REDでは、なんらかの原因でhttp requestがリトライした場合の回数を返していたようですが、現在のNode-REDでは、msg.retryには必ず数値の0が入るようです。(互換性のために設定されていると思われます)
5. 知っておいた方がいいノウハウ
多段でhttp requestノードを使う場合
ひとつのフローで本ノードを複数回利用したいケースがあります。たとえばhttp requestのレスポンスを元に別のAPIにアクセスする場合などです。その際、最初のhttp requestノードが出力するmsg.headersプロパティは次のhttp requestの入力には使えません。
次のhttp requestまでにChangeノードで削除するか、空のオブジェクト{}を設定してから、必要に応じてmsg.headersプロパティを新たに設定する必要があります。
ファイルをアップロードする (multipart/form-data で POST)
ファイルアップロード一度のPOSTで複数の形式の情報を送信するケースで、RFC7578の「multipart/form-data」形式のデータを作成する必要があります。
Content-Typeでboundaryを作成して、msg.payloadをリクエストボディにしてマルチパート形式を作成することで送信は可能ですが、content-type: multipart/form-dataを指定した場合、msg.payloadに送信したい複数の情報を
{
"KEY": {
"value": FILE_CONTENTS,
"options": {
"filename": "FILENAME"
}
}
}
の形式でひとつ、ないし複数作成することで、必要なboundaryヘッダ等は自動で作成されます。
例えば、OpenAI社のSpeech to TextサービスWhisper 使う場合、オーディオデータを
curl --request POST \
--url https://api.openai.com/v1/audio/transcriptions \
--header 'Authorization: Bearer TOKEN' \
--header 'Content-Type: multipart/form-data' \
--form file=@/path/to/file/openai.mp3 \
--form model=whisper-1
の形式で送信する必要があります。
OpenAI社のトークンを環境変数OPENAI_API_KEYに設定、msg.payloadにWAV形式でオーディオデータが格納されている場合は、Changeノードで
のようにmsgオブジェクトを作成し、http requestノードを
のように使うことで、オーディオデータからテキストデータを得ることができます。
フォームにアクセスする (application/x-www-form-urlencoded で POST)
Webページ内のフォームの形式で複数の情報をPOSTする必要があるケースでは、フォームの中身をmsg.payloadにKey:Value形式で格納した上、msg.headers["content-type"]を"application/x-www-form-urlencoded"に設定します。
6. その他
タイムアウト設定
http requestノードでアクセスした後、アクセス先からのレスポンスに時間がかかる場合、以降のフローやほかのフローの実行に影響することがありますので、適切なタイムアウト時間を設定することが必要になります。標準では、Node-REDのsettings.jsのhttpRequestTimeoutパラメータに指定された120000ms(120秒)でタイムアウトしますが、msg.requestTimeoutプロパティでミリ秒の整数で指定することもできます。タイムアウトした場合はETIMEOUT例外となり、以降のフローは実行されませんが、Catchノードをつかってハンドリングすることができます。
内部実装
http requestノードはCoreノードのnetworkカテゴリで、
https://github.com/node-red/node-red/tree/master/packages/node_modules/%40node-red/nodes/core/network
でソースが公開されています。本稿はノードのヘルプ文書、および上記ソースより情報収集して作成しました。
リクエストにはGOT https://github.com/sindresorhus/got が使われており、node.js 標準のhttp モジュールなどより機能拡張されています。
7. おわりに
http request ノードは標準ノードの中でも、「詳細なドキュメントがなくても、なんとなく使えば機能する」という、Node-REDの特徴を示すいいノードだと考えます。本記事で全貌を明らかにしましたが、今後も新機能がたくさん追加されていくことを期待します。
みなさま、よきNode-REDライフを!