引言:为什么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打开终端并执行:
\nbrew install vapor\n如果您没有Homebrew,请从brew.sh安装。
\n\n创建新项目
\n创建一个名为TodoAPI的新项目:
vapor new TodoAPI -n\ncd TodoAPI\n标志-n表示“无示例”——我们将获得一个干净的模板。
启动服务器
\n在Xcode中打开项目:
\nopen Package.swift\n选择Run方案并按Cmd+R。几秒钟后,服务器将在http://127.0.0.1:8080上启动。打开浏览器——您应该会看到Vapor的欢迎消息。
步骤2:创建数据模型
\n\n我们的API将管理任务。每个任务都有ID、标题和完成状态(已完成/未完成)。
\n\n创建Todo模型。在Vapor中,模型是符合Content协议(用于JSON序列化)和Codable协议的普通结构体。
创建文件Sources/App/Models/Todo.swift:
\nimport 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。我们将在创建任务时在服务器上生成它。
步骤3:创建存储和控制器
\n\n为简单起见,我们将任务存储在内存中(数组中)。在实际项目中,您会使用数据库(Fluent ORM),但对于30分钟的演示来说,这过于复杂。
\n\n存储(内存存储)
\n创建文件Sources/App/Controllers/TodoStore.swift:
\nimport 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) ->