MongoDBVapor

一个用于使用 MongoDB + Vapor 构建应用程序的库。

文档

该库的最新文档可在此处获取:此处

您可以在此处找到使用此库构建的完整示例项目!

缺陷 / 功能请求

认为您发现了 bug?想要在 mongodb-vapor 中看到新功能?请在我们的问题管理工具 JIRA 中提交案例

  1. 创建帐户并登录:jira.mongodb.org
  2. 导航到 SWIFT 项目:jira.mongodb.org/browse/SWIFT
  3. 点击 创建 Issue - 请尽可能提供关于问题以及如何重现它的信息。

JIRA 中所有驱动程序项目(即 NODE、PYTHON、CSHARP、JAVA)和核心服务器(即 SERVER)项目的 bug 报告都是公开的

安装

此库适用于 Swift 5.2+,并支持 Linux 和 macOS 用法。所需的最低 macOS 版本为 10.15

通过 Swift Package Manager 支持安装。

步骤 1:安装所需的系统库(仅限 Linux)

如果您使用的是 macOS,则可以跳过 आगे。

驱动程序供应商包装了 MongoDB C 驱动程序 (libmongoc),当在 Linux 环境中构建时,它依赖于许多外部 C 库。因此,为了构建 MongoSwift,必须在您的系统上安装这些库。

要安装这些库,请按照 libmongoc 文档中的说明进行操作。

步骤 2:安装 MongoDBVapor

从模板创建新项目

要使用该库创建新项目,最简单的入门方法是使用 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 用法

请注意,如果您在 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()
}

在请求处理程序中使用 MongoDB

Async/Await API

对于您计划频繁访问的集合,我们建议在 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)
}

EventLoopFuture API

对于您计划频繁访问的集合,我们建议在 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()

使用扩展 JSON

如果您想使用 ExtendedJSONEncoderExtendedJSONDecoder 对 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 尚不支持通过 JSONEncoderJSONDecoder 进行编码/解码。

有关驱动程序中 JSON 互操作的更多信息,请参阅我们的 JSON 互操作指南