LoginSignup
3
2

More than 1 year has passed since last update.

Next.JS の API Route でのファイルアップロード受信処理

Last updated at Posted at 2022-12-07

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() するのを忘れずに、、、

3
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2