第二章:你好,Vapor
!¶
使用一项新技术开始一个项目可能是令人生畏的。Vapor
让你轻松入门。它提供了一个方便的命令行工具来为你创建一个启动项目。
在本章中,你将从安装Vapor
工具箱开始,然后用它来建立和运行你的第一个项目。最后,你将学习路由、接受数据和返回JSON
。
Vapor
工具箱¶
Vapor
工具箱是一个命令行界面(CLI
)工具,你在开发Vapor
应用程序时使用。它可以帮助你从一个模板中创建一个新的Vapor
项目,并可以根据需要添加依赖性。
在你安装工具箱之前,你需要确保你的系统已经安装了Swift
。在macOS
上,只需从Mac App Store
上安装Xcode
。在Linux
上,从https://www.swift.org,如下面描述的那样安装。
Vapor 4
需要Swift 5.2
,无论是在Xcode
还是在命令行。Xcode 11.4
和11.5
都提供Swift 5.2
。
在macOS
上安装¶
Vapor
使用Homebrew
来安装工具箱。
如果你没有安装Homebrew
,请访问https://brew.sh,运行安装命令。
在Terminal
中,运行以下命令:
brew install vapor
Note
Vapor
现在是Homebrew
核心的一部分。如果你使用Vapor
的Homebrew tap
安装了旧版本的工具箱,你可以通过以下方式更新到最新版本:
brew uninstall vapor && brew untap vapor/tap && brew install vapor
这将从Homebrew
的水龙头列表中删除Vapor
,并安装Homebrew
核心的最新版本的工具箱。
在Linux
上安装¶
本书主要侧重于使用Xcode
和macOS
来开发你的应用程序。然而,你用Vapor构建的一切都可以在Swift
支持的Linux
版本上运行。Vapor
工具箱的工作方式完全相同,但例外的是你不能在Linux
上使用Xcode
。
安装Swift
¶
要在Linux
上安装Swift
,请访问https://swift.org/download/并下载适合你的操作系统的工具链。按照安装步骤将工具链安装到你的机器上。完成后,在shell
提示下输入以下内容:
swift --version
你应该得到返回的正确版本的Swift
:
安装Vapor
¶
在你的控制台,运行以下命令:
# 1
git clone https://github.com/vapor/toolbox.git
# 2
cd toolbox
# 3
git checkout 18.0.0
# 4
swift build -c release --disable-sandbox
# 5
mv .build/release/vapor /usr/local/bin
下面是这个的作用:
- 从
GitHub
上克隆工具箱。 - 导航到你克隆的工具箱目录。
- 查看
18.0.0
版本。你可以在GitHub
上的发布页面找到工具箱的最新版本,网址是https://github.com/vapor/toolbox/releases。 - 以发布模式构建工具箱。
--disable-sandbox
允许工具箱执行其他进程。 - 把工具箱移到你的本地路径,这样你就可以从任何地方调用它。
本书在提到Linux
时一直使用Ubuntu 20.04
,但其他支持的Linux
版本应该以完全相同的方式工作。
建立你的第一个应用程序¶
建立一个Vapor
项目一开始可能会显得很复杂,因为有许多必要的文件和目录。为了帮助解决这个问题,工具箱可以根据模板创建一个新的项目。工具箱可以为一个简单的API
、网站和认证生成模板。你甚至可以创建你自己的模板。
首先,在你的主目录或合理的地方创建一个新的目录来处理你的Vapor
项目。例如,在终端输入以下命令:
mkdir ~/vapor
cd ~/vapor
这将在你的主文件夹中创建一个名为vapor
的新目录,并将你引向那里。接下来,用以下方式创建你的项目:
vapor new HelloVapor
然后工具箱会询问你是否愿意使用Fluent
和其他软件包。现在,请输入n
,然后再输入Enter
,就可以使用它们了。你以后会了解到Fluent
和其他软件包。然后,工具箱将为你生成你的项目。
你应该看到以下内容:
要构建和启动你的应用程序,请运行:
# 1
cd HelloVapor
# 2
swift run
下面是这个的作用:
cd
是"改变目录"命令,带你进入项目目录。- 构建并运行应用程序。第一次可能需要一些时间,因为它必须获取所有的依赖项。
该模板有一个预定义的路线,所以打开你的浏览器,访问http://localhost:8080/hello,就可以看到回应了!
Swift Package Manager
¶
Vapor
工具箱使用Swift Package Manager
或SwiftPM
--一个类似于iOS
上CocoaPods
的依赖性管理系统--来配置和构建Vapor
应用程序。打开你的项目目录,看一下结构。在macOS
的Terminal
中,输入:
open .
注意在你的模板中没有Xcode
项目,尽管你已经建立并运行了该应用程序。这是故意的。事实上,项目文件被明确地排除在使用.gitignore
文件的源代码控制之外。当使用SwiftPM
时,Xcode
在一个名为.swiftpm
的隐藏目录中创建一个工作区。
一个SwiftPM
项目被定义在Package.swift
清单文件中。它声明了目标、依赖性以及它们如何连接在一起。项目的布局也与传统的Xcode
项目不同。有一个Tests
目录用于测试。有一个Sources
目录用于存放源文件。在您的清单中定义的每个模块在Sources
中都有自己的目录。您的示例应用程序有一个App
模块和一个Run
模块,因此Sources
包含一个App
目录和一个Run
目录。
在Run
目录下,有一个文件:main.swift
。这是所有Swift
应用程序所需的入口点。
Note
在iOS
上,这通常是用AppDelegate
上的@UIApplicationMain
属性合成的。
该模板包含了你设置应用程序所需的一切,你不应该需要改变main.swift
或Run
模块。你的代码住在App
或你定义的任何其他模块中。
创建你自己的路由¶
Note
本节和本书的大部分内容一样,使用Xcode
。如果你在Linux
上开发,请使用你喜欢的编辑器,然后使用swift run
来构建和运行你的应用程序。
现在你已经制作了你的第一个应用程序,是时候看看用Vapor
添加新的路线有多容易。如果Vapor
应用程序仍在运行,在终端按Control-C
停止它。下一步进入:
open Package.swift
这将在Xcode
中打开该项目作为SwiftPM
工作区。Xcode
将需要几分钟时间来下载依赖项。当它完成后,在Sources/App
中打开routes.swift
。你会看到你上面访问的路由。
要创建另一个路由,请在app.get("hello")
闭包后添加以下内容:
app.get("hello", "vapor") { req -> String in
return "Hello Vapor!"
}
下面是这个的作用:
- 添加一个新的路由来处理一个
GET
请求。app.get
的每个参数是URL
中的一个路径组件。当用户输入http://localhost:8080/hello/vapor作为URL
时,该路由被调用。 - 当这个路由被调用时,提供一个闭包来运行。该闭包接收一个
Request
对象;你将在后面了解更多关于这些对象的信息。 - 返回一个字符串作为这个路由的结果。
在Xcode
工具栏中,选择HelloVapor
方案并选择My Mac
作为设备。
建立和运行。在你的浏览器中,访问http://localhost:8080/hello/vapor。
如果你想向任何访问你的应用程序的人打招呼,怎么办?添加世界上的每一个名字将是相当不切实际的! 一定有一个更好的方法。有的,Vapor
让它变得简单。
添加一个新的路线,向任何访问的人问好。例如,如果你的名字是Tim,你将使用URL
http://localhost:8080/hello/Tim访问应用程序,它说"你好,Tim
!"。
在你刚才输入的代码后添加以下内容:
// 1
app.get("hello", ":name") { req -> String in
// 2
guard let name = req.parameters.get("name") else {
throw Abort(.internalServerError)
}
// 3
return "Hello, \(name)!"
}
以下是分解步骤的过程:
- 使用
:name
来指定一个动态参数。 - 提取用户的名字,在
Request
对象中传递。如果Vapor找不到名为name
的参数,则抛出一个错误。 - 使用这个名字来返回你的问候语。
建立并运行。在你的浏览器中,访问http://localhost:8080/hello/Tim。尝试用一些其他的值替换Tim
。
接受数据¶
大多数网络应用必须接受数据。一个常见的例子是用户登录。要做到这一点,客户端会发送一个带有JSON
主体的POST
请求,应用程序必须对其进行解码和处理。要了解更多关于POST
请求及其工作原理,请参见第3章,"HTTP
基础知识"。
由于Vapor
与Swift
的Codable
协议紧密结合,它使数据解码变得很容易。你给Vapor
一个符合你预期数据的Codable
结构,剩下的就由Vapor
来完成。创建一个POST
请求,看看它是如何工作的。
本书使用RESTed
应用程序,可从Mac App Store
免费下载。如果你愿意,你可以使用另一个REST
客户端来测试你的API
。
设置请求如下:
- URL: http://localhost:8080/info
- Method: POST
- 添加一个名为
name
的单一参数。使用你的名字作为值。 - 选择
JSON-encoded
作为请求类型。这将确保数据以JSON
格式发送,并且Content-Type
头被设置为application/json
。如果你使用一个不同的客户端,你可能需要手动设置。
你的请求应该类似于以下内容:
回到Xcode
,打开routes.swift
,在文件末尾添加以下内容,创建一个名为InfoData
的struct
来表示这个请求:
struct InfoData: Content {
let name: String
}
这个struct
符合Content
,是Vapor
对Codable
的包装。Vapor
使用Content
来提取请求数据,无论它是默认的JSON
编码还是形式的URL
编码。InfoData
包含单一参数name
。
接下来,在app.get("hello", "vapor")
闭包后添加一个新的路由:
// 1
app.post("info") { req -> String in
let data = try req.content.decode(InfoData.self)
return "Hello \(data.name)!"
}
下面是这个的作用:
- 添加一个新的路由处理程序来处理
URL
http://localhost:8080/info的POST
请求。这个路由处理程序返回一个String
。 - 使用
InfoData
对请求的主体进行解码。 - 通过从
data
变量中提取名称来返回字符串。
建立并运行应用程序。从RESTed
发送请求,你会看到响应回来:
这看起来像是从JSON
中提取一个参数的大量模板。然而,Codable
可以扩展,并允许你在一行中解码复杂的、嵌套的、有多种类型的JSON
对象。
返回JSON
¶
Vapor
还可以让你在路由处理程序中轻松返回JSON
。当你的应用程序提供一个API
服务时,这是一个常见的需求。例如,一个处理来自iOS
应用的请求的Vapor
应用需要发送JSON
响应。Vapor
再次使用Content
将响应编码为JSON
。
打开routes.swift
,在文件末尾添加以下结构,称为InfoResponse
,以返回传入的请求:
struct InfoResponse: Content {
let request: InfoData
}
这个struct
符合Content
的要求,并包含一个请求的属性。
接下来,将app.post("info")
替换为以下内容:
// 1
app.post("info") { req -> InfoResponse in
let data = try req.content.decode(InfoData.self)
// 2
return InfoResponse(request: data)
}
以下是变化的内容:
- 路线处理程序现在返回新的
InfoResponse
类型。 - 使用解码后的请求数据构建一个新的
InfoResponse
类型。
构建并运行该应用程序。从RESTed
发送同样的请求。你会看到一个包含原始请求数据的JSON
响应:
Vapor
的故障排除¶
在本书的整个过程中,以及在今后的任何Vapor
应用程序中,你可能会遇到项目中的错误。可以采取一些步骤来解决任何问题。
更新你的依赖性¶
你可能遇到的另一种情况是在Vapor或你使用的另一个依赖中遇到了错误。确保你是在任何依赖的最新软件包版本上,看看更新是否修复了这个问题。在Xcode
中,选择File ▸ Swift Packages ▸ Update to Latest Package Versions
。如果你在终端运行应用程序,或在Linux
上,输入:
swift package update
这个SwiftPMSwiftPM
命令会拉下你的依赖关系的任何更新,并在Package.swift
中使用你支持的最新版本。请注意,当软件包处于测试版或候选版阶段时,更新之间可能会有突破性变化。
清理和重建¶
最后,如果你仍然有问题,你可以使用相当于"关闭并重新打开"的软件。在Xcode
中,使用Command-Option-Shift-K
来清理构建文件夹。
你可能还需要为Xcode
项目以及工作区本身清除你的衍生数据。"核"选项涉及:
- 删除
.build
目录以从命令行中删除任何构建工件。 - 删除
.swiftpm
目录以删除Xcode
工作空间和任何错误的配置。 - 删除
Package.resolved
以确保你在下次构建时获得最新的依赖性。 - 删除
DerivedData
以清除额外的Xcode
构建工件。
Vapor Discord
¶
上述步骤通常可以解决您可能遇到的大多数不是由您的代码引起的问题。 如果一切都失败了,请前往Vapor
的Discord
服务器。 在那里你会发现成千上万的开发者在讨论Vapor
,它的变化并帮助人们解决问题。 单击Vapor
网站上的Join Chat
按钮:https://vapor.codes。
接下来去哪?¶
本章概述了如何开始使用Vapor
以及如何创建基本路线。 本书的前两部分向您展示了如何构建一个复杂的应用程序,包括API
、网站和两部分中的身份验证。 随着你逐步学习它们,你将学习如何使用核心Vapor
概念,例如futures
、Fluent
和Leaf
。 到第 2 部分结束时,您将拥有在Vapor
中构建任何服务器端Swift
应用程序的坚实基础。