| Rule | Detail |
| Keyword | input (not type) |
| Field types | Only scalars, enums, other inputs, lists thereof |
| No resolvers | Pure data shape |
| No interfaces/unions | Not allowed in inputs |
input CreateUserInput {
email: String!
name: String!
role: Role = USER
metadata: JSON
}
type Mutation {
createUser(input: CreateUserInput!): CreateUserPayload!
updateUser(id: ID!, input: UpdateUserInput!): UpdateUserPayload!
}
| Pattern | Why |
Single input arg | Easy to evolve without breaking signatures |
| Required input | Force client to send the object |
input AddressInput {
street: String!
city: String!
country: String!
}
input CreateOrderInput {
customerId: ID!
shipTo: AddressInput!
items: [OrderItemInput!]!
}
| Form | Behavior |
field: T = literal | Used when field omitted |
field: T! = literal | Required type, default applies if omitted |
| Object literal | filter: F = { active: true } |
| Layer | Mechanism |
| Type system | Required fields, scalar type, enum values |
| Custom scalars | Format-level (Email, URL) |
| Directives | @constraint(minLength: 1) |
| Resolver | Cross-field business rules |
| Pattern | Example |
| Pagination input | input PageInput { first: Int, after: String } |
| Filter input | input StringFilter { eq, in, contains } |
| Sort input | input SortInput { field, direction } |
| Aspect | Input | Output (type) |
| Keyword | input | type |
| Direction | Client → Server | Server → Client |
| Allowed fields | Scalar/Enum/Input/List | Any (incl. interfaces, unions) |
| Resolvers | None | Per field |
| Args on fields | No | Yes |
Warning: Never reuse an output type as an argument. Define a parallel input.
| Pattern | Example |
| CRUD | CreateXInput, UpdateXInput, DeleteXInput |
| Filter | XFilter or XWhereInput |
| Sort | XOrderBy |
| Aspect | Detail |
| Directive | @oneOf NEW |
| Rule | Exactly one field must be provided, non-null |
| Use | Polymorphic inputs (lookup by id OR slug OR email) |
input UserBy @oneOf {
id: ID
email: String
username: String
}
type Query {
user(by: UserBy!): User
}
| Convention | Meaning |
| Omitted | "Don't change" (PATCH semantics) |
| Explicit null | "Clear value" (only if field is nullable) |
| Empty list | "Replace with no items" |
Note: Detect omitted vs null in resolvers using info.fieldNodes or pre-parse args; many ORMs treat undefined as "skip".