如何使用 Amplify iOS (AppSync) 存储关系(一对多或多对一)数据?

rod*_*elp 9 ios swift graphql aws-amplify amplify-ios

今天检查了一些放大文档(我知道这个文档说它是iOS场景中的预览)但我遇到了一个障碍。

假设

  1. 在我的 iOS 项目中正确配置了 Amplify。我可以将数据推送到Person并查询Amplify.API
  2. 该架构已定义为:
type Person @model {
  id: ID!
  name: String!
  possessions: [Thing] # list of things this person owns.
    @connection(keyName: "byPerson", fields: ["id"])
}

type Thing @model
           @key(name: "byPerson", fields: ["personId"]) {

  id: ID!
  name: String!
  personId: ID!
  ownerOfThings: Person # defining the 'belongsTo' property.
    @connection(fields: ["personId"])
}
Run Code Online (Sandbox Code Playgroud)

这将生成以下代码:

type Person @model {
  id: ID!
  name: String!
  possessions: [Thing] # list of things this person owns.
    @connection(keyName: "byPerson", fields: ["id"])
}

type Thing @model
           @key(name: "byPerson", fields: ["personId"]) {

  id: ID!
  name: String!
  personId: ID!
  ownerOfThings: Person # defining the 'belongsTo' property.
    @connection(fields: ["personId"])
}
Run Code Online (Sandbox Code Playgroud)

这是我遇到麻烦的地方。Amplify.API似乎没有在单个突变中保存我的对象及其相关数据。我必须将其称为嵌套操作才能产生效果。

public struct Person: Model {
  public let id: String
  public var name: String
  public var possessions: List<Thing>?

  public init(id: String = UUID().uuidString,
      name: String,
      possessions: List<Thing>? = []) {
      self.id = id
      self.name = name
      self.possessions = possessions
  }
}

public struct Person: Model {
  public let id: String
  public var name: String
  public var ownerOfThings: Person?

  public init(id: String = UUID().uuidString,
      name: String,
      ownerOfThings: Person? = nil) {
      self.id = id
      self.name = name
      self.ownerOfThings = ownerOfThings
  }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码将生成类似于以下内容的输出:

Result.success(Person(id: "EC4BEEE1-C1A1-4831-AB86-EA1E22D8AD48", name: "Jon Snow", possessions: nil))

GraphQLResponseError<Thing>: GraphQL service returned a successful response containing errors: [Amplify.GraphQLError(message: "Variable \'input\' has coerced Null value for NonNull type \'ID!\'", locations: Optional([Amplify.GraphQLError.Location(line: 1, column: 26)]), path: nil, extensions: nil)]
Run Code Online (Sandbox Code Playgroud)

我试过将这种关系声明为:

type Person @model {
  id: ID!
  name: String!
  possessions: [Thing] # list of things this person owns.
    @connection(keyName: "byPerson", fields: ["id"])
}

type Thing @model
           @key(name: "byPerson", fields: ["personId"]) {

  id: ID!
  name: String!
  personId: ID!
  # ownerOfThings: Person
  #   @connection(fields: ["personId"]) # Not belongsTo for you!
}
Run Code Online (Sandbox Code Playgroud)

或者它的一个变体,将 定义possessionspossessions: [Thing] @connection

所有这些都会产生各种(尽管有一些相关的)错误,阻止我存储我的数据。

那么,问题来了: 如何在iOS中指定关系来保存呢?