返回 JSON 数据 封面
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。这些检查能在客户端升级后及时发现兼容性回归。


本系列其他文章