Amplify-cli: Codegen fails for deeply nested schema

Created on 29 Dec 2018  Â·  12Comments  Â·  Source: aws-amplify/amplify-cli

Describe the bug
If a query contains a deeply nested data the amplify codegen command fails to generate typescript types because graphql/queries.ts file is generated with the invalid query that misses the nested data deeper than certain level

To Reproduce

I have the following schema:

type EmailMessage {
    Body: String
    FromAddress: String!
    HtmlBody: String!
    Title: String!
}

type MessageConfiguration {
    EmailMessage: EmailMessage
}

type Schedule {
    EndTime: String
    StartTime: String
    Frequency: String
    IsLocalTime: Boolean
    Timezone: String
    QuietTime: QuietTime
}

type State {
    CampaignStatus: String
}

type Campaign {
    CreationDate: String
    HoldoutPercent: Int
    Id: ID!
    IsPaused: Boolean
    IsDraft: Boolean
    LastModifiedDate: String
    Limits: String
    Name: String!
    SegmentId: String!
    MessageConfiguration: MessageConfiguration!
    Schedule: Schedule
    State: State
}

type CampaignsConnection {
    Item: [Campaign]
    NextToken: String
}


type Query {
    Campaigns(Token: String, PageSize: String): CampaignsConnection!
    Campaign(CampaignId: String!): Campaign
}

schema {
    query: Query
}

When I ran amplify codegen command graphql/queries.ts is generated with the following content:

export const campaigns = `query Campaigns($Token: String, $PageSize: String) {
  Campaigns(Token: $Token, PageSize: $PageSize) {
    Item {
      CreationDate
      HoldoutPercent
      Id
      IsPaused
      IsDraft
      LastModifiedDate
      Limits
      Name
      SegmentId
      MessageConfiguration     <--- should have nested subfields
      Schedule {
        EndTime
        StartTime
        Frequency
        IsLocalTime
        Timezone
      }
      State {
        CampaignStatus
      }
    }
    NextToken
  }
}
`;
export const campaign = `query Campaign($CampaignId: String!) {
  Campaign(CampaignId: $CampaignId) {
    CreationDate
    HoldoutPercent
    Id
    IsPaused
    IsDraft
    LastModifiedDate
    Limits
    Name
    SegmentId
    MessageConfiguration {      <--- nested subfields are generated
      EmailMessage {
        Body
        FromAddress
        HtmlBody
        Title
      }
    }
    Schedule {
      EndTime
      StartTime
      Frequency
      IsLocalTime
      Timezone
      QuietTime {
        Start
        End
      }
    }
    State {
      CampaignStatus
    }
  }
}
`;

I have the following error:

amplify codegen                         
✔ Downloaded the schema
✔ Generated GraphQL operations successfully and saved at src/graphql
â ‹ Generating.../src/graphql/queries.ts: Field "MessageConfiguration" of type "MessageConfiguration!" must have a selection of subfields. Did you mean "MessageConfiguration { ... }"?
2018-12-29T12:02:57.268Z - error: uncaughtException: Validation of GraphQL query document failed date=Sat Dec 29 2018 13:02:57 GMT+0100 (CET), pid=71587, uid=501, gid=20, cwd=/Users/dmitriy/Work/moonmail-frontend, execPath=/Users/dmitriy/.nvm/versions/node/v9.11.1/bin/node, version=v9.11.1, argv=[/Users/dmitriy/.nvm/versions/node/v9.11.1/bin/node, /usr/local/bin/amplify, codegen], rss=159444992, heapTotal=114999296, heapUsed=88981160, external=380031, loadavg=[2.5224609375, 3.7255859375, 4.37255859375], uptime=2781354, trace=[column=11, file=/Users/dmitriy/.config/yarn/global/node_modules/amplify-graphql-types-generator/src/validation.ts, function=Object.validateQueryDocument, line=29, method=validateQueryDocument, native=false, column=3, file=/Users/dmitriy/.config/yarn/global/node_modules/amplify-graphql-types-generator/src/generate.ts, function=generate, line=34, method=null, native=false, column=7, file=/Users/dmitriy/.config/yarn/global/node_modules/amplify-codegen/src/commands/types.js, function=projects.forEach, line=39, method=forEach, native=false, column=null, file=null, function=Array.forEach, line=null, method=forEach, native=false, column=14, file=/Users/dmitriy/.config/yarn/global/node_modules/amplify-codegen/src/commands/types.js, function=generateTypes, line=22, method=null, native=false, column=9, file=/Users/dmitriy/.config/yarn/global/node_modules/amplify-codegen/src/commands/generateStatementsAndType.js, function=Object.generateStatementsAndTypes [as generate], line=28, method=generateStatementsAndTypes [as generate], native=false, column=null, file=null, function=null, line=null, method=null, native=false, column=7, file=internal/process/next_tick.js, function=process._tickCallback, line=182, method=_tickCallback, native=false], stack=[ToolError: Validation of GraphQL query document failed,     at Object.validateQueryDocument (/Users/dmitriy/.config/yarn/global/node_modules/amplify-graphql-types-generator/src/validation.ts:29:11),     at generate (/Users/dmitriy/.config/yarn/global/node_modules/amplify-graphql-types-generator/src/generate.ts:34:3),     at projects.forEach (/Users/dmitriy/.config/yarn/global/node_modules/amplify-codegen/src/commands/types.js:39:7),     at Array.forEach (<anonymous>),     at generateTypes (/Users/dmitriy/.config/yarn/global/node_modules/amplify-codegen/src/commands/types.js:22:14),     at Object.generateStatementsAndTypes [as generate] (/Users/dmitriy/.config/yarn/global/node_modules/amplify-codegen/src/commands/generateStatementsAndType.js:28:9),     at <anonymous>,     at process._tickCallback (internal/process/next_tick.js:182:7)]

