2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Next.js (typescript) で S3 にファイルをアップロードする API を作る

Posted at

色々面倒だった

React.js で画像をアップロードしたかったが、S3 のクレデンシャル情報は隠匿したかったので、アップロード自体は、サーバサイド(API)で行った。

やってみたら結構面倒臭かった。

環境

  • React.js: 18.0.0
  • Next.js: 12.1.6
  • formidable: 2.0.1

React.js 側は axios で Next.js で実装した API を呼ぶ。
Next.js 側で受け取ってたら S3 にアップロードする。

React 側

まず、File タイプを POST する場合、"Content-Type": "multipart/form-data" でないと送れない。json 形式だと送れない。

例えば、リクエストパラメータとして、file: File, type: string を送りたい場合、

axios.post('/api/upload', {
    file: somefile,
    path: 'dir/'
  }, {
    headers: {
      'Content-Type': 'multipart/form-data',
    }
  });

などとしても送れそうだけど、送れない。FormData に append して送る。

const params = new FormData();
params.append('file', somefile);
params.append('path', 'dir/');
axios.post('/api/upload', 
    params,
  {
    headers: {
      'Content-Type': 'multipart/form-data',
    }
  }

Next 側

にあるように、まず、

export const config = {
  api: {
    bodyParser: false,
  },
};

こうしてあげる必要がある。
なお、s3 にアップロードするのに必要な package は、aws-sdk, formidable, fs なので、@type/aws-sdk, @types/formidable と共にインストールしておく。

const form = formidable();
form.parse(req, async (err, fields, files: any) => {
  if (...) {
    // 必要なエラー処理
  }
  try {
    // S3 にアップロードする処理
  } catch (err) {
    // S3 アップロードに失敗した時の処理
  }
}

流れはこんな感じ。

React 側で送った file と path を POST しているが、file は、files.file に、FILE タイプ以外の path は、fields.path に入る。file を hoge で送れば、files.hoge。

S3 に put する Body は、fs で。

s3.putObject({
  ACL: 'public-read',
  Bucket: process.env.S3_BUCKET,
  Key: `${fields.path}${files.file.originalFilename}`,
  ContentType: files.file.minetype,
  Body: fs.createReadStream(files.file.filepath),
});

files: any などとしておかないと、formidable の originalFilename とか filepath などのプロパティにアクセスしようとした時 Type Error になる。取得できるけど、build できない。any じゃなくて、厳密に files: formidable.Files としたいところだが、うまくいかない。

なお、File をアップロードするだけの API であれば、response は 201 が良いかと。

おしまい。

2
1
0

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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?