Redux(react-redux)における適切な配列要素の更新
2021年8月23日…
本ブログ初の技術ネタ。こちらの記事でも宣言しているように、普段Node.jsを使ってWebサービスの開発をしている。Node.jsのWebアプリケーションフレームワークには、
Express
を使用している。Expressの魅力というか、メリットは、やはりNode.js界隈でいうとわりと昔から開発されていて、他のNode.jsのWebアプリケーションフレームワークよりも安定性がある程度期待できること、あとはExpress用のミドルウェアの充実、特に周辺環境が活発に整備されていることだろう。少し古めの記事ではあるが、Node.js関連のWebアプリケーションフレームワークの盛り上がり具合でいうと、この記事が分かりやすい。
2014年 Webアプリケーションフレームワークトレンド(Node.js) – Qiita
上記の記事で分かるように、他フレームワークと比較しても知見が多そうなことも、Expressを選ぶ要因と成り得る。ちなみに、この記事の時点(2015年6月20日)でトップのMeteorはGitHubでのスター数25,990、Expressは19,502、Sailsは11,035であって、順位的には変動ナシといった具合だ。じゃあ、スター数で見てMeteorでいいじゃん、という方は待ってほしい。Expressはフルスタックのフレームワークではないのに対して、Meteorはフルスタックのフレームワークである。ちなみに、Sailsもフルスタックのフレームワークで、Railsの思想に影響を受けているようだ。これは個人的な主張なので流してもらってまったく構わないが、Node.jsなノリを存分に体験したいのなら、フレームワークはExpressでいいと思う。Sailsは内部にExpressを組み込んでいるそうだし、ExpressはNode.jsのWebアプリケーションフレームワークの中では特に長く開発されてきたし、安定性も優れたものなのだ。
というわけで、本題。お膳立ては終了。ここからは普通に本題のExpressでPOSTによる値の取得でハマった件について、最近のNode.js関連のことで一番ハマったので、書いておく。Expressやってる人がPOSTで値を受け取る場合、まずbody-parserミドルウェアというものを使うということを知り、その設定をしに取り掛かる。だが、ここで問題が起こる。Node.js関連のことをWebでちまちま調べているときによく起こりがちだが、そのバージョンでは設定の仕方が違いますということだ。近いバージョンなので、似たようなこと書けば通るだろう、と思って記述したコードも、どうにも通らない。
例えば、Google検索で「express4 req.body undefined」という具合に調べてみても、なかなかバチっと答えが決まらないわけである。とりあえず、こんなんかな?みたいなようなことを4時間もGoogle先生に聞くことを繰り返してしまった…。
というわけで結論、最強はやはりミドルウェアの公式ページである。
最新のバージョンのOSSの使い方は、公式に行け!である。本当にこれは新しいOSSを追う上で重要な行動だと思った。たとえば、僕がハマったbodyParserでの値の取得のコードはこうだ。
var express = require('express’); var bodyParser = require('body-parser')var app = express(); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); app.post(‘/', function(req,res,next){ console.log(req.body); }); var server = app.listen(3000, function () { console.log('Server starting.'); });
どうしてこうなったかというと、「 body-parserの値ってreq.bodyに入ってるんだぜ!urlencodedで設定しないとダメよ」…と多くで解説されていたからずーっとこう書いてみていたが、一見合っているようで間違っている。この状態で、プログラムを実行していくと、console.log(req.body)の箇所でエラーで終了してしまうundefindedと出力され、意図する値が取得できない。body-parserの公式を参照した結果、実際には、Express4.1系での最新のbody-parserの使い方はこうだった。
var express = require('express’); var bodyParser = require('body-parser')var app = express(); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); app.post(‘/', function(req,res,next){ res.setHeader('Content-Type', 'text/plain'); console.log(req.body); }); var server = app.listen(3000, function () { console.log('Server starting.'); });
不正解コードとの違いは、
res.setHeader('Content-Type', 'text/plain');
の1行だけである。自分はHTTP通信とかTCP/IPはあまり勉強していないので、浅はかなコメントになるが、見た感じ送られてきた情報に対し、ヘッダー情報を付与してはじめてExpressが扱えるような状態になっているのだろう。
これは、Node.jsの公式ドキュメントによると、この命令はこうだ。
HTTP Node.js v0.12.6 Manual & Documentation
https://nodejs.org/api/http.html#http_response_setheader_name_value
というわけで、間違ったこと書いてんじゃねーwとツッコミを入れてくれたPipesh代表山田さんありがとうございます。ドキュメントを確認したところ、リクエストに対して返す情報のヘッダーはtaxt/plainの形式にして’Content-Type’, ‘text/plain’にしてください、そのままおっしゃる通りでした。
これはハマった、本当にハマった。僕みたいな愚かなことを繰り返さないように、このエントリーがExpress4.1にてbody-parserでやはりundefinedが出てしまった方を助けになることを祈っている。そして、自分のようにOSSの最新の正しい情報は、公式に行くというのが最強の方法ことを学習し、トラブルにかける労力が少しでも減ることを祈っている。
プログラムを書きながらTranceを聴くのが良いですね。みなさんも聴いたほうがいいですよ、Trance。EDMよりハードトランスでしょ。
Discussion about this post