If I remove one level and define a query like

Campaigns(Token: String, PageSize: String): [Campaign]!

Everything works fine.

Expected behavior
amplify codegen should generate valid queries for deeply nested types

Additional context
I'm using @aws-amplify/[email protected]

Related issues #623 #444

code-gen documentation feature-request

Most helpful comment

We have added a new configuration option to codegen, which allows to configure the max depth, while pushing a new AppSync API. For APIs that are already configured, this can be updated by running amplify codegen configure.

The depth can also be controlled by passing --max-depth param to either amplify codegen or amplify codegen statements

All 12 comments

hi, I have the same problem when try to generate for Api.Swift
@jimmyn Did you find any solution?

We move from @aws-amplify/[email protected] to @aws-amplify/[email protected] and came to the same (exactly same) error @jimmyn described.
When we downgrade to 0.1.36 and we came to the same error too...

hi, I have the same problem when try to generate for Api.Swift
@jimmyn Did you find any solution?

@danielrobleM nope, right now I have to manually update everything

any update here?

@UnleashedMind could you recommend any workaround that could be used until it is fixed?

Not sure if you've considered this, but I'd write a separate file (maybe in the same folder):
graphql/queriesCustom.ts or something like that, and put your custom ones in there. That file won't get overwritten every time you run codegen.

In https://github.com/aws-amplify/amplify-cli/issues/715#issuecomment-445930231, contributor @yuth confirmed:

the codegen generates statements only up to 2 level deep. This is to prevent nested types.

@yuth Is it possible to increase this limit to something more reasonable, like 5 levels deep?

@jimmyn statement generation is intended to reduce the friction and onboarding for customers that found they had to learn GraphQL and write documents before they could get a native app up and running. Increasing the levels to 5 increases makes the processing time longer. As mentioned in #745, for short term will make it a parameter which can be passed to codegen.

A temporary solution that works for me.

  1. Open /node_modules/amplify-codegen/src/commands/statements.js
  2. Add maxDepth param on line 35
await statementsGen(schema, opsGenDirectory, { separateFiles: true, language, maxDepth: 5 });

We have added a new configuration option to codegen, which allows to configure the max depth, while pushing a new AppSync API. For APIs that are already configured, this can be updated by running amplify codegen configure.

The depth can also be controlled by passing --max-depth param to either amplify codegen or amplify codegen statements

If somebody needs some examples can look here: https://aws-amplify.github.io/docs/cli-toolchain/graphql#codegen

PS: for me, the only thing that worked was to change the maxDepth param in the local auto generated file _.graphqlconfig.yml_

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rygo6 picture rygo6  Â·  43Comments

kaustavghosh06 picture kaustavghosh06  Â·  51Comments

baharev picture baharev  Â·  44Comments

DonPepone picture DonPepone  Â·  70Comments

lennybr picture lennybr  Â·  46Comments