使用Vapor3将多个记录插入数据库

时间:2018-09-17 13:47:57

标签: arrays json record vapor

我希望能够将记录批量添加到Vapor 3中的nosql数据库中。

这是我的结构。

struct Country: Content {

   let countryName: String
   let timezone: String
   let defaultPickupLocation: String

}

因此,我尝试传递一个JSON对象数组,但不确定如何构造路由,也不确定如何访问该数组以解码每个对象。

我尝试过此路线:

    let countryGroup = router.grouped("api/country")

    countryGroup.post([Country.self], at:"bulk", use: bulkAddCountries)

具有以下功能:

 func bulkAddCountries(req: Request, countries:[Country]) throws ->  Future<String> {
    for country in countries{
    return try req.content.decode(Country.self).map(to: String.self) { countries in



        //creates a JSON encoder to encode the JSON data
        let encoder = JSONEncoder()
        let countryData:Data
        do{
            countryData = try encoder.encode(country) // encode the data
        } catch {
            return "Error. Data in the wrong format."
        }
        // code to save data
    }
    }
}

那么,我该如何构造“路线”和功能以获取对每个国家/地区的访问权限?

2 个答案:

答案 0 :(得分:3)

我不确定您打算使用哪个NoSQL数据库,但是MongoKitten 5和Meow 2.0的当前beta版本使此操作非常容易。

请注意,当我们首先使用稳定的API时,我们如何还没有为这两个库编写文档。以下代码大致是MongoKitten 5所需的代码:

// Register MongoKitten to Vapor's Services
services.register(Future<MongoKitten.Database>.self) { container in
    return try MongoKitten.Database.connect(settings: ConnectionSettings("mongodb://localhost/my-db"), on: container.eventLoop)
}

// Globally, add this so that the above code can register MongoKitten to Vapor's Services
extension Future: Service where T == MongoKitten.Database {}

// An adaptation of your function
func bulkAddCountries(req: Request, countries:[Country]) throws ->  Future<Response> {
    // Get a handle to MongoDB
    let database = req.make(Future<MongoKitten.Database>.self)

    // Make a `Document` for each Country
    let documents = try countries.map { country in
        return try BSONEncoder().encode(country)
    }

    // Insert the countries to the "countries" MongoDB collection
    return database["countries"].insert(documents: documents).map { success in
        return // Return a successful response
    }
}

答案 1 :(得分:0)

我也有类似的需求,并想分享我的解决方案,以便在蒸气中进行批量处理。3.我希望有另一个经验丰富的开发人员来帮助我完善解决方案。

我将尽力解释自己的所作所为。而且我可能错了。

首先,路由器中没有什么特别的。在这里,我正在处理items/batch的POST,以获取商品的JSON数组。

router.post("items", "batch", use: itemsController.handleBatch)

然后是控制器的处理程序

func createBatch(_ req: Request) throws -> Future<HTTPStatus> {
    // Decode request to [Item]
    return try req.content.decode([Item].self)
        // flatMap will collapse Future<Future<HTTPStatus>> to [Future<HTTPStatus>]
        .flatMap(to: HTTPStatus.self) { items in
        // Handle each item as 'itm'. Transforming itm to Future<HTTPStatus>
        return items.map { itm -> Future<HTTPStatus> in
            // Process itm. Here, I save, producing a Future<Item> called savedItem
            let savedItem = itm.save(on: req)
            // transform the Future<Item> to Future<HTTPStatus>
            return savedItem.transform(to: HTTPStatus.ok)
        }
        // flatten() : “Flattens an array of futures into a future with an array of results”
        // e.g. [Future<HTTPStatus>] -> Future<[HTTPStatus]>
        .flatten(on: req)
        // transform() : Maps the current future to contain the new type. Errors are carried over, successful (expected) results are transformed into the given instance.
        // e.g. Future<[.ok]> -> Future<.ok>
        .transform(to: HTTPStatus.ok)
    }
}