一个用于使用 MongoDB + Vapor 构建应用程序的库。
认为您发现了 bug?想要在 mongodb-vapor
中看到新功能?请在我们的问题管理工具 JIRA 中提交案例
JIRA 中所有驱动程序项目(即 NODE、PYTHON、CSHARP、JAVA)和核心服务器(即 SERVER)项目的 bug 报告都是公开的。
此库适用于 Swift 5.2+,并支持 Linux 和 macOS 用法。所需的最低 macOS 版本为 10.15。
通过 Swift Package Manager 支持安装。
如果您使用的是 macOS,则可以跳过 आगे。
驱动程序供应商包装了 MongoDB C 驱动程序 (libmongoc
),当在 Linux 环境中构建时,它依赖于许多外部 C 库。因此,为了构建 MongoSwift,必须在您的系统上安装这些库。
要安装这些库,请按照 libmongoc
文档中的说明进行操作。
要使用该库创建新项目,最简单的入门方法是使用 Vapor 的命令行工具 Vapor Toolbox,以及我们的应用程序模板
vapor new MyProject --template https://github.com/mongodb/mongodb-vapor-template/
这将从模板创建一个新项目,您可以根据自己的喜好进行编辑。有关生成的项目的更多详细信息,请参阅 此处 或生成的 README 中的说明。
或者,您可以通过将此库与 Vapor 作为依赖项添加到项目的 Package.swift
文件中,在 SwiftPM 项目中手动集成此库
// swift-tools-version:5.2
import PackageDescription
let package = Package(
name: "VaporExample",
platforms: [
.macOS(.v10_15)
],
dependencies: [
.package(url: "https://github.com/vapor/vapor", .upToNextMajor(from: "4.7.0")),
.package(url: "https://github.com/mongodb/mongodb-vapor", .upToNextMajor(from: "1.1.0"))
],
targets: [
.target(
name: "App",
dependencies: [
.product(name: "Vapor", package: "vapor"),
.product(name: "MongoDBVapor", package: "mongodb-vapor")
]
),
.target(name: "Run", dependencies: [
.target(name: "App"),
.product(name: "MongoDBVapor", package: "mongodb-vapor")
])
]
)
然后运行 swift build
来下载、编译和链接所有依赖项。
请注意,如果您在 Docker 上使用此库以及 Vapor 的默认 Docker 模板文件,则需要在 Linux 上安装驱动程序所需的系统依赖项,如上面所述。
为此,请将以下内容添加到您的 Dockerfile 中
RUN apt-get update && apt-get install -y libssl-dev
用户 @dotmain 还创建了一个包含 Docker 配置的 Vapor 模板,此处。
总结可用功能
在 App/configure.swift
中的 configure(_:)
方法中,添加
// Configure the app for using a MongoDB server at the provided connection string.
try app.mongoDB.configure("mongodb://:27017")
在 Run/main.swift
中,添加
import MongoDBVapor
defer {
// Cleanup the application's MongoDB data.
app.mongoDB.cleanup()
// Clean up the driver's global state. The driver will no longer be usable from this program after this method is
// called.
cleanupMongoSwift()
}
对于您计划频繁访问的集合,我们建议在 Request
的扩展中添加计算属性以提供轻松访问,例如
extension Request {
/// A collection with an associated `Codable` type `Kitten`.
var kittenCollection: MongoCollection<Kitten> {
self.application.mongoDB.client.db("home").collection("kittens", withType: Kitten.self)
}
}
然后,您可以像下面这样在请求处理程序中使用它们
/// Handles a request to load the list of kittens.
app.get("kittens") { req async throws -> [Kitten] in
try await req.kittenCollection.find().toArray()
}
/// Handles a request to add a new kitten.
app.post("kittens") { req async throws -> Response in
let newKitten = try req.content.decode(Kitten.self)
try await req.kittenCollection.insertOne(newKitten)
return Response(status: .created)
}
对于您计划频繁访问的集合,我们建议在 Request
的扩展中添加计算属性以提供轻松访问,例如
extension Request {
/// A collection with an associated `Codable` type `Kitten`.
var kittenCollection: MongoCollection<Kitten> {
self.mongoDB.client.db("home").collection("kittens", withType: Kitten.self)
}
}
您通过 Request.mongoDB
访问的任何客户端、数据库或集合对象都将自动在处理 Request
的同一 EventLoop
上返回 EventLoopFuture
,从而简化了线程安全问题,并通过消除对返回的 future 进行 hop
的需求来提高性能。
然后,您可以像下面这样在请求处理程序中使用它们
/// Handles a request to load the list of kittens.
app.get("kittens") { req -> EventLoopFuture<[Kitten]> in
req.kittenCollection.find().flatMap { cursor in
cursor.toArray()
}
}
/// Handles a request to add a new kitten.
app.post("kittens") { req -> EventLoopFuture<Response> in
let newKitten = try req.content.decode(Kitten.self)
return req.kittenCollection.insertOne(newKitten)
.map { _ in Response(status: .created) }
}
如果您有一次性代码需要在每次应用程序启动时运行,例如在 Run/main.swift
中,您可以使用全局客户端,可以通过 Application.mongoDB
访问
// Configure the app for using a MongoDB server at the provided connection string.
try app.mongoDB.configure("mongodb://:27017")
let coll = app.mongoDB.client.db("home").collection("kittens")
// creates a unique index if it doesn't exist already.
_ = try coll.createIndex(["name": 1], indexOptions: IndexOptions(unique: true)).wait()
如果您想使用 ExtendedJSONEncoder
和 ExtendedJSONDecoder
对 JSON 请求/响应进行编码/解码,请在 App/configure.swift
中添加
// Use `ExtendedJSONEncoder` and `ExtendedJSONDecoder` for encoding/decoding `Content`.
ContentConfiguration.global.use(encoder: ExtendedJSONEncoder(), for: .json)
ContentConfiguration.global.use(decoder: ExtendedJSONDecoder(), for: .json)
请注意,如果您想使用 BSONDocument
作为 Content
类型,并例如直接从请求处理程序返回 BSONDocument
,则目前这是必需的,因为 BSONDocument
尚不支持通过 JSONEncoder
和 JSONDecoder
进行编码/解码。
有关驱动程序中 JSON 互操作的更多信息,请参阅我们的 JSON 互操作指南。