Vapor 大型教程
返回 JSON 数据
接口返回 JSON 前,先定义可编码的类型,再让路由负责解码和编码。这里用 Content 协议完成一个 POST 接口,并检查错误输入的响应。
让结构体自动编码为 JSON
Content 协议也可以编码结构体成为 JSON 数据,在代码中定义一个遵循 Content 协议的结构体 InfoResponse,使用请求数据初始化一个响应结构体对象,直接返回,JSON 编码会自动完成,并返回 JSON 数据给用户。
import Vapor
func routes(_ app: Application) throws {
app.get { req in
return "It works!"
}
app.get("hello") { req -> String in
return "Hello, world!"
}
// Add Routes
app.get("hello", ":name") { req -> String in
guard let name = req.parameters.get("name", as: String.self) else {
return "\(HTTPStatus.notFound)"
}
return "Hello, \(name)"
}
// ---
app.post("info") { (req) -> InfoResponse in
let info = try req.content.decode(InfoData.self)
let response = InfoResponse(requestData: info)
return response
}
}
struct InfoData: Content {
let name: String
}
struct InfoResponse: Content {
let requestData: InfoData
}
用 curl 测试
下面是测试命令:
curl http://localhost:8080/info \
-X POST \
-H "content-type:application/json" \
-d '{"name":"joker"}'
返回的 JSON:
{"requestData":{"name":"joker"}}
用 jq 格式化输出
如果想格式化输入的话,可以使用 jq 工具命令。
jq这个命令行工具,系统可能没有自带。- macOS 可以使用
brew install jq进行安装。 - Ubuntu 可以使用
sudo apt-get install jq -y进行安装。
curl -s http://localhost:8080/info \
-X POST \
-H "content-type:application/json" \
-d '{"name":"joker"}' | jq
{
"requestData": {
"name": "joker"
}
}
使用 rested 应用测试如下。
接口契约与兼容性
返回 JSON 时,字段名、类型和空值策略都属于接口契约。接口一旦被移动端或第三方调用,尽量通过新增可选字段扩展,而不是直接改名或改变类型;必要时在路径中区分版本。对日期、金额等容易产生歧义的值,建议明确格式和时区。
测试时除了检查成功响应,还要覆盖缺少字段、类型错误和未知字段三类输入,并确认响应头包含 application/json。这些检查能在客户端升级后及时发现兼容性回归。