やりたいこと
- multer, ibm-cos-sdk, multer-s3を使用して、multipart/form-dataで受け付けたファイルをIBM CloudのObject Storageにアップロードする。
- 参考:https://github.com/IBM/cos-web-gallery/blob/master/src/controllers/galleryController.js
- 備忘録
前提条件
- Node.js...10.16.0
- multer...1.4.2
- multer-s3...2.9.0
- ibm-cos-sdk...1.5.4
- IBM Cloud Object Storage・Bucket作成ずみ
パッケージのインストール
npm install --save multer multer-s3 ibm-cos-sdk
upload.controller.js
const multer = require('multer');
const config = require('config');
const aws = require('ibm-cos-sdk');
const multerS3 = require('multer-s3');
const ep = new aws.Endpoint(config.objectStorage.endpoints);
const s3 = new aws.S3({ endpoint: ep, region: 'us-south', apiKeyId: config.objectStorage.apikey });
const bucket = config.objectStorage.iam_apikey_name;
const upload = multer({
storage: multerS3({
s3: s3,
bucket: bucket,
acl: 'public-read',
key: function(req, file, cb) {
cb(null, `${new Date().getTime()}_${file.originalname}`);
}
})
});
exports.upload = upload;
config/development.json
"objectStorage": {
"apikey": "自分のAPI KEY",
"endpoints": "https://s3.{自分のregionのprefix}.cloud-object-storage.appdomain.cloud",
"iam_apikey_name": "自分のバケットの名前"
}
uploader.controller.js
const uploadImage = async (req, res, next) => {
// ファイルのURLはfiles[index].locationに保存される
const imagePathList = req.files.map((file) => file.location);
const list = JSON.parse(req.body.list);
const result = await db.update(); // あとはDBの更新なり行ってください。
res.json(result);
};
exports.uploadImage = uploadImage;
uploader.route.js
const express = require('express');
const { upload } = require('./upload.controller');
const { uploadImage } = require('./uploader.controller');
/* eslint new-cap: 0 */
const router = express.Router();
router.route('/upload')
// upload.array('photos', 10)で10枚まで同時アップロード可能
.post(upload.array('photos', 10), updateCarStatusWithImage)
テストコード(mocha+chai+supter test)
it('should upload multi image file', async () => {
const result = await request(app)
.post(`/upload`)
.attach('photos', path.join(__dirname, 'images', 'image1.jpg'))
.attach('photos', path.join(__dirname, 'images', 'image2.jpg'))
.attach('photos', path.join(__dirname, 'images', 'image3.jpg'))
.attach('photos', path.join(__dirname, 'images', 'image4.jpg'))
// req.body.listとして送信したい情報がある場合
.field('list', JSON.stringify(['one', 'two', 'three']))
.expect(200);
should.exist(result.body);
});