本稿では、POSTで送信されたフォームの内容を、Koaのハンドラーで取得する方法を紹介する。
Koa単体ではPOST Bodyは解釈できない
Koa単体では、POSTされたBodyを解釈することができない。
Bodyをパースしてオブジェクトにするには、koaとは別途koa-bodyをインストールする必要がある。
yarn add koa-body
ちなみに、koa-bodyパッケージにはTypeScriptの型情報が同梱されているので、@types
から型情報を入れる必要がない。というか、そもそも@types/koa-body
というパッケージはない。
koa-bodyの使い方
1) koa-body
からkoaBody
をimportする。
import koaBody from "koa-body"
2) POSTデータを処理するハンドラーより先に、koaBody()
をミドルウェアとして差し込む。
import Koa from "koa"
import koaBody from "koa-body"
const app = new Koa()
app.use(koaBody())
app.use(ctx => {
ctx.body = JSON.stringify(ctx.request.body)
})
app.listen(4000)
実行例
POSTリクエスト
POST / HTTP/1.1
Content-Length: 11
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: localhost:4000
foo=1&bar=2
レスポンス
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 21
Content-Type: text/plain; charset=utf-8
Date: Mon, 02 Sep 2019 07:15:59 GMT
{
"bar": "2",
"foo": "1"
}
koa-routerと組み合わせて使う
上記のコードでは、すべてのURLに対してPOST Bodyのパースが走ってしまう。特定のURLパスだけパースするには、koa-bodyだけではできないので、koa-routerなどのルーティングライブラリと組み合わせる必要がある。
import Koa from "koa"
import koaBody from "koa-body"
import Router from "koa-router"
const app = new Koa()
const router = new Router()
router.post('/', koaBody(), async ctx => {
ctx.body = JSON.stringify(ctx.request.body)
})
app.use(router.routes())
app.listen(4000, () => process.stdout.write('Web server started at port 4000\n'))
koa-routerの場合、router.post(url, middleware, middleware)
といった具合に、ミドルウェアを複数指定できるAPIになっている。したがって、koaBody()
を1つ目の引数に、POSTデータを扱うミドルウェア(=ハンドラ)を2つ目の引数にすることで、次の流れが特定のURLだけで発生するようになる。
- まず、Bodyのパースがされ、
ctx.request.body
に値がセットされる。 - 次に、
ctx.request.body
の値を使って何らかの処理をする。