Vapor 2 模型 JSON 失败
Vapor 2 Model to JSON failure
目前有一个 class 有两个嵌套的变量,它们是结构类型。当我 post 到控制器时,我通过使用以下方法将 post 主体映射到对象来验证 JSON:
extension Request {
func user() throws -> User {
guard let json = json else { throw Abort.badRequest }
do {
return try User(json: json)
} catch {
throw Abort.init(.notAcceptable, metadata: nil, reason: "\(json.wrapped)", identifier: nil, possibleCauses: nil, suggestedFixes: nil, documentationLinks: nil, WhosebugQuestions: nil, gitHubIssues: nil)
}
}
}
调用:
extension User: JSONInitializable {
convenience init(json: JSON) throws {
try self.init(
type: json.get("type"),
person: json.get("person")
)
}
}
问题是我从 Request.user() 方法中收到抛出错误。我的模型很可靠,我已经检查了 JSON 对 person 对象的响应。目前的人是:
struct Person {
var firstName: String
var lastName: String
var email: String
var password: String
var address: Address
}
extension Person: JSONInitializable {
init(json: JSON) throws {
try self.init(
firstName: json.get("firstName"),
lastName: json.get("lastName"),
email: json.get("email"),
password: json.get("password"),
address: json.get("address")
)
}
}
这是非常基础的,因此应该可以通过映射验证。此结构是否也需要符合 Vapor Model subclass
才能正确映射,还是有其他问题?
编辑:添加用户
final class User: Model {
let storage = Storage()
var type: String
var person: Person
init(type: String, person: Person) {
self.type = type
self.person = person
}
//MARK: Parse row from the database
init(row: Row) throws {
type = try row.get("type")
person = try row.get("person")
}
//MARK: Adding a row to the database
func makeRow() throws -> Row {
var row = Row()
try row.set("person", person)
try row.set("type", type)
try row.set("country", person.address.country)
return row
}
}
extension User: JSONInitializable {
// MARK: Will be the request in json format
convenience init(json: JSON) throws {
try self.init(
type: json.get("type"),
person: json.get("person")
)
}
}
extension User: Timestampable, SoftDeletable, JSONConvertible {
//MARK: Convert user to json to pass back
func makeJSON() throws -> JSON {
var json = JSON()
try json.set("id", id)
try json.set("type", type)
try json.set("person", person)
return json
}
}
// Fluent DB Preparation
extension User: Preparation {
static func prepare(_ database: Database) throws {
try database.create(self) { builder in
builder.id()
builder.string("person")
builder.string("type")
builder.string("country")
}
}
static func revert(_ database: Database) throws {
try database.delete(self)
}
}
extension User: ResponseRepresentable, NodeRepresentable {}
您的 Person
结构也需要符合 JSONInitializable
。您的 User
扩展试图从 JSON 创建一个 Person
但不知道如何做。此外,您还需要符合 Address
,因为这似乎也是一种自定义类型。
作为替代方案,使用 Swift 4,您还可以使用 Codable
协议从 JSON.
创建模型
目前有一个 class 有两个嵌套的变量,它们是结构类型。当我 post 到控制器时,我通过使用以下方法将 post 主体映射到对象来验证 JSON:
extension Request {
func user() throws -> User {
guard let json = json else { throw Abort.badRequest }
do {
return try User(json: json)
} catch {
throw Abort.init(.notAcceptable, metadata: nil, reason: "\(json.wrapped)", identifier: nil, possibleCauses: nil, suggestedFixes: nil, documentationLinks: nil, WhosebugQuestions: nil, gitHubIssues: nil)
}
}
}
调用:
extension User: JSONInitializable {
convenience init(json: JSON) throws {
try self.init(
type: json.get("type"),
person: json.get("person")
)
}
}
问题是我从 Request.user() 方法中收到抛出错误。我的模型很可靠,我已经检查了 JSON 对 person 对象的响应。目前的人是:
struct Person {
var firstName: String
var lastName: String
var email: String
var password: String
var address: Address
}
extension Person: JSONInitializable {
init(json: JSON) throws {
try self.init(
firstName: json.get("firstName"),
lastName: json.get("lastName"),
email: json.get("email"),
password: json.get("password"),
address: json.get("address")
)
}
}
这是非常基础的,因此应该可以通过映射验证。此结构是否也需要符合 Vapor Model subclass
才能正确映射,还是有其他问题?
编辑:添加用户
final class User: Model {
let storage = Storage()
var type: String
var person: Person
init(type: String, person: Person) {
self.type = type
self.person = person
}
//MARK: Parse row from the database
init(row: Row) throws {
type = try row.get("type")
person = try row.get("person")
}
//MARK: Adding a row to the database
func makeRow() throws -> Row {
var row = Row()
try row.set("person", person)
try row.set("type", type)
try row.set("country", person.address.country)
return row
}
}
extension User: JSONInitializable {
// MARK: Will be the request in json format
convenience init(json: JSON) throws {
try self.init(
type: json.get("type"),
person: json.get("person")
)
}
}
extension User: Timestampable, SoftDeletable, JSONConvertible {
//MARK: Convert user to json to pass back
func makeJSON() throws -> JSON {
var json = JSON()
try json.set("id", id)
try json.set("type", type)
try json.set("person", person)
return json
}
}
// Fluent DB Preparation
extension User: Preparation {
static func prepare(_ database: Database) throws {
try database.create(self) { builder in
builder.id()
builder.string("person")
builder.string("type")
builder.string("country")
}
}
static func revert(_ database: Database) throws {
try database.delete(self)
}
}
extension User: ResponseRepresentable, NodeRepresentable {}
您的 Person
结构也需要符合 JSONInitializable
。您的 User
扩展试图从 JSON 创建一个 Person
但不知道如何做。此外,您还需要符合 Address
,因为这似乎也是一种自定义类型。
作为替代方案,使用 Swift 4,您还可以使用 Codable
协议从 JSON.