method-override
はルーティングの前に読み込む
ExpressでHTMLフォームからPUT, DELETEを発行したい場合、
method-override パッケージを使用するのが一般的です。
が、一向にPUTが呼ばれなくてかなりハマったのでメモしておきます。
結論としてはタイトルの通り、method-override
の読み込みはルーティングの前に書きましょう。
これで動作するようになりました。
app.js
const methodOverride = require("method-override");
const routes = require("./presentation/routes");
app.use(methodOverride("_method")); // <= !!! ルーティングの前に書く !!!
app.use("/", routes); // ルーティングの定義
まあ、SPAとかになればAjax通信すると思うので、HTMLフォームから呼びたいケースは少なくなっていくと思いますが。。。
補足
一応気が付いたきっかけをメモっておきます。(解釈が間違ってたらすみません)
method-override
の公式に書いてある、
app.use(methodOverride((req: Request, res: Response) => {
if (req.body && typeof req.body === "object" && "_method" in req.body) {
// look in urlencoded POST bodies and delete it
const method = req.body._method;
delete req.body._method;
return method;
}
}));
にブレイクポイントを張ってステップ実行していると以下に辿り着きます。
node_modules/method-override/index.js
// replace
if (method !== undefined && supports(method)) {
req.method = method.toUpperCase()
debug('override %s as %s', req.originalMethod, req.method)
}
next()
結局method
を置き換えてnext()
を呼んでるんだから先に読み込まないとだな、と思った次第でした。
根本的にはパッケージ(というかミドルウェア)の読み込み順に気をつけようという話にもなるかと思います。