Next.JS の API Route でのフォーム読み込み
Next.JS の API Route 機能におけるフォームの解析処理である bodyParser は multipart に対応していないようだ、、、
req.body に生のリクエストボディが入っているだけ、、、
なので formidable を利用してリクエストボディを解析してみる
$ yarn add fomidable @types/fomidable
以下、TypeScript で
api/sample.ts
import type { NextApiRequest, NextApiResponse } from 'next'
import formidable from 'formidable'
// Next.JS の bodyParser を無効化するのを忘れずに
export const config = {
api : {
bodyParser : false
}
}
// 受信 API の処理
export const Sample = async ( req : NextApiRequest, res : NextApiResponse ) => {
try {
// POST 以外ならエラー
if ( req.method !== 'POST' ) {
throw new Error( `Invalid method [ ${ req.method } ]` )
}
// formidable を利用して multipart リクエストボディを解析する
// /tmp/sample にアップロードされる (前もってディレクトリは作成しておく)
const form = new formidable.IncomingForm( { uploadDir : '/tmp/smple' } )
// リクエストボディのパースが完了するのを待って、結果を { files, fields } で受け取る
const { files, fields } = await new Promise<{ files : formidable.Files, fields : formidable.Fields }>(
( resolve, reject ) => {
// リクエストボディのパースをする
form.parse( req, ( error, fields, files ) => {
// エラーなら reject する
if ( error ) reject( error )
// 得られたリクエストボディの内容を返して resolve する
resolve( { files, fields } )
} )
}
)
// files には file 属性でアップロードされたファイルがフォームの name で指定したプロパティに格納される
const file = files.<name> as formidable.File // ファイルの情報が得られる
const path = file.filepath // 格納先ファイルパスが得られる
const name = file.originalFileame // 元のファイル名が得られる
const mime = file.mimetype // ファイル名の形式が得られる
// fields には、file 以外のフォームの name で指定したプロパティにパラメータと値が入る
const value = fields.<name> // 値が得られる
} catch ( error ) {
// エラーの時は 500 で返す
res.status( 500 ).json( { message : error.message } )
return
}
// 正常終了
res.status( 200 ).json( {} )
return
}
なんてことないことなのだが、気が付かないと調べても Express 関係の記事が多くて
時間がかかってしまったので
ちょっと記録として
なお、格納したファイルは fs.rm() するのを忘れずに、、、