如何通过 Express Route 使用 Mongoose-Crate 存储文件

How to store a file with Mongoose-Crate via an Express Route

我正在使用 Node + Express 4 + MongoDB + Mongoose 构建 RESTful API。

我的 API 需要做的一件事是存储和检索文件。我将存储在 Amazon S3 中。 Mongoose 有一个特定的插件,用于将文件附加到 Mongo 名为 Mongoose-Crate, which in turn has a storage provider Mongoose-Crate-S3 的文档,该插件将文件上传到 S3。

我已尽最大努力将 Mongoose-Crate-S3 npm 页面中的示例代码改编为快速路由,但到目前为止我还没有成功上传图片到我的 S3 存储。我的 'file' 模型的文档正在我的 mongo 数据库中创建,但只有“_id”和“__v”字段。没有 'title',没有 'description',没有任何迹象表明 .post 端点实际上正在接收我尝试 post 的文件。我一直在对我的代码进行细微的调整,但我通常会在 "Could not get any response" 上得到一些变化。

这是我的 mongoose 架构 file.js(当然删除了我的 S4 凭据)

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var crate = require('mongoose-crate');
var S3 = require('mongoose-crate-s3');

var FileSchema = new Schema({
    title: String,
    description: String
});

FileSchema.plugin(crate, {
    storage: new S3({
        key: '<api-key-here>',
        secret: '<secret-here>',
        bucket: '<bucket-here>',
        acl: '<acl-here>', // defaults to public-read 
        region: '<region-here>', // defaults to us-standard 
        path: function(attachment) { // where the file is stored in the bucket - defaults to this function
            return '/' + path.basename(attachment.path)
        }
    }),
    fields: {
        file: {}
    }
});

module.exports = mongoose.model('File', FileSchema);

这里是我的 api 路由文件的相关片段。我相当确定我需要修复的代码在这里。

apiRouter.route('/files')

        .post(function(req, res){

            var file = new File()

            //.attach = function(field, attachment, callback)
            file.attach('image', req.body, function(error) {
                // file is now uploaded and post.file is populated e.g.:
                // post.file.url
            })

        })

        .get(function(req, res){
           //get a list of all files goes here
        });

我完全希望我遗漏了一些明显的东西,但是 MEAN 堆栈编程对我来说是新的,我已经搜索了 Whosebug 和整个网络以寻找更多示例或任何可以暗示我遗漏的东西。请帮忙!

首先,您应该设置您希望文件在 S3 上保存的位置路径,目前在该示例中它使用与原始文件相同的路径(可以是 /var/tmp/y7sday...C:/Users/SomeGuy/Pictures/..) 所以我们需要先解决这个问题。

在我的代码中,我使用的名称与他们提供的文件相同,在生产中,您可能希望按日期对这些文件进行排序并向其添加随机 uuid。 full example

FileSchema.plugin(crate, {
    storage: new S3({
        key: process.env.KEY,
        secret: process.env.SECRET,
        bucket: process.env.BUCKET,
        acl: 'public-read', // defaults to public-read
        region: 'eu-west-1', // defaults to us-standard
        path: function(attachment) { // where the file is stored in the bucket - defaults to this function
            return '/' + attachment.name
        }
    }),
    fields: {
        file: {}
    }
});

接下来,在您的 API 端点中,您想要在正文中包含任何表单信息并将这些信息添加到对象中,这些将位于 req.body 部分。

这里要注意的最重要的事情是我已将附件设置为 file,这需要与您在 mongoose 模式中声明的字段相匹配,否则它将消失。

接下来包括 req.files.file 作为第二个参数。 full example

exports.create = function (req, res) {
    var file = new File();
    file.title = req.body.title;
    file.description = req.body.description;
    file.attach('file', req.files.file, function (error) {
        if (error) {
            return res.send(error);
        } else {
            return res.send(file);
        }
    });
};

我已经将我的作品上传到 GitHub,所以请克隆它并尝试一下。

你需要做的就是POST到/file/

{
    "description": "My Description",
    "title": "My Title",
    "file": {
        "url": "https://mysecretbucket.s3-eu-west-1.amazonaws.com/bb4bf9f69bf41ab478824d80a338beb6.png",
        "type": "image/png",
        "name": "bb4bf9f69bf41ab478824d80a338beb6.png",
        "size": 8912
    },
    "_id": "553e8ed8282cc30000000001"
}

确保将表单中的字段设置为 file,如下图所示