Skip to content
techird edited this page Apr 6, 2016 · 1 revision

Step5. 支持图片元数据更新

上一步:Step4. 列出所有上传的文件记录

本步骤完整源码在 workflow/step-5 分支上,提交记录为 cfe4704b

当客户端可以列出图片数据的时候,就可以根据图片记录的 ID 来更新元数据。同样是通过 MongoDB 进行操作。

我们客户端通过 POST JSON 的形式提交要修改的图片 ID 以及元数据,如:

{
    "id": "5702287c425194b13df1cacf",
    "meta": {
        "author": "techird",
        "labels": [
            "qq",
            "icon"
        ],
        "alt": "QQ Icon"
    }
}

那么 Express 接收到这个数据的时候,是不知道怎么去解析的。这时候我们需要添加 body-parser,来解析 JSON 类型的 Request Body。

npm install body-parser --save

修改 server.js,为其添加 body-parser 中间件。

// server.js
const bodyParser = require("body-parser");

// 注意放在所有路由前面
app.use(bodyParser.json());

现在,Express 可以解析 JSON 类型的报文了,我们添加一个路由来处理元数据的更改。

// server.js
app.use("/meta", require("./handle/meta"));

然后,创建 handle/meta.js 来处理该请求。

// handle/meta.js
'use strict';

const async = require("co");
const printer = require("../lib/printer");
const mongo = require("../lib/mongo");
const ObjectId = require("mongodb").ObjectId;

/**
 * 更新/添加元数据
 */
const meta = (request, response) => async (function * () {
    const print = printer(request, response);
    const body = request.body;
    const id = body.id;
    const meta = body.meta;
    
    // parameter checks
    if (!id) {
        print({ error: "Specific `id` to tell the server which image meta to update" });
        return;
    }
    if (!meta) {
        print({ error: "No meta specific" });
        return;
    }
    
    // connect to mongo db
    let db;
    try {
        db = yield mongo.connect();
    } catch (mongoError) {
        print({ mongoError });
        return;
    }
    
    // find and update
    try {
        const collection = db.collection("images");
        
        const query = { _id: ObjectId(id) };
        const update = { $set: { meta } };
        const result = yield collection.findOneAndUpdate(query, update);
        
        print({ result });
        
    } catch (error) {
        print({ error });
    } finally {
        db.close();
    }
});

module.exports = meta;

这里核心的代码只有几行:

const collection = db.collection("images");

const query = { _id: ObjectId(id) };
const update = { $set: { meta } };
const result = yield collection.findOneAndUpdate(query, update);

首先,创建一个用于定位要更新的文档的查询,然后定义更新的内容。使用 collection.findOneAndUpdate() 方法即可完成更新操作。需要注意的是,针对自动生成的 _id 字段,需要使用 ObjectId 来构造查询条件。

同步代码后,使用 Postman 来提交一个 /meta 请求,可以看到服务器返回元数据更新成功:

元数据更新成功

下一步:Step6. 添加分页支持和搜索到列表上