You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS AppSync中避免Mutation重复定义Input类型的方案咨询

How to Avoid Duplicate Input Types for Mutation/Subscription in AWS AppSync Local Data Sources

Hey there! I’ve dealt with this exact headache in AWS AppSync before—having to duplicate Profile/Address into InputProfile/InputAddress feels so redundant, especially when working with local (NONE-type) data sources. Let’s walk through the best solutions to reuse your existing types without hitting those validation errors.

First, let’s quickly clarify why you can’t just pass Profile directly: GraphQL enforces a strict separation between output type definitions and input input definitions. Even with local data sources, AppSync adheres to this spec, so raw object types won’t work as mutation arguments. But there are workarounds!

1. Use the @inputObject Directive (Transformer v2+)

If you’re using AWS AppSync’s GraphQL Transformer v2 (common with Amplify or CDK), the @inputObject directive lets you mark an existing object type as usable both as an output and input type. This eliminates the need for duplicate input definitions entirely.

Example schema:

type Profile @inputObject {
  id: ID!
  name: String!
  address: Address @inputObject
}

type Address @inputObject {
  street: String!
  city: String!
}

type Mutation {
  updateProfile(profile: Profile!): Profile
}

type Subscription {
  profileUpdated: Profile
    @aws_subscribe(mutations: ["updateProfile"])
}

Now you can pass a Profile object directly to your updateProfile mutation, and it will work seamlessly with your subscription. Note: This doesn’t support complex types like unions or interfaces, but it’s perfect for simple nested object structures like your Profile/Address setup.

2. Reduce Redundancy with Reusable Field Fragments

If you can’t use @inputObject (e.g., manual schema writing, older Transformer versions), you can use GraphQL fragments to centralize field definitions, so you only write them once and reference them in both your object and input types.

Example schema:

# Shared field definitions for Profile
fragment ProfileCoreFields on Profile {
  id: ID!
  name: String!
}

# Shared field definitions for Address
fragment AddressCoreFields on Address {
  street: String!
  city: String!
}

# Output type
type Profile {
  ...ProfileCoreFields
  address: Address
}

type Address {
  ...AddressCoreFields
}

# Input type (reuses the same field definitions)
input InputProfile {
  id: ID!
  name: String!
  address: InputAddress
}

input InputAddress {
  street: String!
  city: String!
}

While you still have separate input types, you only maintain the field definitions once. This cuts down on typos and makes updates much easier.

3. Generate Input Types Programmatically

For larger schemas, consider automating input type generation using a script. You can parse your GraphQL schema AST, identify object types, and auto-generate corresponding input types with the Input prefix.

Here’s a quick example using the graphql npm package:

const { parse, print, visit } = require('graphql');

// Parse your existing schema string
const schemaAST = parse(`
type Profile {
  id: ID!
  name: String!
  address: Address
}

type Address {
  street: String!
  city: String!
}
`);

// Traverse the AST to generate input types
const inputTypes = [];
visit(schemaAST, {
  ObjectTypeDefinition(node) {
    // Skip root types like Query/Mutation
    if (['Query', 'Mutation', 'Subscription'].includes(node.name.value)) return;
    
    // Convert object type to input type
    const inputType = {
      kind: 'InputObjectTypeDefinition',
      name: { kind: 'Name', value: `Input${node.name.value}` },
      fields: node.fields.map(field => ({
        ...field,
        // Recursively replace object types with their input counterparts
        type: visit(field.type, {
          NamedType(typeNode) {
            if (typeNode.name.value !== 'String' && typeNode.name.value !== 'ID') {
              return { ...typeNode, name: { ...typeNode.name, value: `Input${typeNode.name.value}` } };
            }
            return typeNode;
          }
        })
      }))
    };
    inputTypes.push(inputType);
  }
});

// Add generated input types to the schema
schemaAST.definitions.push(...inputTypes);

// Print the updated schema with input types
console.log(print(schemaAST));

This script will auto-generate InputProfile and InputAddress for you, ensuring consistency between your output and input types without manual duplication.

内容的提问来源于stack exchange,提问作者Riku92

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 14:47:31