如何在我的 GraphQL 模式中实现一对多和多对多关系?

How do I implement one-to-many & many-to-many relationships in my GraphQL schema?

这是我第一次使用 GraphQL,我已经为包含用户、歌曲和提示的应用程序创建了一个架构。请注意,听众和艺术家都表示为用户,并且任何用户都可以通过创建提示

'tip' 歌曲

我在正确定义架构中的一对多和多对多关系时遇到问题。我也对如何编写突变来创建 Song/User/Tip 正确指向彼此的对象感到困惑。

我知道我需要在我的架构定义中使用@connection 指令,并且我尝试遵循 this example,但我仍然对如何将此设计转换为我的用例感到困惑。

这是我在指定对象之间的关系时采取的尝试:

type Song @model{
  id: ID!
  title: String!
  artist: String!
  artistArray: [User]! @connection(name: "SongArtists")
  tips: [Tip]! @connection(name: "SongTips")
  totalAmountReceived: Float!
}

type Tip @model{
  id: ID!
  from: User! @connection(name: "UserTipsSent")
  to: User! @connection(name: "UserTipsReceived")
  song: Song! @connection(name: "SongTips")
  amount: Float!
  createdAt: String!
  hash: String!
}

type User @model{
  id: ID!
  name: String!
  walletAddress: String!
  totalAmountDonated: Float!
  totalAmountReceived: Float!
  songs: [Song]! @connection(name: "SongArtists")
  tipsSent: [Tip]! @connection(name: "UserTipsSent")
  tipsReceived: [Tip]! @connection(name: "UserTipsReceived")
}

我的模式没有指定任何连接

type Song @model {
  id: ID!
  title: String!
  artist: String!
  artistArray: [User]!
  tips: [Tip]!
  totalAmountReceived: Float!
}

type Tip @model {
  id: ID!
  from: User!
  to: User!
  song: Song!
  amount: Float!
  createdAt: String!
  hash: String!
}

type User @model {
  id: ID!
  name: String!
  walletAddress: String!
  totalAmountDonated: Float!
  totalAmountReceived: Float!
  songs: [Song]!
  tipsSent: [Tip]!
  tipsReceived: [Tip]!
}

我想实现以下关系

我也不知道如何编写突变(例如)创建歌曲(指向正确的艺术家/用户)同时确保艺术家(用户对象中的歌曲数组) ) 还引用了我刚刚创建的歌曲。

值得注意的是,我在我的 AWS AppySync DynamoDB 中创建了 3 个表(歌曲、用户、提示),并且希望能够检索(例如)一个用户,他们制作的所有歌曲,以及他们在单个查询中收到的所有提示。

我目前的解决方案:

GraphQL 本身还不支持多对多关系。我简化了我的模式(不理想但暂时可以使用)以放弃 M2M 关系并向我的连接添加一个 keyField。示例:

type Song @model {
  id: ID!
  title: String!
  artist: String!
  artistObject: User! @connection(name: "ArtistSong", keyField: "userId")
  tips: [Tip]! @connection(name: "SongTip", sortField: "createdAt")
  totalAmountReceived: Float!
  inRotation: Boolean!
}

type User @model {
  id: ID!
  name: String!
  walletAddress: String!
  totalAmountDonated: Float!
  totalAmountReceived: Float!
  songs: [Song]! @connection(name: "ArtistSong", keyField: "userId")
  tipsSent: [Tip]! @connection(name: "FromUserTip")
  tipsReceived: [Tip]! @connection(name: "ToUserTip")
  email: String
}

现在,一首歌曲必须只有一个艺术家(用户)。我还没有为 Tips 实现连接,但它正在为 Users & Songs 工作。

我通过在我的突变中使用一个名为 songArtistObjectId 的字段(指的是我的 Song 模型上的 artistObject 字段)创建了链接到各自用户对象的歌曲。

这是我使用的突变(假设 User/artist 已经创建并且你有他们的 ID):

mutation CreateSong {
  createSong(input: { 
    title: "Ghost", 
    artist: "quickly, quickly",
    songArtistObjectId: "e412ca8a-367c-4cda-bc6f-91aa2d85c180",
    totalAmountReceived: 0,
    inRotation: true
  }) {
    id
    title
    artist
    artistObject {
      id
      name
      walletAddress
    }
  }
}

如果您还使用 AWS Amplify/AppSync,在本地更新架构后,请确保通过 Amplify CLI 将您的更改推送到云端:

amplify api gql-compile
amplify push

希望对您有所帮助!如果您还有其他问题,请告诉我 (: