使用 Vapor3 将多条记录插入数据库
Insert multiple records into database with Vapor3
我希望能够在 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
}
}
}
那么我该如何构造路由和函数来访问每个国家?
我不确定您打算使用哪个 NoSQL 数据库,但 MongoKitten 5 和 Meow 2.0 的当前测试版让这变得非常简单。
请注意,在我们首先推出稳定版 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
}
}
我有类似的需求,想分享我的 Vapor 批量处理解决方案 3. 我希望有另一位经验丰富的开发人员帮助完善我的解决方案。
我会尽力解释我所做的事情。我可能错了。
首先,路由器 没有什么特别之处。在这里,我正在处理 POST 到 items/batch
的 JSON 项数组。
router.post("items", "batch", use: itemsController.handleBatch)
然后是controller的handler.
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)
}
}
我希望能够在 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
}
}
}
那么我该如何构造路由和函数来访问每个国家?
我不确定您打算使用哪个 NoSQL 数据库,但 MongoKitten 5 和 Meow 2.0 的当前测试版让这变得非常简单。
请注意,在我们首先推出稳定版 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
}
}
我有类似的需求,想分享我的 Vapor 批量处理解决方案 3. 我希望有另一位经验丰富的开发人员帮助完善我的解决方案。
我会尽力解释我所做的事情。我可能错了。
首先,路由器 没有什么特别之处。在这里,我正在处理 POST 到 items/batch
的 JSON 项数组。
router.post("items", "batch", use: itemsController.handleBatch)
然后是controller的handler.
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)
}
}