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

met*_*lin 2 amazon-s3 mongoose mongodb node.js express

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

我的API需要做的一件事是存储和检索文件.我将存储在Amazon S3中.Mongoose有一个特定的插件,用于将文件附加到称为Mongoose-Crate的 Mongo文档,后者又有一个存储提供程序Mongoose-Crate-S3,它将文件上传到S3.

我已尽力调整Mongoose-Crate-S3 npm页面中的示例代码作为快速路由,但到目前为止我还没有成功上传到S3存储的映像.我的'文件'模型的文档正在我的mongo数据库中创建,但是只有'_id'和'__v'字段.没有"标题",没有"描述",没有任何迹象表明.post端点实际上正在接收我尝试发布的文件.我一直在对我的代码进行微调,但我通常会对"无法获得任何响应"进行一些修改.

这是我的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);
Run Code Online (Sandbox Code Playgroud)

这是我的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
        });
Run Code Online (Sandbox Code Playgroud)

我完全相信我错过了一些明显的东西,但MEAN堆栈编程对我来说是新的,我已经搜索了stackoverflow和网络,寻找更多的例子或任何暗示我缺少的东西.请帮忙!

Ed *_*les 6

首先,您应该设置您希望在S3上保存文件的位置路径,当前在该示例中,它使用与原始文件相同的路径(可能是/var/tmp/y7sday...C:/Users/SomeGuy/Pictures/..),因此我们需要先将其排序.

在我的代码中,我使用与他们提供的文件相同的名称,在生产中,您可能希望按日期对这些进行排序,并为它们添加随机uuid.完整的例子

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: {}
    }
});
Run Code Online (Sandbox Code Playgroud)

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

这里要注意的最重要的事情是我将附件设置为file,这需要匹配您在mongoose模式中声明的字段,否则它将会死亡.

接下来包括req.files.file作为第二个参数.完整的例子

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);
        }
    });
};
Run Code Online (Sandbox Code Playgroud)

我已将我的工作上传到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"
}
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述