GraphQL Mutations
GraphQL Mutations
Section titled “GraphQL Mutations”Complete reference for all GraphQL mutations available in the platform. Mutations are write operations that create, update, or delete data.
Overview
Section titled “Overview”GraphQL mutations are auto-generated from service Command contracts. Each mutation:
- Uses POST semantics (state-changing)
- Requires input parameters via input types
- Returns typed output with operation results
- Filtered by user permissions
- May trigger domain events
Mutation Structure
Section titled “Mutation Structure”All mutations follow this pattern:
mutation OperationName($input: InputType!) { mutationName(input: $input) { success field1 field2 error }}Variables:
{ "input": { "parameter1": "value1", "parameter2": "value2" }}Authentication Mutations
Section titled “Authentication Mutations”CreateUser
Section titled “CreateUser”Create a new user account.
Permission Required: auth:create-user
mutation CreateUser($input: CreateUserInput!) { createUser(input: $input) { success userId email error validationErrors { field message } }}Variables:
{ "input": { "email": "newuser@example.com", "password": "SecurePassword123!", "profile": { "firstName": "Jane", "lastName": "Smith", "displayName": "Jane Smith", "timezone": "America/New_York" }, "initialRoles": ["user"], "skipEmailVerification": false }}Response:
{ "data": { "createUser": { "success": true, "userId": "user-456", "email": "newuser@example.com", "error": null, "validationErrors": null } }}Validation Error Example:
{ "data": { "createUser": { "success": false, "userId": null, "email": null, "error": "Validation failed", "validationErrors": [ { "field": "email", "message": "Email already exists" }, { "field": "password", "message": "Password must be at least 8 characters" } ] } }}UpdateUser
Section titled “UpdateUser”Update user profile or account settings.
Permission Required: auth:update-user
mutation UpdateUser($input: UpdateUserInput!) { updateUser(input: $input) { success user { id email profile { firstName lastName displayName } updatedAt } error }}Variables:
{ "input": { "userId": "user-123", "profile": { "firstName": "John", "lastName": "Updated", "timezone": "America/Los_Angeles" } }}AuthenticateUser
Section titled “AuthenticateUser”Authenticate with email and password.
Permission Required: None (public endpoint)
mutation AuthenticateUser($input: AuthenticateUserInput!) { authenticateUser(input: $input) { success accessToken refreshToken expiresIn user { id email permissions } error }}Variables:
{ "input": { "email": "user@example.com", "password": "SecurePassword123!" }}Response:
{ "data": { "authenticateUser": { "success": true, "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "expiresIn": 3600, "user": { "id": "user-123", "email": "user@example.com", "permissions": ["users:read", "orders:read"] }, "error": null } }}RefreshToken
Section titled “RefreshToken”Refresh an expired access token.
Permission Required: None (requires valid refresh token)
mutation RefreshToken($input: RefreshTokenInput!) { refreshToken(input: $input) { success accessToken expiresIn error }}Variables:
{ "input": { "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." }}RevokeToken
Section titled “RevokeToken”Revoke an active token (logout).
Permission Required: auth:revoke-token
mutation RevokeToken($input: RevokeTokenInput!) { revokeToken(input: $input) { success error }}Variables:
{ "input": { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." }}Role and Permission Mutations
Section titled “Role and Permission Mutations”CreateRole
Section titled “CreateRole”Create a new role with permissions.
Permission Required: auth:manage-roles
mutation CreateRole($input: CreateRoleInput!) { createRole(input: $input) { success roleName description permissions error }}Variables:
{ "input": { "roleName": "editor", "description": "Content editor role", "permissions": ["users:read", "users:create", "content:edit"] }}AssignRole
Section titled “AssignRole”Assign a role to a user.
Permission Required: auth:assign-roles
mutation AssignRole($input: AssignRoleInput!) { assignRole(input: $input) { success userId roleName error }}Variables:
{ "input": { "userId": "user-123", "roleName": "editor" }}UpdateRolePermissions
Section titled “UpdateRolePermissions”Update permissions for an existing role.
Permission Required: auth:manage-roles
mutation UpdateRolePermissions($input: UpdateRolePermissionsInput!) { updateRolePermissions(input: $input) { success roleName permissions error }}Variables:
{ "input": { "roleName": "editor", "permissions": ["users:read", "users:create", "content:edit", "content:publish"] }}AssignPermission
Section titled “AssignPermission”Assign a direct permission to a user (not via role).
Permission Required: auth:assign-permissions
mutation AssignPermission($input: AssignPermissionInput!) { assignPermission(input: $input) { success userId permission error }}Variables:
{ "input": { "userId": "user-123", "permission": "admin:view-logs" }}Session Management Mutations
Section titled “Session Management Mutations”CreateSession
Section titled “CreateSession”Create a new user session.
Permission Required: None (internal use)
mutation CreateSession($input: CreateSessionInput!) { createSession(input: $input) { success sessionId expiresAt error }}RefreshSession
Section titled “RefreshSession”Refresh an active session.
Permission Required: None (requires valid session)
mutation RefreshSession($input: RefreshSessionInput!) { refreshSession(input: $input) { success sessionId expiresAt error }}RevokeSession
Section titled “RevokeSession”Revoke a specific session.
Permission Required: auth:manage-sessions
mutation RevokeSession($input: RevokeSessionInput!) { revokeSession(input: $input) { success sessionId error }}RevokeAllUserSessions
Section titled “RevokeAllUserSessions”Revoke all sessions for a user (force logout everywhere).
Permission Required: auth:manage-sessions
mutation RevokeAllUserSessions($input: RevokeAllUserSessionsInput!) { revokeAllUserSessions(input: $input) { success userId revokedCount error }}Variables:
{ "input": { "userId": "user-123", "reason": "Security: password changed" }}Common Patterns
Section titled “Common Patterns”Transaction-Style Mutations
Section titled “Transaction-Style Mutations”Execute multiple related mutations:
mutation CreateUserWithRole($userInput: CreateUserInput!, $roleInput: AssignRoleInput!) { user: createUser(input: $userInput) { success userId error }
role: assignRole(input: $roleInput) { success error }}Note: Each mutation executes independently. Use sagas for true distributed transactions.
Conditional Mutations
Section titled “Conditional Mutations”mutation UpdateUserIfActive($input: UpdateUserInput!) { updateUser(input: $input) { success user { id isActive updatedAt } error }}Handle conditional logic in the handler or client based on response.
Optimistic Updates
Section titled “Optimistic Updates”Client-side pattern for better UX:
// Optimistically update UIupdateUserInCache(userId, newData);
// Execute mutationconst result = await apolloClient.mutate({ mutation: UPDATE_USER, variables: { input }});
// Rollback on errorif (!result.data.updateUser.success) { rollbackUserInCache(userId, oldData);}Error Handling
Section titled “Error Handling”Validation Errors
Section titled “Validation Errors”{ "data": { "createUser": { "success": false, "error": "Validation failed", "validationErrors": [ { "field": "email", "message": "Invalid email format" } ] } }}Permission Errors
Section titled “Permission Errors”{ "errors": [ { "message": "Missing required permission: auth:create-user", "path": ["createUser"], "extensions": { "code": "PERMISSION_DENIED" } } ], "data": null}Business Logic Errors
Section titled “Business Logic Errors”{ "data": { "assignRole": { "success": false, "error": "Role 'admin' cannot be assigned to external users", "userId": null, "roleName": null } }}Best Practices
Section titled “Best Practices”Input Validation
Section titled “Input Validation”Always validate inputs on the client before sending:
function validateCreateUserInput(input: CreateUserInput): string[] { const errors: string[] = [];
if (!input.email?.includes('@')) { errors.push('Invalid email format'); }
if (input.password.length < 8) { errors.push('Password must be at least 8 characters'); }
return errors;}Error Handling
Section titled “Error Handling”Check both GraphQL errors and business logic errors:
const result = await apolloClient.mutate({ mutation: CREATE_USER, variables: { input }});
// GraphQL-level errors (permissions, validation)if (result.errors) { handleGraphQLErrors(result.errors); return;}
// Business logic errors (custom validation)if (!result.data.createUser.success) { handleBusinessErrors(result.data.createUser.error); return;}
// SuccesshandleSuccess(result.data.createUser);Idempotency
Section titled “Idempotency”Some mutations should be idempotent (safe to retry):
mutation CreateUserIdempotent($input: CreateUserInput!) { createUser(input: $input) { success userId error # If user exists, returns existing userId instead of error }}Caching
Section titled “Caching”Mutations can update the cache automatically:
const result = await apolloClient.mutate({ mutation: UPDATE_USER, variables: { input }, update: (cache, { data }) => { if (data.updateUser.success) { cache.writeQuery({ query: GET_USER, variables: { userId: input.userId }, data: { getUser: data.updateUser.user } }); } }});Next Steps
Section titled “Next Steps”- GraphQL Queries - Read operations
- GraphQL Subscriptions - Real-time events
- GraphQL Schema - Complete type reference
- Authentication - JWT tokens and permissions