amplify-category-api icon indicating copy to clipboard operation
amplify-category-api copied to clipboard

Selection set returns incomplete data (Gen2)

Open MKlaeui opened this issue 1 year ago • 1 comments

How did you install the Amplify CLI?

npm

If applicable, what version of Node.js are you using?

20.10.0

Amplify CLI Version

@aws-amplify/[email protected] @aws-amplify/[email protected]

What operating system are you using?

Chromebook/Linux

Did you make any manual changes to the cloud resources managed by Amplify? Please describe the changes made.

none

Describe the bug

Selection Set returns unexpected data when querying custom types and arrays. Also, cannot retrieve foreign keys of many-to-many tables. I'm assuming reading the key from the "other side" table (part) would take longer and cost more.

Expected behavior

  1. a.string().required().array().required() should return string[] and not string[][]
  2. custom type should return the data elements, not "array, authorization, required"
  3. foreign key of many-to-many table should be available rather than having to query the "other side" just to get the id

Reproduction steps

  1. const schema = a.schema({

ExperienceEnum: a.enum(['Great', 'Ok', 'Mediocre', 'Lousy']),

AlphabetEnum: a.enum(['A', 'B', 'C', 'D']),

Address: a.customType({ street: a.string(), city: a.string(), }),

CustomerDetails: a.customType({ address: a.ref('Address'), since: a.datetime().required(), }),

Verbiage: a.customType({ name: a.ref('AlphabetEnum').required(), paragraphs: a.string().required().array().required(), }),

Part: a .model({ name: a.string().required(), orders: a.hasMany('CustomerPart'), }) .authorization([a.allow.owner(),]),

Customer: a .model({ name: a.string().required(), verbiage: a.ref('Verbiage').required().array().required(), orders: a.hasMany('CustomerPart'), }) .authorization([a.allow.owner(),]),

CustomerPart: a .model({ customerDetails: a.ref('CustomerDetails'), experience: a.ref('ExperienceEnum'), customer: a.belongsTo('Customer'), part: a.belongsTo('Part'), }) .authorization([a.allow.owner(),]),

}); 3. ``` const { data: customerSet } = await client.models.Customer.list({ selectionSet: ['id', 'name', 'verbiage.', 'orders.', /* orders.partOrdersId, */ 'orders.part.id'] });

4. `const paragraphs = customerSet[0].verbiage[0]?.paragraphs;  // string[][] instead of string[]`
5. `const customerDetails = customerSet[0].orders[0].customerDetails;   // {array, authorization, required} instead of { address, since}`
6.     `const partId = customerSet[0].orders[0].partOrdersId; //  partOrdersId does not exist`

### Project Identifier

_No response_

### Log output

<details>

Put your logs below this line


</details>


### Additional information

_No response_

### Before submitting, please confirm:


- [X] I have done my best to include a minimal, self-contained set of instructions for consistently reproducing the issue.
- [X] I have removed any sensitive information from my code snippets and submission.

MKlaeui avatar Mar 19 '24 18:03 MKlaeui

Hi @MKlaeui thanks for raising this issue and providing reproduction steps. We've reproduced internally and marked as a bug for further investigation by the team.

chrisbonifacio avatar Mar 27 '24 20:03 chrisbonifacio

@MKlaeui these issues have now been fixed.

Since you're using a dev preview version of the library, you'll need to perform the following steps:

  1. Update the following aws-amplify deps in your package.json:
"dependencies": {
    "aws-amplify": "^6.3.6",
    ...
},
"devDependencies": {
    "@aws-amplify/backend": "^1.0.4",
    "@aws-amplify/backend-cli": "^1.1.0",
    ...
}
  1. rm -rf node_modules package-lock.json && npm i
  2. We changed the way relationships and authorization rules are defined in the schema between preview and GA. Please update your schema to the following:
const schema = a.schema({
  ExperienceEnum: a.enum(['Great', 'Ok', 'Mediocre', 'Lousy']),
  AlphabetEnum: a.enum(['A', 'B', 'C', 'D']),
  Address: a.customType({
    street: a.string(),
    city: a.string(),
  }),
  CustomerDetails: a.customType({
    address: a.ref('Address'),
    since: a.datetime().required(),
  }),
  Verbiage: a.customType({
    name: a.ref('AlphabetEnum').required(),
    paragraphs: a.string().required().array().required(),
  }),
  Part: a
    .model({
      name: a.string().required(),
      orders: a.hasMany('CustomerPart', 'partId'),
    })
    .authorization((allow) => [allow.owner()]),
  Customer: a
    .model({
      name: a.string().required(),
      verbiage: a.ref('Verbiage').required().array().required(),
      orders: a.hasMany('CustomerPart', 'customerId'),
    })
    .authorization((allow) => [allow.owner()]),
  CustomerPart: a
    .model({
      customerDetails: a.ref('CustomerDetails'),
      experience: a.ref('ExperienceEnum'),
      customer: a.belongsTo('Customer', 'customerId'),
      customerId: a.string(),
      part: a.belongsTo('Part', 'partId'),
      partId: a.string(),
    })
    .authorization((allow) => [allow.owner()]),
});

Please let us know if you run into any issues with updating.

iartemiev avatar Jul 02 '24 17:07 iartemiev

This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.

github-actions[bot] avatar Jul 02 '24 17:07 github-actions[bot]

Thanks for this update. This looks great. One thing that I noticed as still off (and wasn't in my original example) is that an optional array of custom types return a single instance or null instead of an array or null. For example, if I changed the Customer model to "verbiage: a.ref('Verbiage').required().array()," I get back verbiage | null instead of verbiage[] | null

MKlaeui avatar Aug 02 '24 08:08 MKlaeui