Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for input type in custom mutation definition #2734

Open
travishaby opened this issue Jul 31, 2024 · 11 comments
Open

Allow for input type in custom mutation definition #2734

travishaby opened this issue Jul 31, 2024 · 11 comments
Labels

Comments

@travishaby
Copy link

Environment information

System:
  OS: macOS 14.5
  CPU: (10) arm64 Apple M2 Pro
  Memory: 1.89 GB / 32.00 GB
  Shell: /bin/zsh
Binaries:
  Node: 20.12.2 - ~/.nvm/versions/node/v20.12.2/bin/node
  Yarn: 1.22.21 - /opt/homebrew/bin/yarn
  npm: 10.5.0 - ~/.nvm/versions/node/v20.12.2/bin/npm
  pnpm: undefined - undefined
NPM Packages:
  @aws-amplify/auth-construct: 1.2.0
  @aws-amplify/backend: 1.0.4
  @aws-amplify/backend-auth: 1.1.0
  @aws-amplify/backend-cli: 1.2.1
  @aws-amplify/backend-data: 1.1.0
  @aws-amplify/backend-deployer: 1.0.2
  @aws-amplify/backend-function: 1.3.0
  @aws-amplify/backend-output-schemas: 1.1.0
  @aws-amplify/backend-output-storage: 1.0.2
  @aws-amplify/backend-secret: 1.0.0
  @aws-amplify/backend-storage: 1.0.4
  @aws-amplify/cli-core: 1.1.1
  @aws-amplify/client-config: 1.1.1
  @aws-amplify/deployed-backend-client: 1.1.0
  @aws-amplify/form-generator: 1.0.0
  @aws-amplify/model-generator: 1.0.2
  @aws-amplify/platform-core: 1.0.3
  @aws-amplify/plugin-types: 1.1.0
  @aws-amplify/sandbox: 1.1.1
  @aws-amplify/schema-generator: 1.2.0
  aws-amplify: 6.4.3
  aws-cdk: 2.150.0
  aws-cdk-lib: 2.150.0
  typescript: 5.5.4
AWS environment variables:
  AWS_STS_REGIONAL_ENDPOINTS = regional
  AWS_NODEJS_CONNECTION_REUSE_ENABLED = 1
  AWS_SDK_LOAD_CONFIG = 1
No CDK environment variables

Description

It doesn't look like the Gen2 data construct provides the ability to declare an input type when creating a mutation.

I have a fairly complex object that I'm trying to pass in to write a record, and an input type that accepted nested input types would be ideal in order to keep the schema DRY and make things clearer.

Thanks!

@ykethan
Copy link
Member

ykethan commented Jul 31, 2024

Hey,👋 thanks for raising this! I'm going to transfer this over to our API repository for better assistance 🙂

@ykethan ykethan transferred this issue from aws-amplify/amplify-backend Jul 31, 2024
@ykethan ykethan added the Gen 2 label Jul 31, 2024
@chrisbonifacio chrisbonifacio self-assigned this Aug 1, 2024
@chrisbonifacio
Copy link
Member

chrisbonifacio commented Aug 1, 2024

Hi @travishaby thanks for raising this issue. While we support setting arguments for custom mutations that generate input types in the compiled schema, it seems you are asking for something more robust that supports nested input types. Can you please explain a bit more how you would like this feature to work? Could you provide an API example?

For now, I will mark this as a feature request for the team to consider.

@chrisbonifacio chrisbonifacio added the feature-request New feature or request label Aug 1, 2024
@travishaby
Copy link
Author

travishaby commented Aug 15, 2024

Hi @chrisbonifacio ! Sorry for the delay--here's an example of a valid graphql schema that I would like to see support for that currently doesn't seem possible. Happy to be wrong if this is supported!

input ProgramInput {
  parentId: ID!
  active: Boolean!
  # nested input type is the key thing that doesn't seem supported
  requirements: ProgramRequirementsInputType
}

input ProgramRequirementsInputType {
  createdAt: AWSDateTime
  minCollegeCredits: Int
  minCollegeCreditsDetails: String
  updatedAt: AWSDateTime
}

createProgram(programData: ProgramInput!): ProgramType

in the Gen2 definition api, i would expect to be able to do something like...

