afv-library/skills/using-webapplication-salesforce-data/references/mutation-query-generation.md
k-j-kim a779945206
Rename webapp/webapplication to UI bundle in skills (#129)
* Split generating-webapp-metadata into single-purpose skills

Extract the deployment sequence into a new deploying-webapp skill so each
webapp skill describes exactly one actionable goal. This improves agent
skill selection accuracy by eliminating multi-concern descriptions.

- generating-webapp-metadata: now focused on scaffolding, bundle config, CSP
- deploying-webapp: new skill for the 7-step deployment sequence

* Rename -webapp- skill directories and references to -webapplication-

Rename all 7 webapp skill directories to use the full "webapplication"
entity name. Update frontmatter name fields, cross-skill references,
and descriptive prose. Package names and CLI commands are preserved
as-is since those are actual identifiers.
2026-03-30 11:49:19 -05:00

5.6 KiB

Mutation Query Generation

Mutation Types

The GraphQL engine supports three mutation operations:

  • Create — Insert a new record
  • Update — Modify an existing record (Id-based)
  • Delete — Remove an existing record (Id-based)

Mutations are GA in API v66+. They live under mutation { uiapi { ... } } and only support UI API-available objects.

Generation Rules

  1. Input fields validation — Validate that input fields satisfy the constraints for the operation type
  2. Output fields validation — Validate that output fields satisfy the constraints for the operation type
  3. Type consistency — Variables used as query arguments and their related fields must share the same GraphQL type. Verify types via the schema search script — do NOT assume types
  4. Input argumentsinput is the default argument name unless otherwise specified
  5. Output field — For Create and Update, the output field is always named Record (type: EntityName)
  6. Field name validation — Every field name in the generated mutation MUST match a field confirmed via the schema search script. Do NOT guess or assume field names exist
  7. Raw input values — Numeric values must be raw numbers without commas, currency symbols, or locale formatting (e.g., 80000 not "80,000" or "$80,000"). Compound fields (like addresses) require constituent fields (e.g., BillingCity, BillingStreet) — do not attempt to set the compound wrapper itself.

Transactional Semantics: allOrNone

The uiapi mutation input accepts an allOrNone argument that controls rollback behavior:

  • allOrNone: true (default) — If any operation fails, all operations in the request are rolled back. Use when operations must succeed or fail together.
  • allOrNone: false — Independent operations can succeed individually. However, dependent operations (those using @{alias} references) still roll back together with their dependencies.

Always set allOrNone explicitly to make transactional intent clear.

Mutation Schema Patterns

Replace EntityName with the actual entity name (e.g., Account, Case). Delete operations use generic Record types.

input EntityNameCreateRepresentation {
  # Subset of EntityName fields
}
input EntityNameCreateInput { EntityName: EntityNameCreateRepresentation! }
type EntityNameCreatePayload { Record: EntityName! }

input EntityNameUpdateRepresentation {
  # Subset of EntityName fields
}
input EntityNameUpdateInput { Id: IdOrRef! EntityName: EntityNameUpdateRepresentation! }
type EntityNameUpdatePayload { Record: EntityName! }

input RecordDeleteInput { Id: IdOrRef! }
type RecordDeletePayload { Id: ID }

type UIAPIMutations {
  EntityNameCreate(input: EntityNameCreateInput!): EntityNameCreatePayload
  EntityNameDelete(input: RecordDeleteInput!): RecordDeletePayload
  EntityNameUpdate(input: EntityNameUpdateInput!): EntityNameUpdatePayload
}

Input Field Constraints

Create

  • Must include all required fields (unless defaultedOnCreate is true and not explicitly requested)
  • Must only include createable fields
  • Child relationships cannot be set — exclude them
  • Reference fields (REFERENCE type) can only be assigned IDs through their ApiName name
  • No nested child creates — Creating a record with child relationships in a single create operation is not supported. To create a parent and child together, use separate operations with IdOrRef chaining (see Mutation Chaining).

Update

  • Must include the Id of the entity to update
  • Must only include updateable fields
  • Child relationships cannot be set — exclude them
  • Reference fields (REFERENCE type) can only be assigned IDs through their ApiName name

Delete

  • Must include the Id of the entity to delete

Output Field Constraints

Create and Update

  • Must exclude all child relationships (child relationships cannot be queried in mutations)
  • Must exclude all REFERENCE fields unless accessed through their ApiName member (no navigation to referenced entity, no sub fields)
  • Inaccessible fields are reported in the errors attribute of the returned payload

Delete

  • Must only include the Id field

Mutation Chaining

Chain related mutations in a single request using references to Id values from previous mutations. This is the required approach for creating parent-child records together, since nested child creates are not supported.

  1. Ordering — Mutation B can reference mutation A only if A comes first in the query
  2. Notation — Use SomeId: "@{A}" in mutation B to set a field to the Id produced by mutation A
  3. IDs only@{A} is always interpreted as the Id from mutation A
  4. RestrictionsA must be a Create or Delete mutation (chaining from Update will fail)

Chaining Example

mutation CreateAccountAndContact {
  uiapi(input: { allOrNone: true }) {
    AccountCreate(input: { Account: { Name: "Acme" } }) {
      Record { Id }
    }
    ContactCreate(input: { Contact: { LastName: "Smith", AccountId: "@{AccountCreate}" } }) {
      Record { Id }
    }
  }
}

Mutation Query Template

mutation mutateEntityName(
  # arguments
) {
  uiapi(input: { allOrNone: true }) {
    EntityNameOperation(input: {
      # For Create and Update only:
      EntityName: {
        # Input fields — use raw values, no formatting
      }
      # For Update and Delete only:
      Id: ... # id here
    }) {
      # For Create and Update only:
      Record {
        # Output fields
      }
      # For Delete only:
      Id
    }
  }
}