如何在30分钟内用Swift编写REST API:实践指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么Swift适合REST API?

\n\n

当谈到服务器端开发时,Swift并不是第一个想到的语言。然而,随着Vapor框架(及其替代方案Kitura)的出现,Swift已成为创建REST API的成熟工具。为什么要在服务器上使用Swift?首先,它是iOS、macOS和后端的统一语言——您可以重用数据模型。其次,Swift快速、安全,并通过async/await提供了出色的异步支持。

\n\n

在本指南中,我们将使用Vapor框架在Swift中创建一个简单的REST API来管理任务列表(Todo list)。您将学习如何配置服务器、创建路由、处理JSON以及测试API。整个过程大约需要30分钟。

\n\n

步骤1:安装和配置项目

\n\n

在编写代码之前,需要安装Vapor Toolbox——一个用于创建和管理Vapor项目的命令行工具。

\n\n

安装Vapor Toolbox

\n

打开终端并执行:

\n
brew install vapor
\n

如果您没有Homebrew,请从brew.sh安装。

\n\n

创建新项目

\n

创建一个名为TodoAPI的新项目:

\n
vapor new TodoAPI -n\ncd TodoAPI
\n

标志-n表示“无示例”——我们将获得一个干净的模板。

\n\n

启动服务器

\n

在Xcode中打开项目:

\n
open Package.swift
\n

选择Run方案并按Cmd+R。几秒钟后,服务器将在http://127.0.0.1:8080上启动。打开浏览器——您应该会看到Vapor的欢迎消息。

\n\n

步骤2:创建数据模型

\n\n

我们的API将管理任务。每个任务都有ID、标题和完成状态(已完成/未完成)。

\n\n

创建Todo模型。在Vapor中,模型是符合Content协议(用于JSON序列化)和Codable协议的普通结构体。

\n\n

创建文件Sources/App/Models/Todo.swift:

\n
import Vapor\n\nstruct Todo: Content, Codable {\n    var id: UUID?\n    var title: String\n    var isCompleted: Bool\n    \n    init(id: UUID? = nil, title: String, isCompleted: Bool = false) {\n        self.id = id\n        self.title = title\n        self.isCompleted = isCompleted\n    }\n}
\n\n

注意:id是可选的UUID。我们将在创建任务时在服务器上生成它。

\n\n

步骤3:创建存储和控制器

\n\n

为简单起见,我们将任务存储在内存中(数组中)。在实际项目中,您会使用数据库(Fluent ORM),但对于30分钟的演示来说,这过于复杂。

\n\n

存储(内存存储)

\n

创建文件Sources/App/Controllers/TodoStore.swift:

\n
import Vapor\n\nfinal class TodoStore {\n    private var todos: [Todo] = []\n    private let lock = NSLock()\n    \n    func getAll() -> [Todo] {\n        lock.lock()\n        defer { lock.unlock() }\n        return todos\n    }\n    \n    func get(id: UUID) -> Todo? {\n        lock.lock()\n        defer { lock.unlock() }\n        return todos.first { $0.id == id }\n    }\n    \n    func create(_ todo: inout Todo) -> Todo {\n        lock.lock()\n        defer { lock.unlock() }\n        todo.id = UUID()\n        todos.append(todo)\n        return todo\n    }\n    \n    func update(id: UUID, with updatedTodo: Todo) -> Todo? {\n        lock.lock()\n        defer { lock.unlock() }\n        guard let index = todos.firstIndex(where: { $0.id == id }) else { return nil }\n        var mutableTodo = updatedTodo\n        mutableTodo.id = id\n        todos[index] = mutableTodo\n        return mutableTodo\n    }\n    \n    func delete(id: UUID) ->                

博客

书籍推荐