【问题标题】:POST collection of objects in json-serverPOST json-server 中的对象集合
【发布时间】:2020-01-12 01:52:27
【问题描述】:

我正在使用 json-server 为前端团队伪造 Api。

我们希望有一个功能可以在一次调用中创建多个对象(例如产品)。

在 WebApi2 或实际的 RestApis 中,可以这样完成:

POST api/products //For Single Creation
POST api/productCollections  //For Multiple Creation

我不知道如何使用 json-server 来实现它。我尝试使用邮递员将以下数据发布到api/products,但它不会拆分数组并单独创建项目。

[
    {
        "id": "ff00feb6-b1f7-4bb0-b09c-7b88d984625d",
        "code": "MM",
        "name": "Product 2"
    },
    {
        "id": "1f4492ab-85eb-4b2f-897a-a2a2b69b43a5",
        "code": "MK",
        "name": "Product 3"
    }
]

它将整个数组视为单个项目并附加到现有的json。

您能否建议我如何在 json-server 中模拟批量插入?还是 Restful Api 应该始终用于单个对象操作?

【问题讨论】:

    标签: rest json-server


    【解决方案1】:

    据我所知,这不是 json-server 原生支持的,但可以通过变通方法来完成。

    我假设你对 node.js 有一些先验知识

    您必须创建一个 server.js 文件,然后您将使用 node.js 运行该文件。 server.js 文件将使用 json-server 模块。

    我已将 server.js 文件的代码包含在下面的代码 sn-p 中。

    我使用 lodash 进行重复检查。因此,您将需要安装 lodash。如果您不想使用 lodash,也可以将其替换为您自己的代码,但在我看来 lodash 效果很好。

    server.js 文件包含一个自定义发布请求函数,该函数访问 json-server 实例中使用的 lowdb 实例。检查来自 POST 请求的数据是否重复,并且仅将新记录添加到 ID 尚不存在的数据库中。 lowdb 的 write() 函数将数据持久化到 db.json 文件中。因此,内存中的数据和文件中的数据将始终匹配。

    请注意,json-server 生成的 API 端点(或重写的端点)仍然存在。因此,您可以将自定义函数与默认端点结合使用。

    在需要的地方随意添加错误处理。

    const jsonServer = require('json-server');
    const server = jsonServer.create();
    const _ = require('lodash')
    const router = jsonServer.router('./db.json');
    const middlewares = jsonServer.defaults();
    const port = process.env.PORT || 3000;
        
    server.use(middlewares);
    server.use(jsonServer.bodyParser)
    server.use(jsonServer.rewriter({
        '/api/products': '/products'
    }));
        
    server.post('/api/productcollection', (req, res) => {
        const db = router.db; // Assign the lowdb instance
        
        if (Array.isArray(req.body)) {
            req.body.forEach(element => {
                insert(db, 'products', element); // Add a post
            });
        }
        else {
            insert(db, 'products', req.body); // Add a post
        }
        res.sendStatus(200)
        
        /**
         * Checks whether the id of the new data already exists in the DB
         * @param {*} db - DB object
         * @param {String} collection - Name of the array / collection in the DB / JSON file
         * @param {*} data - New record
         */
        function insert(db, collection, data) {
            const table = db.get(collection);
            if (_.isEmpty(table.find(data).value())) {
                table.push(data).write();
            }
        }
    });
        
    server.use(router);
    server.listen(port);
    

    如果您有任何问题,请随时提出。

    【讨论】:

    • 谢谢。我想知道在写入 db.json 之后如何刷新数据。目前,新数据在 db.json 中发生了变化。但它不会影响现有的内存数据库,它始终保留以前的 db.json。
    • 感谢您的评论。我现在已经更正了我的答案,以更好地解决您面临的问题。我的答案中的新代码会将记录添加到 lowdb 实例并保存到 db.json 文件中。
    • 谢谢阮。我想知道你怎么知道可以调用db.get 来获取内存中的现有集合。我在 json-server 文档中根本找不到它。或者我可能忽略了。
    • 我实际上在 npm 站点上的 json-server page 上发现它使用 lowdb 来保存对 db.json 文件的所有更改。那时我意识到我只需要通过 lowdb 工作。然后我在 github 存储库的lowdb readme 中阅读了如何使用 lowdb。 json-server 文档肯定会更详细。
    【解决方案2】:

    标记为正确的答案实际上对我不起作用。由于 insert 函数的编写方式,它总是会生成新文档而不是更新现有文档。 “重写”对我也不起作用(也许我做错了什么),但创建一个完全独立的端点会有所帮助。

    这是我的代码,以防它帮助其他人尝试进行批量插入(以及修改现有数据(如果存在))。

    const jsonServer = require('json-server');
    const server = jsonServer.create()
    const _ = require('lodash');
    const router = jsonServer.router('./db.json');
    const middlewares = jsonServer.defaults()
    
    server.use(middlewares)
    server.use(jsonServer.bodyParser)
    
    
    server.post('/addtasks', (req, res) => {
        const db = router.db; // Assign the lowdb instance
        if (Array.isArray(req.body)) {
            req.body.forEach(element => {
                insert(db, 'tasks', element);
            });
        }
        else {
            insert(db, 'tasks', req.body);
        }
        res.sendStatus(200)
    
        function insert(db, collection, data) {
            const table = db.get(collection);
    
            // Create a new doc if this ID does not exist
            if (_.isEmpty(table.find({_id: data._id}).value())) {
                table.push(data).write();
            }
            else{
                // Update the existing data
                table.find({_id: data._id})
                .assign(_.omit(data, ['_id']))
                .write();
            }
        }
    });
    
    server.use(router)
    server.listen(3100, () => {
      console.log('JSON Server is running')
    })
    

    在前端,调用将如下所示: axios.post('http://localhost:3100/addtasks', tasks)

    【讨论】:

      【解决方案3】:

      在发布此问题时可能无法正常工作,但现在可以使用/products 端点上的数组进行批量插入。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多