swift – 使Vapor API响应符合JSON API规范

swift – 使Vapor API响应符合JSON API规范,第1张

概述我有一个用Vapor编写的API.我想按照 JSON API规范. 我正在努力理解如何以正确的格式创建我的响应对象. 例如,我希望我的回复结构如此…… { "links": { "self": "http://example.com/dish", "next": "http://example.com/dish?page=2", "last": "http://exam 我有一个用Vapor编写的API.我想按照 JSON API规范.

我正在努力理解如何以正确的格式创建我的响应对象.

例如,我希望我的回复结构如此……

{  "links": {    "self": "http://example.com/dish","next": "http://example.com/dish?page=2","last": "http://example.com/dish?page=10"  },"data": [{    "Title": "Spag Bol","course": "main","description": "BasGetti","price": 3.9900000000000002  },{    "Title": "Ice Cream","course": "desert","description": "Vanilla","price": 0.98999999999999999  }]}

如果POST到此端点,我可以非常简单地返回数据的内容(伪代码)

router.post(dish.self,at: "API/dish") { req,data -> Future<dish> in    return Future.map(on: req,{ () -> dish in        data.ID = 001        return data    })}

我尝试创建一个APIResponse类并传入​​数据,以便我可以构造响应,但这不适用于错误无法将类型’APIResonse’的返回表达式转换为返回类型’dish’

router.post(dish.self,data -> Future<dish> in        return Future.map(on: req,{ () -> dish in            data.ID = 001            return APIResonse(links: links(self: "http://Google.com",next: "http://Google.com",last: "http://Google.com"),data: data)        })    }

我不知道怎么能这样做.这些是尝试过的课程

final class dish: Content {    var ID: Int?    var Title: String    var description: String    var course: String    var price: Double    init(Title: String,description: String,course: String,price: Double) {        self.Title = Title        self.description = description        self.course = course        self.price = price    }}struct links {    var `self`: String?    var next: String?    var last: String?}class APIResonse {    var links: links?    var data: Any    init(links: links,data: Any) {        self.links = links        self.data = data    }}

我是否需要使用泛型来设置响应类?有人能提供一个例子吗?

解决方法 >复合对象APIResponse中的每个类或结构都需要符合内容协议. Content协议包括用于JsON解码和编码的Codable协议.
>请注意,Any不符合Codable协议,因此Any不能用作Response的任何组成部分.有关更多详细信息,请参见 Vapor Docs: “Using Content”.

In Vapor 3,all content types (JsON,protobuf,URLEncodedForm,Multipart,etc) are treated the same. All you need to parse and serialize content is a Codable class or struct.

>完全符合Content的对象或复合对象可用作Responseencodable响应.
>当每个路由端点解析为特定的符合内容协议的类型时,APIResponse模型可以是通用的.

以下代码的示例项目位于GitHub: VaporExamplesLab/Example-SO-VaporJsonResponse.

示例模型

struct dish: Content {    var ID: Int?    var Title: String    var description: String    var course: String    var price: Double    init(ID: Int? = nil,Title: String,price: Double) {        self.ID = ID        self.Title = Title        self.description = description        self.course = course        self.price = price    }}struct links: Content {    var current: String?    var next: String?    var last: String?}struct APIResponse: Content {    var links: links?    var dishes: [dish]    init(links: links,dishes: [dish]) {        self.links = links        self.dishes = dishes    }}

示例POST:返回APIResponse

router.post(dish.self,at: "API/dish") {     (request: Request,dish: dish) -> APIResponse in    var dishMutable = dish    dishMutable.ID = 001    var links = links()    links.current = "http://example.com"    links.next = "http://example.com"    links.last = "http://example.com"    return APIResponse(links: links,dishes: [dishMutable])}

示例POST:返回Future< APIResponse>

router.post(dish.self,at: "API/dish-future") {     (request: Request,dish: dish) -> Future<APIResponse> in    var dishMutable = dish    dishMutable.ID = 002    var links = links()    links.current = "http://example.com"    links.next = "http://example.com"    links.last = "http://example.com"    return Future.map(on: request,{         () -> APIResponse in        return APIResponse(links: links,dishes: [dishMutable])    }) }

收到JsON响应

上述代码的Response主体产生以下内容:

{  "links": {    "current": "http://example.com","next": "http://example.com","last": "http://example.com"  },"dishes": [    {      "ID": 1,"Title": "Aztec Salad","description": "Flavorful Southwestern ethos with sweet potatos and black beans.","course": "salad","price": 1.82    }  ]}

通用模型

struct APIResponseGeneric<T> : Content where T: Content {     var links: links?    var data: T    init(links: links,data: T) {        self.links = links        self.data = data    }}

具体路线终点

router.post(dish.self,at: "API/dish-generic-future") {     (request: Request,dish: dish) -> Future<APIResponseGeneric<[dish]>> in    var dishMutable = dish    dishMutable.ID = 004    var links = links()    links.current = "http://example.com"    links.next = "http://example.com"    links.last = "http://example.com"    return Future.map(on: request,{         () -> APIResponseGeneric<[dish]> in        return APIResponseGeneric<[dish]>(links: links,data: [dishMutable])    }) }
总结

以上是内存溢出为你收集整理的swift – 使Vapor API响应符合JSON API规范全部内容,希望文章能够帮你解决swift – 使Vapor API响应符合JSON API规范所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1010573.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存