Skip to main content

Overview

Mutations allow you to modify data in the RealtimeChat system. All message mutations automatically trigger real-time updates to subscribed clients.
All mutations automatically publish events to the MessageUpdated subscription topic, enabling real-time updates for connected clients.

SendMessage

Send a new message to a chat room. This mutation creates a message and broadcasts an ADDED event to all subscribers.

Parameters

chatRoomId
Int!
required
The ID of the chat room to send the message to
senderId
String!
required
The identifier of the user sending the message
text
String!
required
The text content of the message

Return Type

MessageGraph! - The newly created message object

GraphQL Schema

type Mutation {
  sendMessage(
    chatRoomId: Int!
    senderId: String!
    text: String!
  ): MessageGraph!
}

type MessageGraph {
  id: Int!
  sentAt: DateTime!
  senderId: String!
  chatRoomId: Int!
  content: MessageContent!
}

Example Mutation

mutation SendMessage {
  sendMessage(
    chatRoomId: 1
    senderId: "user123"
    text: "Hello, everyone!"
  ) {
    id
    sentAt
    senderId
    chatRoomId
    content {
      ... on TextMessageContentGraph {
        text
      }
    }
  }
}

Example Response

{
  "data": {
    "sendMessage": {
      "id": 104,
      "sentAt": "2026-03-05T10:45:00Z",
      "senderId": "user123",
      "chatRoomId": 1,
      "content": {
        "text": "Hello, everyone!"
      }
    }
  }
}

Real-Time Event

After execution, this mutation publishes an event to subscribers:
{
  "eventType": "ADDED",
  "message": {
    "id": 104,
    "sentAt": "2026-03-05T10:45:00Z",
    "senderId": "user123",
    "chatRoomId": 1,
    "content": {
      "text": "Hello, everyone!"
    }
  }
}

Implementation Details

From MessageMutation.cs:11-29:
public async Task<MessageGraph> SendMessage(
    [Service] IMessageRepository messageRepository, 
    int chatRoomId, 
    string senderId, 
    string text)
{
    var message = await messageRepository.AddAsync(new Message
    {
        SenderId = senderId,
        ChatRoomId = chatRoomId,
        Content = new TextMessageContent(text)
    });
    
    var messageGraph = mapper.Map<MessageGraph>(message);

    await eventSender.SendAsync("MessageUpdated", new MessageUpdatedEvent
    {
        EventType = "ADDED",
        Message = messageGraph
    });

    return messageGraph;
}

EditMessage

Update the content of an existing message. This mutation broadcasts an UPDATED event to all subscribers.

Parameters

messageId
Int!
required
The ID of the message to edit
newText
String!
required
The new text content for the message

Return Type

MessageGraph! - The updated message object

GraphQL Schema

type Mutation {
  editMessage(
    messageId: Int!
    newText: String!
  ): MessageGraph!
}

Example Mutation

mutation EditMessage {
  editMessage(
    messageId: 104
    newText: "Hello, everyone! (edited)"
  ) {
    id
    sentAt
    senderId
    chatRoomId
    content {
      ... on TextMessageContentGraph {
        text
      }
    }
  }
}

Example Response

{
  "data": {
    "editMessage": {
      "id": 104,
      "sentAt": "2026-03-05T10:45:00Z",
      "senderId": "user123",
      "chatRoomId": 1,
      "content": {
        "text": "Hello, everyone! (edited)"
      }
    }
  }
}

Real-Time Event

After execution, this mutation publishes an event:
{
  "eventType": "UPDATED",
  "message": {
    "id": 104,
    "sentAt": "2026-03-05T10:45:00Z",
    "senderId": "user123",
    "chatRoomId": 1,
    "content": {
      "text": "Hello, everyone! (edited)"
    }
  }
}

Implementation Details

From MessageMutation.cs:31-44:
public async Task<MessageGraph> EditMessage(
    [Service] IMessageRepository messageRepository, 
    int messageId, 
    string newText)
{
    var message = await messageRepository.UpdateContentAsync(
        messageId, 
        new TextMessageContent(newText)
    );
    
    var messageGraph = mapper.Map<MessageGraph>(message);
    
    await eventSender.SendAsync("MessageUpdated", new MessageUpdatedEvent
    {
        EventType = "UPDATED",
        Message = messageGraph
    });

    return messageGraph;
}
The sentAt timestamp is not modified when editing a message.

DeleteMessage

Delete a message from a chat room. This mutation broadcasts a DELETED event to all subscribers.

Parameters

messageId
Int!
required
The ID of the message to delete

Return Type

MessageGraph! - The deleted message object (before deletion)

GraphQL Schema

type Mutation {
  deleteMessage(messageId: Int!): MessageGraph!
}

Example Mutation

mutation DeleteMessage {
  deleteMessage(messageId: 104) {
    id
    senderId
    chatRoomId
    content {
      ... on TextMessageContentGraph {
        text
      }
    }
  }
}

Example Response

{
  "data": {
    "deleteMessage": {
      "id": 104,
      "senderId": "user123",
      "chatRoomId": 1,
      "content": {
        "text": "Hello, everyone! (edited)"
      }
    }
  }
}

Real-Time Event

After execution, this mutation publishes an event:
{
  "eventType": "DELETED",
  "message": {
    "id": 104,
    "senderId": "user123",
    "chatRoomId": 1,
    "content": {
      "text": "Hello, everyone! (edited)"
    }
  }
}

Implementation Details

From MessageMutation.cs:46-58:
public async Task<MessageGraph> DeleteMessage(
    [Service] IMessageRepository messageRepository, 
    int messageId)
{
    var message = await messageRepository.DeleteAsync(messageId);
    var messageGraph = mapper.Map<MessageGraph>(message);
    
    await eventSender.SendAsync("MessageUpdated", new MessageUpdatedEvent
    {
        EventType = "DELETED",
        Message = messageGraph
    });

    return messageGraph;
}
The mutation returns the message data before deletion, allowing clients to display what was deleted or implement undo functionality.

Complete Mutation Example

Here’s a complete example demonstrating all three mutations in sequence:
# 1. Send a new message
mutation {
  sendMessage(
    chatRoomId: 1
    senderId: "user123"
    text: "Initial message"
  ) {
    id
    content {
      ... on TextMessageContentGraph {
        text
      }
    }
  }
}

# 2. Edit the message
mutation {
  editMessage(
    messageId: 104
    newText: "Updated message"
  ) {
    id
    content {
      ... on TextMessageContentGraph {
        text
      }
    }
  }
}

# 3. Delete the message
mutation {
  deleteMessage(messageId: 104) {
    id
  }
}

Error Handling

Mutations may return errors in the following scenarios:
Message not found
When trying to edit or delete a non-existent message
Chat room not found
When sending a message to a non-existent chat room
Invalid input
When required parameters are missing or invalid
Example error response:
{
  "errors": [
    {
      "message": "Sequence contains no elements",
      "path": ["editMessage"],
      "extensions": {
        "code": "ENTITY_NOT_FOUND"
      }
    }
  ],
  "data": null
}

Source Code Reference

The mutations are implemented in:
  • Infrastructure/RealtimeChat.Infrastructure.GraphQL/Mutations/MessageMutation.cs
Related types:
  • Infrastructure/RealtimeChat.Infrastructure.GraphQL/Models/MessageGraph.cs
  • Infrastructure/RealtimeChat.Infrastructure.GraphQL/Events/MessageUpdatedEvent.cs

Next Steps

Subscriptions

Learn how to subscribe to real-time message updates triggered by these mutations

Build docs developers (and LLMs) love