Using amplify version 1.1.7
When I run amplify codegen
on my schema, it ends up skipping some of the fields in one model and does not include all of the fields for a related model for the "list" statement. I can always go back and manually edit them, but it is a pain to need to do this every time.
So 2 issues/questions.
1) It seems to me that it should include all of the model fields in the return results for a list or get query.
2) I would like it to include as many levels deep as I've configured it to go for the query result items as well.
Here is the model from Schema.graphql:
type Instrument
@model
@auth(
rules: [
{allow: owner},
{allow: owner, ownerField: "owner", mutations: [create, update, delete], queries: [get, list]},
{allow: groups, groups: ["Admin"]}
])
{
id: ID!
owner: String
name: String!
category: InstrumentCategory!
status: InstrumentStatus
type: InstrumentType!
manufacturer: String
model: String
color: String
serialNumber: String
yearManufactured: String
description: String
purchasedAt: String
purchaseLocation: String
purchasePrice: Float
purchaseDate: AWSDate
soldPrice: Float
soldDate: AWSDate
images: [S3Object] @connection(name: "InstrumentImages")
}
type S3Object @model {
id: ID!
bucket: String!
key: String!
region: String!
order: Int
instrument: Instrument @connection(name:"InstrumentImages")
}
When I call amplify codegen, the queries look like this:
export const getInstrument = `query GetInstrument($id: ID!) {
getInstrument(id: $id) {
id
owner
name
category
status
type
manufacturer
model
color
serialNumber
yearManufactured
description
purchasedAt
purchaseLocation
purchasePrice
purchaseDate
soldPrice
soldDate
images {
nextToken
}
}
}
`;
export const listInstruments = `query ListInstruments(
$filter: ModelInstrumentFilterInput
$limit: Int
$nextToken: String
) {
listInstruments(filter: $filter, limit: $limit, nextToken: $nextToken) {
items {
id
owner
name
manufacturer
model
color
serialNumber
yearManufactured
description
purchasedAt
purchaseLocation
purchasePrice
purchaseDate
soldPrice
soldDate
}
nextToken
}
}
`;
Note that for listInstruments, the category and status fields are missing as is images and for getInstrument, the properties of S3Object are missing.
Every time I do amplify codegen
I need to go back and manually fix these items.
Graphqlconfig.yml does have maxDepth set to 2 so I would expect that the images fields are filled in for those queries.
I think you can run amplify codegen configure
to set the maximum depth for future codegen runs. You can also specify a --max-depth
argument to amplify codegen
to get a custom depth beyond what you have configured.
I have been experiencing similar issues with (named) 1-to-1 connections. (Named 1-to-many connections work fine on queries, don't have any many-to-many relationships.) For instance, I have something like this:
type User @model @auth {...myRulesSimilarToOP} {
id: ID!
UserProfile @connection(name:"UserProfile")
ManyItems @connection(name:"UserManyItems")
...
}
type UserProfile @model @auth(...sameRules) {
id: ID!
user: User @connection(name:"UserProfile")
someOtherUserItem: @connection(name:"UserProfileOtherUserItem") #goes for a couple more depths
}
type ManyItems @model {
id: ID!
user: @connection(name:"UserManyItems")
...
}
When I run amplify push
with a max depth of 5
, this type of schema works for the one-to-many connections, but the one-to-one connection (User to UserProfile) returns Null when querying with the generated getUser
query, despite verifying that the "userUserProfileId" (forget exact name, paraphrasing) generated "foreign key" is correctly generated in the table and matches the id
field of the previously created User
field.
Please note that this error (with the one-to-one connection) also persists when running a query in the AppSync console, so I do not think this is an Amplify issue in particular. I will be raising an issue with the AppSync team on Monday. OP's issue is more related to codegen, so my comment might not be super relevant (hope it helps someone though).
Setting the max level to 3 still doesn't include the info on the images in the statement for listInstruments. Also, it seem like maxLevel of 2 should return them since they are just one level down though it looks like the docs hint that getting the info on the photos is level 3?
From diagram on statement depth
blog { # depth level 3
id
name
posts { # depth level 4
items { # depth level 5
id
title
}
nextToken
}
}
Either way, I would expect the items to show up in MaxLevel 3 for listInstruments and they didn't when I just tried it.
@poppybank
When I call amplify codegen, the queries look like this:
export const getInstrument = `query GetInstrument($id: ID!) {
getInstrument(id: $id) {
id
owner
name
category
status
type
manufacturer
model
color
serialNumber
yearManufactured
description
purchasedAt
purchaseLocation
purchasePrice
purchaseDate
soldPrice
soldDate
images {
nextToken
}
}
}
`;
You would see this only if the the max-depth is set to 2. When its max-depth is set to 3 you should get this
export const getInstrument = `query GetInstrument($id: ID!) {
getInstrument(id: $id) {
id
owner
name
category
status
type
manufacturer
model
color
serialNumber
yearManufactured
description
purchasedAt
purchaseLocation
purchasePrice
purchaseDate
soldPrice
soldDate
images {
items {
id
bucket
key
region
order
}
nextToken
}
}
}
`;
In AppSync any field thats an list returns a connection object with items
and nextToken
to support the pagination and codegen doesn't treat these object as a special object.
Yes, and at level 3 for getInstrument, that is what I get. But listInstruments still does not include the items under images.
@poppybank thats because the listInstruments
images
is of list type. AppSync converts a lists to connection object so it can support pagination
query ListInstruments(
$filter: ModelInstrumentFilterInput
$limit: Int
$nextToken: String
) {
listInstruments(filter: $filter, limit: $limit, nextToken: $nextToken) { # level 1
items { # level 2
id
owner
name
category
status
type
manufacturer
model
color
serialNumber
yearManufactured
description
purchasedAt
purchaseLocation
purchasePrice
purchaseDate
soldPrice
soldDate
images { # level 3
items { # level 4
id
bucket
key
region
order
}
nextToken
}
}
nextToken
}
}
OK, as a user, this is problematic. In order to consistently get the same information back from calls (I always want instruments to include the images) I need to set maxLevel to 4 for listInstruments to work but then calls like getInstrument will include the instrument data multiple times. My recommendation would be to include the items as the level for the thing that includes it so that the getInstruments and listInstruments calls would be much more in sync with the data that is returned.
@poppybank Thank you for your feedback. We will discuss this internally. The generation of statements is meant to be used as a starting point. In the mean time I recommend you to write custom queries, if your use case has different max-depth for different statements. You could write your custom queries and drop in its own file and codegen will generate the types for your custom queries.
I just ran into this as well and filed https://github.com/aws-amplify/amplify-cli/issues/1244, which now looks like a dupe of this ticket. I agree with @poppybank that not including items but including nextToken is undesirable and that a list of items with pagination token should be treated as one level rather than 2.
Just ran into this as well. I expected that list and get to return the same data from the items level.
I found that just using
amplify codegen --max-depth 6
does not work.
I had to do amplify codegen configure
and set the max-depth
there and then it worked like a charm.
Nice catch @sudeep-quantelai I was able to get the right depth by using configure.
Most helpful comment
I found that just using
amplify codegen --max-depth 6
does not work.I had to do
amplify codegen configure
and set the
max-depth
there and then it worked like a charm.