Amplify-cli: Cannot use gsi in connection directive for intermediary m2m table

Created on 15 May 2020  路  1Comment  路  Source: aws-amplify/amplify-cli

Note: If your issue/bug is regarding the AWS Amplify Console service, please log it in the
Amplify Console GitHub Issue Tracker

I'm attempting to create a m2m relation using an intermediary TaggedPost table, which will query the Tag table by the key byName. This is my first time using DynamoDB so I wouldn't be surprised if this in on my end.

Describe the bug
Using keyName in @connection directive causes mock api / push to fail. Removing this attribute and just using @connection(fields: ["name"]) succeeds.

Amplify CLI Version

$ amplify -v
4.18.1

Schema

type Post
  @model
  @key(name: "byOwner", fields: ["userID", "createdAt"])
  @auth(
    rules: [
      { allow: owner }
      { allow: groups, groups: ["Users"], operations: [read] }
      { allow: private, provider: iam, operations: [read, update] }
      { allow: public, provider: apiKey, operations: [read] }
    ]
  ) {
  id: ID!
  title: String!
  description: String!
  createdAt: AWSDateTime!
  userID: ID!
  tags: [TaggedPost]! @connection(keyName: "byPost", fields: ["id"])
  thumb: String!
  resolutions: [Image]!
  dailyViews: Int
  monthlyViews: Int
  totalViews: Int
  votes: [Vote!] @auth(rules: [{ allow: private }])
  totalScore: Int @auth(rules: [{ allow: private }])
}

type TaggedPost
  @model(queries: null)
  @auth(
    rules: [
      { allow: groups, groups: ["Admin"] }
      { allow: public, provider: apiKey, operations: [read] }
    ]
  )
  @key(name: "byPost", fields: ["postID", "tagName"])
  @key(name: "byTag", fields: ["tagName", "postID"]) {
  id: ID!
  postID: ID!
  tagName: ID!
  post: Post! @connection(fields: ["postID"])
  tag: Tag! @connection(keyName: "byName", fields: ["tagName"])
}

type Tag
  @model
  @auth(
    rules: [
      { allow: groups, groups: ["Admin"] }
      { allow: public, provider: apiKey, operations: [read] }
    ]
  )
  @key(name: "byName", fields: ["name"]) {
  id: ID!
  name: ID!
  description: String
  posts: [TaggedPost] @connection(keyName: "byTag", fields: ["name"])
}
$ amplify mock api
Failed to start API Mock endpoint InvalidDirectiveError: Connection is to a single object but the keyName byName was provided which does not reference the default table.

Desktop (please complete the following information):

  • OS: Ubuntu 18
  • Node Version: v10.13.0

Possibly related to #2071?

@connection question

Most helpful comment

Hi @quorth0n, you're seeing this error because connections on GSI perform a DynamoDB Query operation under the hood which returns a list of records. So you'll either need to change the tag field of the TaggedPost model to an array of Tags or change the connection to the primary index of the Tag model. If tag names are guaranteed to be unique (which it seems like your current definition is assuming) then you can set the Tag name to be the primary key with type Tag @model @key(fields: ["name"]) and then set your tag connection to tag: Tag @connection(fields: ["tagName"])

>All comments

Hi @quorth0n, you're seeing this error because connections on GSI perform a DynamoDB Query operation under the hood which returns a list of records. So you'll either need to change the tag field of the TaggedPost model to an array of Tags or change the connection to the primary index of the Tag model. If tag names are guaranteed to be unique (which it seems like your current definition is assuming) then you can set the Tag name to be the primary key with type Tag @model @key(fields: ["name"]) and then set your tag connection to tag: Tag @connection(fields: ["tagName"])

Was this page helpful?
0 / 5 - 0 ratings