Amplify-cli: amplify codegen creates incomplete statements

Created on 10 Mar 2019  路  11Comments  路  Source: aws-amplify/amplify-cli

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.

code-gen feature-request

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.

All 11 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nicksmithr picture nicksmithr  路  3Comments

mwarger picture mwarger  路  3Comments

jeanpaulcozzatti picture jeanpaulcozzatti  路  3Comments

davo301 picture davo301  路  3Comments

onlybakam picture onlybakam  路  3Comments