您可以尝试以下一些概念:
对于@model 指令,在不重命名查询的情况下试一试。 AWS Amplify 为自动生成的查询提供了很好的名称。例如,要获得一家公司,它将是 getCompany,而对于列表,它将是 listCompanys。如果您仍想给它起新名称,您可以稍后更改。
对于@connection 指令:
@connection 需要在连接的两个表上设置。此外,如果您想要多对多连接,则需要添加第三个处理连接的表。当您的架构中有许多连接时,给连接命名也很有用。
只有您在架构中创建的标量类型、String、Int、Float 和 Boolean 等标准 schalar 以及 AWS 特定 schalar(如 AWSDateTime)才能用作架构中的 schalar。看看这个链接:
https://docs.aws.amazon.com/appsync/latest/devguide/scalars.html
这是我认为您想要实现的一些示例:
type Company @model {
id: ID!
name: String
president: String
vicePresident: String
secretary: String
treasurer: String
shareholders: [Shareholder] @connection(name: "CompanySharholderConnection")
address: Address @connection(name: "CompanyAdressConnection") #one to many example
# you may add more connections/attributes ...
}
# table handling many-to-many connections between users and companies, called Shareholder.
type Shareholder @model {
id: ID!
company: Company @connection(name: "CompanySharholderConnection")
user: User @connection(name: "UserShareholderConnection")
numberOfShares: Int #or String
}
type User @model {
id: ID!
firstname: String
lastname: String
company: [Shareholder] @connection(name: "UserShareholderConnection")
#... add more attributes / connections here
}
# address table, one address may have many companies
type Address @model {
id: ID!
street: String
city: String
code: String
country: String
companies: [Company] @connection(name: "CompanyAdressConnection") #many-to-one connection
}
每个这种类型...@model 都会生成一个新的 dynamoDB 表。此示例将使您可以创建多个公司和多个用户。要将用户作为股东添加到公司,您只需在 Shareholder 表中创建一个新项目,方法是在 User 表中创建一个新项目,其中用户的 ID 和 Company 表中的公司 ID + 添加多少股。
编辑
请注意,当您在两个表之间生成连接时,放大 cli(它使用 cloudformation 进行后端更改)将为一个或多个 dynamodb 表生成一个新的全局索引,以便 appsync 可以高效地为您提供数据。
dynamodb 的限制使得在编辑表时一次只能生成一个索引 (@connection)。我认为您可以在创建新表 (@model) 时做更多事情。因此,当您编辑一个或多个表时,每次只能在每次放大推送/放大发布之间删除或添加一个连接。否则,当您推送更改时,cloudformation 将失败。这可能是一团糟。因此,我不得不多次删除整个环境,幸好不是在生产环境中。
更新
(我还用 som 值更新了架构中的地址表);
要在创建新公司时连接新地址,首先必须在 dynamoDb 的地址表中创建一个新地址项。
从 appsync 生成的这个突变可能被命名为 createAddress() 并接受一个 createAddressInput。
创建地址后,您将收到整个新创建的项目,包括自动创建的 ID(如果您没有自己添加)。
现在您可以保存正在创建的新公司。 createCompany 突变采用的属性之一是您创建的地址的 id,可能命名为 companyAddressId。在此处存储地址 ID。然后,当您使用 getCompany 或 listCompanys 检索您的公司时,您将获得您公司的地址。
Javascript 示例:
const createCompany = async (address, company) => {
// api is name of the service with the mutations and queries
try {
const newaddress = await this.api.createAddress({street: address.street, city: address.city, country: address.country});
const newcompany = await this.api.createCompany({
name: company.name,
president: company.president,
...
companyAddressId: newaddress.id
})
} catch(error) {
throw error
}
}
// and to retrieve the company including the address, you have to update your graphql statement for your query:
const statement = `query ListCompanys($filter: ModelPartiFilterInput, $limit: Int, $nextToken: String) {
listCompanys(filter: $filter, limit: $limit, nextToken: $nextToken) {
__typename
id
name
president
...
address {
__typename
id
street
city
code
country
}
}
}
`
AppSync 现在将检索您的所有公司(取决于您的过滤器和限制)以及您已将地址连接到的那些公司的地址。
编辑 2
带有@model 的每种类型都是对 aws 中 dynamoDb 表的引用。因此,当您在两个表之间创建一对多关系时,当两个项目都是新的时,您首先必须在一对多关系中创建“多”。在 dynamoDb 公司表中,当一个地址可以有多个公司,而一个公司只能有一个地址时,您必须将地址的 id(dynamoDB 主键)存储在公司上。您当然可以在前端生成地址 id,并将其用作地址的 id,并将其用于公司的 addressCompanyId 并使用 await Promise.all([createAddress(...),createCompany(...)) 但如果一个失败,则将创建另一个(但通常是 appsync api非常稳定,所以如果你发送的数据是正确的,它就不会失败。
另一种解决方案,如果您通常不必在多个表中创建/更新多个项目,您可以将地址直接存储在公司项目中。
type Company @model {
name: String
...
address: Address # or [Address] if you want more than one Address on the company
}
type Address {
street: String
postcode: String
city: string
}
那么地址类型将是 dynamoDb 中同一个表中同一个项目的一部分。但是您将失去对地址(或股东)进行查询以查找地址并查看哪些公司位于那里(或类似地查找一个人并查看该人拥有哪些公司的股份)的能力。一般来说,我不喜欢这种方法,因为它将您的应用程序锁定在一个特定的事物上,并且以后很难创建新功能。
据我所知,不可能在一个 graphql (Amplify/AppSync) 突变中的多个 dynamoDb 表中创建多个项目。因此,使用 Promise.all() 进行异步等待并在创建项目之前手动生成前端的 id 属性可能是您的最佳选择。