Relax


License Swift SwiftPM Platforms Test

在 Swift 中声明式地构建和发送 REST API 的客户端请求。

概述

Relax 提供了一种声明式地定义和组织 REST API 的客户端 HTTP 请求的方法。该框架基于协议构建,轻量级,可以轻松地构建请求,即使是最复杂的 REST API 也能应对。

完整参考文档

https://swiftpackageindex.cn/tdeleon/relax/documentation

特性

支持的平台

适用于所有 Swift (5.7+) 平台,包括

平台 最低版本
macOS 12.0
iOS 14.0
watchOS 7.0
tvOS 14.0
Linux Swift 5.7*
Windows Swift 5.7*

*在任何支持 Swift 5.7 的版本上均可使用。

开始使用

Relax 支持 Swift Package Manager。要集成到你的项目中 -

使用 Package Manifest 文件

  1. 将以下内容添加到 package dependencies 中 Package.swift manifest 文件

    dependencies: [
        .package(url: "https://github.com/tdeleon/Relax.git", from: "2.0.0")
    ]
  2. Relax 添加到 target dependencies

    targets: [
        .target(
            name: "YourProject",
            dependencies: ["Relax"])
    ]

使用 Xcode 项目

  1. 在你的项目中,选择 文件 > Add Package Dependencies...

  2. 选择所需的条件,然后单击 Add Package

  3. 在 Package Product 选择对话框中,在 Add to Target 列中为 Package Product Relax 选择你的 target。除非你有测试 target,否则将 URLMock 设置为 None

  4. 单击 Add Package

提示:URLMock 是一个额外的框架,旨在通过模拟请求的响应来帮助测试,应仅添加到你的测试 target 中。有关更多信息,请参阅下面的 Testing

导入框架

在你将要使用 Relax 的文件中,导入该框架

import Relax

发送请求

你可以发送非常简单的请求

do {
    let request = Request(.get, url: URL(string: "https://example.com/users")!)
    try await request.send()
} catch {
    print(error)
}

或者,更复杂的具有多个属性的请求

let request = Request(.post, url: URL(string: "https://example.com/users")!) {
    Body {
        // Send an Encodable user object as JSON in the request body
        User(name: "firstname")
    }
    Headers {
        Header.authorization(.basic, value: "secret-123")
        Header.contentType(.applicationJSON)
    }
}

有关更多详细信息,请参阅 Defining Requests

定义复杂的 API 结构

你可以将请求组组织成 Services 和 Endpoints 的结构,继承公共的 base URL 和属性

enum UserService: Service {
    static let baseURL = URL(string: "https://example.com/")!
    // Define shared properties for any request/endpoint children
    static var sharedProperties: Request.Properties {
        Headers {
            Header.authorization(.basic, value: "secretpassword")
        }
    }

    // define a /users endpoint
    enum Users: Endpoint {
        // /users appended to base URL: https://example.com/users
        static let path = "users"
        // connect Users to UserService
        typealias Parent = UserService

        // GET request
        static var getAll = Request(.get, parent: UserService.self)
    }
}

// make a get request to https://example.com/users
let users = try await UserService.Users.getAll.send()

有关更多详细信息,请参阅 Defining an API Structure

测试

URLMock 是一个用于模拟 URLSession 请求响应的框架,并作为第二个库 target 包含在 Relax 包中。

这允许你通过使用仅返回模拟内容的 URLSession 来测试所有 Requests,而永远不会通过网络发出真实请求。为常见响应(例如 HTTP 状态代码、JSON 和错误)提供了便捷方法。

要使用,只需将 URLMock 作为依赖项添加到你的 Package.swift 文件或 Xcode 中的测试 target 中

.testTarget(
    name: "MyAppTests",
    dependencies: ["Relax", "URLMock"]),

注意:URLMock 框架仅供测试使用。强烈建议仅将其作为依赖项包含在你的测试 target 中。

接下来,在你的测试中,将 URLMock 框架与 Relax 以及被测试的 target 一起包含进来

import XCTest
import Relax
import URLMock
@testable import MyApp

最后,创建一个提供模拟响应的 URLSession,并将其与 Request 一起使用

// Create a session which returns a URLError
let session = URLMock.session(.mock(.notConnectedToInternet))
// Make a request using the modified session. An error should be thrown
do {
    try await MyAPIService.Endpoint.get.send(session: session)
    XCTAssertFail("Should have failed")
} catch {
    // Validate error is handled correctly
}

有关更多示例,请参阅完整文档