【Node.js】WebAPIを受け取ってみる。
こんばんは葛の葉です。
さて、簡単なWebAPIを作成し、Javascriptで値を受け取るようにしてみます。
pythonでWebAPIをつくる
# app.py from flask import Flask, request, jsonify app = Flask(__name__) @app.route('/') def index(): data = { 'status': 'ok', 'message': 'Hello' } return jsonify(data) @app.route('/test') def test(): if request.args.get('name'): name = request.args.get('name') else: name = 'Nanashi' data = { 'status': 'ok', 'message': f'Hello! {name}! How are you?' } return jsonify(data)
flaskについては当ブログでも結構扱ってきたから、あんまり説明しなくてもよいかな、と思っています。jsonify
は引数で受け取った辞書型をJSONに変換し、さらにHttpレスポンスのContent-Typeをapplication/json
にしてくれるものです。上記のPythonプログラムをapp.py
として作成し、flask run
とコマンドを叩いて実行すると以下のようになります。
$ flask run * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: off * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
別のターミナルを開いてcurl
を使ってレスポンスを受け取ってみます。
// ルート直下へGetリクエスト $ curl http://127.0.0.1:5000 {"message":"Hello","status":"ok"} // テストルートへGetリクエストで、パラメータなし $ curl -G "http://127.0.0.1:5000/test" {"message":"Hello! Nanashi! How are you?","status":"ok"} // テストルートへGetリクエストで、パラメータあり $ curl -G "http://127.0.0.1:5000/test?name=kuzunoha" {"message":"Hello! kuzunoha! How are you?","status":"ok"} $ curl -G "http://127.0.0.1:5000/test?name=albatross" {"message":"Hello! albatross! How are you?","status":"ok"} $ curl -G "http://127.0.0.1:5000/test?name=" {"message":"Hello! Nanashi! How are you?","status":"ok"}
とまぁこんな感じで簡素なWebAPIが作れました。
Nodeのaxiosというモジュールをつかう
Node.Jsにはaxios
というHttpリクエストを投げて受け取るモジュールがあります。ご多分の通り、Node.jsは非同期I/Oなので、普通にリクエストを投げるとレスポンスが帰ってくる前に次のコードが実行されちゃいます。そこでPromiseというオブジェクトを用いることがあるわけですが、このaxios
はHttpRequestをPromiseベースで実行してくれるモジュールになります。
使い方はこんな感じ。(typescriptです)
// webapp.ts import axios from "axios"; axios.get('http://localhost:5000/') .then(function(response) { console.log(response.data); }).catch(function(error){ console.log(error) })
axios.get(URL)
は見ての通りgetメソッドでURLを取得しにいっています。さて、.then
というPromiseオブジェクトっぽいのが出てきました。
axios.get(URL).then(コールバック関数1).catch(コールバック関数2)
axios.get()
が正常に終了したとき.then
内のコールバック関数1が実行されます。このときの引数をrespose
としていますが、axios
が受け取ってきたHttpResponseになります。axios.get()
が失敗した際はそのerrorを.catch
内のコールバック関数2に渡し、実行します。
コンパイルすると以下の感じ。
"use strict"; exports.__esModule = true; var axios_1 = require("axios"); axios_1["default"].get('http://localhost:5000/') .then(function (response) { console.log(response.data); })["catch"](function (error) { console.log(error); });
コンパイルされたwebapp.js
をnodeで実行すると以下のようになります。
$ node webapp.js { message: 'Hello', status: 'ok' }
webapp.tsの3行目をaxios.get('http://localhost:4000/')
にしてコンパイルして実行すると、そのポートにWepアプリがなければエラーが返ります。
$ node webapp.js { Error: connect ECONNREFUSED 127.0.0.1:4000 at Object._errnoException (util.js:1022:11) at _exceptionWithHostPort (util.js:1044:20) at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1198:14) code: 'ECONNREFUSED', errno: 'ECONNREFUSED', syscall: 'connect', address: '127.0.0.1', port: 4000, config: { url: 'http://localhost:4000/', method: 'get', (以下省略)
getメソッドのパラメータを渡すことも可能です。
// webapp.ts import axios from "axios"; axios.get('http://localhost:5000/test', { params:{ name: "kuzunoha" } }) .then(function(response) { console.log(response.data); }).catch(function(error){ console.log(error) })
Nodeで実行すれば以下のように。
$ tsc webapp.ts $ node webapp.js { message: 'Hello! kuzunoha! How are you?', status: 'ok' }
expressで表示してみる
webapp.tsにexpressで表示してあげればもっとわかりやすくなる。
// webapp.ts import axios from "axios"; import * as express from "express"; let app = express(); app.get('/', (req, res)=>{ axios.get('http://localhost:5000/test', { params:{ name: "kuzunoha" } }) .then(function(response) { const ret = response.data; res.send(ret.message); }).catch(function(error){ console.log(error) }) }) app.listen('3000', function(){ console.log('listen port:3000') })
ExpressとはWebフレームワークになります。Expressのインスタンスをapp
としています。
tsc webapp.ts
-> node webapp.js
として実行してみてください。
$ tsc webapp.ts $ node webapp.js listen port:3000
http:127.0.0.1:3000/にアクセスすると以下のようになります。
app.get(文字列, コールバック関数)
は文字列でアクセスするとコールバック関数が実行されるというものです。アクセスが正常であればコールバック関数に受け取ったHttpRequestとこれからクライアントに返すResponseが引数に渡されます。http://127.0.0.1:3000にアクセスしたタイミングで、axios.get()
以下が実行されます。
axios
はpythonのflask
アプリケーションに飛んで、情報を取得してきます。その取得してきた情報をhttp://127.0.0.1:3000にアクセスしたクライアントに返しています。
とこのようにすることで、Javascriptは表示に専門、Pythonは内部処理に専門、と分けることができるのです。