Webhooks

June 10, 2026 · View on GitHub

DataSurface can publish events when CRUD operations occur. Webhooks are useful for integrations, audit trails, event-driven architectures, and triggering downstream workflows.


Setup

Webhooks activate automatically when an IWebhookPublisher is registered in DI — there is no flag to toggle. Register a publisher and CRUD mutations are published to it.

Implement a Publisher

using DataSurface.Core.Webhooks;

public class MyWebhookPublisher : IWebhookPublisher
{
    private readonly HttpClient _http;
    private readonly ILogger<MyWebhookPublisher> _logger;

    public MyWebhookPublisher(HttpClient http, ILogger<MyWebhookPublisher> logger)
    {
        _http = http;
        _logger = logger;
    }

    public async Task PublishAsync(WebhookEvent evt, CancellationToken ct)
    {
        _logger.LogInformation("Webhook: {Operation} on {Resource} id={Id}",
            evt.Operation, evt.ResourceKey, evt.EntityId);

        await _http.PostAsJsonAsync("https://hooks.example.com/datasurface", evt, ct);
    }
}

builder.Services.AddSingleton<IWebhookPublisher, MyWebhookPublisher>();

WebhookEvent

Published after every create, update, and delete operation:

PropertyTypeDescription
ResourceKeystringThe resource that changed (e.g., "User")
OperationCrudOperationCreate, Update, or Delete
EntityIdstring?ID of the affected entity
TimestampDateTimeUTC timestamp of the event
PayloadJsonObject?JSON representation of the entity (for create/update)

Create/update payloads are built from the API response after field-authorization redaction, so fields the caller cannot read never appear in webhook payloads.

Example Payload

{
  "resourceKey": "User",
  "operation": "Create",
  "entityId": "42",
  "timestamp": "2024-12-28T14:30:00Z",
  "payload": {
    "id": 42,
    "email": "alice@example.com",
    "name": "Alice"
  }
}

WebhookSubscription

The WebhookSubscription record defines how subscriptions are configured:

PropertyTypeDescription
IdstringUnique subscription identifier
UrlstringTarget URL to receive webhook events
ResourceKeystring?Filter to specific resource (null = all resources)
OperationsIReadOnlyList<CrudOperation>?Filter to specific operations (null = all operations)
Secretstring?Shared secret for HMAC signature verification
IsActiveboolWhether the subscription is active

Failure Handling

  • Webhook publishing is fire-and-forget by default
  • Failures are logged but do not fail the CRUD operation
  • The CRUD operation completes successfully regardless of webhook delivery status
  • Inside a bulk transaction (useTransaction = true), events are buffered and published only after the transaction commits — a rolled-back batch publishes nothing
  • Implement retry logic, dead-letter queues, or circuit breakers in your IWebhookPublisher as needed