内容与 JSON 编码
解码和编码请求体与响应体。
内容与 JSON 编码 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。
Content 协议
通过 HTTP 传输的 Vapor 模型需要遵循 Content。Content 建立在 Swift 的 Codable 之上,增加了从请求正文解码以及自动编码为响应的能力。
import Vapor
struct Todo: Content {
var id: Int?
var title: String
var done: Bool
}将响应编码为 JSON
从处理程序返回任意 Content 值,Vapor 就会将其编码为 JSON,并为您设置正确的 Content-Type 标头。
app.get("todo") { req -> Todo in
Todo(id: 1, title: "Learn Vapor", done: false)
}解码请求正文
使用 req.content.decode(_:) 从传入的请求中读取类型化载荷。Vapor 会检查 Content-Type,并相应地解析 JSON(或表单数据)。
app.post("todo") { req -> Todo in
let incoming = try req.content.decode(Todo.self)
return incoming
}将数组作为 Content
Content 类型的集合会自动编码为 JSON 数组。返回 [Todo] 后,客户端会收到一个 JSON 列表。
app.get("todos") { req -> [Todo] in
[Todo(id: 1, title: "A", done: false),
Todo(id: 2, title: "B", done: true)]
}自定义编码键
由于 Content 遵循 Codable,您可以使用 CodingKeys 将 Swift 属性名称映射为不同的 JSON 键,这对使用蛇形命名法的 API 很有用。
struct User: Content {
var firstName: String
enum CodingKeys: String, CodingKey {
case firstName = "first_name"
}
}配置 JSON 编码器
您可以通过 ContentConfiguration 设置全局编码策略,例如将所有键转换为蛇形命名法,或将日期格式化为 ISO-8601。
let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
encoder.dateEncodingStrategy = .iso8601
ContentConfiguration.global.use(encoder: encoder, for: .json)验证已解码的内容
Vapor 的 Validatable 协议让您可以声明验证规则。在解码之前调用 try Todo.validate(content: req),即可使用清晰的 400 错误拒绝无效输入。
extension Todo: Validatable {
static func validations(_ v: inout Validations) {
v.add("title", as: String.self, is: !.empty)
}
}在处理程序中使用验证
先验证,再解码。如果验证失败,Vapor 会自动抛出错误,客户端会收到描述性错误响应。
app.post("todo") { req -> Todo in
try Todo.validate(content: req)
return try req.content.decode(Todo.self)
}分离请求和响应 DTO
一个良好的做法是为输入和输出保留不同的类型。例如,请求使用不含 id 的 CreateTodo,响应使用完整的 Todo。这样可以将 API 与内部模型解耦。
struct CreateTodo: Content {
var title: String
}
struct TodoResponse: Content {
var id: Int
var title: String
}编码查询字符串
同样的 Content 机制可以通过 req.query.decode(_:) 将查询字符串解码为结构体,非常适合筛选和分页参数。
struct Page: Content {
var page: Int?
var size: Int?
}
app.get("items") { req -> String in
let p = try req.query.decode(Page.self)
return "page=" + String(p.page ?? 1)
}使用 Content 返回自定义状态
如果要同时控制正文和状态,可以构建一个 Response 并将内容编码到其中,或者返回类似元组的结构。下面的示例会返回带有 JSON 正文的 201 Created。
app.post("todo") { req -> Response in
let todo = try req.content.decode(Todo.self)
let res = Response(status: .created)
try res.content.encode(todo)
return res
}快速检查:Content 与 JSON
请测试您对编码的理解。
回顾:Content 与 JSON 编码
您已经了解数据如何通过网络在 Vapor 中传输:
- 让模型遵循
Content(它建立在Codable之上)。 - 返回内容以编码为 JSON;使用
req.content.decode读取正文。 - 通过
CodingKeys和ContentConfiguration自定义键和日期。 - 使用
Validatable验证输入,并考虑分离请求和响应 DTO。
常见问题解答
「内容与 JSON 编码」课时是免费的吗?
是的 — 「内容与 JSON 编码」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。
「内容与 JSON 编码」这节课中我会学到什么?
解码和编码请求体与响应体。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Swift Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「内容与 JSON 编码」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Swift Academy 课中编写并运行代码吗?
能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 路由与请求处理
- 内容与 JSON 编码
- Fluent ORM 与模型
- 中间件与身份验证