const schema = a.schema({
  // ...
  ProgramInput: a.customInputType({
    parentId: a.id(),
    active: a.boolean().required(),
    requirements: a.ref('ProgramRequirementsInputType'),
  }),
  ProgramRequirementsInputType: a.customInputType({
     // ...
  }),
  createProgram: a
    .mutation()
    .arguments({
      programData: a.ref('ProgramInput')
    })
    .returns(a.ref('ProgramType'))
    .authorization((allow) => allow.authenticated('oidc'))
    .handler(
      a.handler.custom({
      entry: './resolvers/createProgram.js',
      dataSource: 'CreateProgramDataSource',
    }),
  // ...
),

@travishaby
Copy link
Author

travishaby commented Aug 15, 2024

ah, almost forgot! just to call it out explicitly, would also want to do an array of an input type like:

// ...
const schema = a.schema({
  // ...
  ProgramInput: a.customInputType({
    parentId: a.id(),
    active: a.boolean().required(),
    requirements: a.ref('ProgramRequirementsInputType').array(),
  }),
  // ...

@thomasoehri
Copy link

I'm having problems here too.

  • For one, not being able to create input types makes everything more difficult in my frontend. I'm using the Apollo GraphQL client to execute queries and mutations. In my Amplify backend i have a custom updateForum mutation where i'm able to update single fields or multiple fields at once (for example just the name, key, description, etc. for a forum or multiple of those fields at once).

In my frontend i have the case where i only update single fields at once. By not having an input type i have to define a separate GraphQL document for each field i want to update with just that argument present (for example UpdateForumNameMutation.graphql, UpdateForumKeyMutation.graphql, UpdateForumDescriptionMutation.graphql, etc.).

Coming from Amplify Gen 1 i was able to define an input type with all of the fields nested underneath with just one GraphQL document for updateForum in my frontend where i am able to just not pass the field i don't want to update.

// What currently is possible in Gen 2 and causes problems:
customCreateForum: a
        .mutation()
        .arguments({
                key: a.string().required(),
                name: a.string().required(),
                organizationID: a.id().required(),
                private: a.boolean(),
                allowUnauthenticatedPosts: a.boolean(),
                autoModerationEnabled: a.boolean(),
                autoModerationThreshold: a.integer(),
                ...
        })

// vs. what was possible in Gen 1 and works with only one GraphQL Document in my frontend:
CreateForumInput: a.customInputType({
        key: a.string().required(),
        name: a.string().required(),
        organizationID: a.id().required(),
        private: a.boolean(),
        allowUnauthenticatedPosts: a.boolean(),
        autoModerationEnabled: a.boolean(),
        autoModerationThreshold: a.integer(),
}),

customCreateForum: a
        .mutation()
        .arguments({
                input: a.ref("CreateForumInput")
        })
  • In Gen 2 we currently have a discrepancy between the auto-generated queries/mutations and the custom ones. The autogenerated mutations follow the convention of having an input argument, which cannot be replicated with custom mutations. I don't want to have an input argument in half of my mutations and none in the other half.

  • Another thing is that I can't pass enums that I have defined as custom types in my schema as arguments. I have to re-declare the enum with all its values as a raw argument type. Having to add or remove a value from the enum is suboptimal, since I'd have to change all the enums instead of just one that I can reference in all the arguments.

StatusColor: a.enum([
        "NEUTRAL",
        "BLUE",
        "GREEN",
        "RED",
        "YELLOW",
        "TEAL",
        "PURPLE",
]),
        
customCreateStatus: a
        .mutation()
        .arguments({
                forumID: a.id().required(),
                name: a.string().required(),
                // TODO: Use StatusColor custom type once supported
                color: a.enum([
                    "NEUTRAL",
                    "BLUE",
                    "GREEN",
                    "RED",
                    "YELLOW",
                    "TEAL",
                    "PURPLE",
                ]),
                // Just let me use my StatusColor custom type:
                // color: a.ref("StatusColor")
        })

@thomasoehri
Copy link

thomasoehri commented Aug 16, 2024

Another use-case that is currently not supported is that of filter input types.

All auto-generated queries have a filter argument as shown below and it is currently not possible to something similar with custom queries in Gen 2 since we can't define/use input types and nest them.

listForums(filter: ModelForumFilterInput, limit: Int, nextToken: String): ModelForumConnection

input ModelForumFilterInput {
        //  All of these nested input types are not possible in Gen 2 since we can't reference custom types in arguments
	key: ModelStringInput
	name: ModelStringInput
	symbol: ModelStringInput
	private: ModelBooleanInput
	allowUnauthenticatedPosts: ModelBooleanInput
	autoModerationEnabled: ModelBooleanInput
	autoModerationThreshold: ModelIntInput
	organizationID: ModelIDInput
	id: ModelIDInput
	createdAt: ModelStringInput
	updatedAt: ModelStringInput
	and: [ModelForumFilterInput]
	or: [ModelForumFilterInput]
	not: ModelForumFilterInput
}

input ModelStringInput {
	ne: String
	eq: String
	le: String
	lt: String
	ge: String
	gt: String
	contains: String
	notContains: String
	between: [String]
	beginsWith: String
	attributeExists: Boolean
	attributeType: ModelAttributeTypes
	size: ModelSizeInput
}

...

@jmarshall9120
Copy link

Just to add to this.... I'm not sure how to even get the auto generated types from the schema:

Would expect something like:

Type MyInput = Schema['MyInput']

But Schema doesn't include the Input Types.

@aashishjaria
Copy link

Can we expect this feature in future versions?

@iartemiev
Copy link
Member

Hey all, we're currently working on adding support for custom types and refs in custom query/mutation arguments. GraphQL Input types will be automatically generated from these behind the scenes. We'll post an update here as soon as the feature is released.

@thomasoehri
Copy link

Hey all, we're currently working on adding support for custom types and refs in custom query/mutation arguments. GraphQL Input types will be automatically generated from these behind the scenes. We'll post an update here as soon as the feature is released.

Thanks for the update. I‘m eagerly awaiting this feature since this is a blocker for me.

@thomasoehri
Copy link

@iartemiev Are you working on adding support for custom types and refs in custom query/mutation arguments as well as return types?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants