Skip to content

[Enh]: Support Web Hooks Post-CRUD Operations #3230

@JerryNixon

Description

@JerryNixon

What?

Support web hooks that trigger before and after CRUD operations on an entity.

  • Allows an external service to enforce custom business rules.
  • Allows centralized validation across multiple APIs or services.
  • Enables auditing and compliance logging of data access and mutations.
  • Enables integration with messaging or event systems.
  • Enables cache invalidation or search index updates after data changes.
  • Enables security checks such as fraud detection or policy enforcement.
  • Enables observability and telemetry for downstream monitoring systems.

Note

This feature supports any HTTP webhook endpoint, including services that publish events to external systems or HTTP-triggered Azure Functions.

Process flow

sequenceDiagram
    participant Client
    participant DAB
    participant Before as Before Hook
    participant DB as Database
    participant After as After Hook

    Client->>DAB: Request
    DAB->>Before: POST

    alt stop
        Before-->>DAB: stop
        DAB-->>Client: Error response
    else non-2xx
        Before-->>DAB: non-2xx
        DAB-->>Client: Error response
    else 2xx
        Before-->>DAB: Continue
        DAB->>DB: CRUD
        DB-->>DAB: Result
        DAB-->>Client: Response
        DAB-->>+After: POST (async)
    end
Loading

Before

Outbound payload (to the webhook)

{
  "action": "create | read | update | delete | execute",
  "entity": "Book",
  "timestamp": "2026-03-14T18:22:11Z",
  "correlationId": "7b9c5c3e-21d3-4c64-a9e2-4e2e4b0f4f7c",
  "source": "rest | graphql | mcp",
  "userRole": "authenticated",
  "requestData": {
    "id": 10,
    "title": "Dune",
    "author": "Frank Herbert"
  }
}
Field Description
action Operation that triggered the hook: create, read, update, delete, or execute.
entity Entity name defined in the DAB configuration.
timestamp UTC time when the event occurred.
correlationId Unique identifier used to correlate the webhook with the original API request.
source API surface that triggered the operation: rest, graphql, or mcp.
userRole Role assigned to the caller after DAB authorization.
requestData Data submitted in the API request that triggered the operation. For read, this may contain query parameters or filter information rather than entity data.

Inbound payload (from the webhook)

Important

A webhook may return HTTP status 200 with no payload. In this case, the request proceeds unchanged.

{
  "correlationId": "7b9c5c3e-21d3-4c64-a9e2-4e2e4b0f4f7c",
  "updateRequestData": {
    "title": "New value"
  }
}
Field Description
correlationId Identifier matching the original webhook request so DAB can associate the response with the correct operation. Generated from the OpenTelemetry trace or span context.
updateRequestData Optional object containing field changes the webhook wants to apply before the operation continues.

The before-hook can return updateRequestData to mutate the request.

  1. Any values in updateRequestData not in the request are ignored.
  2. Any fields, including the primary key fields can be modified.
  3. Request substitutions occur before mutation, so authentication is not impacted.

Abort example

{
  "correlationId": "7b9c5c3e-21d3-4c64-a9e2-4e2e4b0f4f7c",
  "stop": {
    "reason": "error message"
  }
}
Field Description
correlationId Identifier matching the original webhook request so DAB can associate the response with the correct operation. Generated from the OpenTelemetry trace or span context.
stop Indicates the operation should not continue.
stop.reason Human readable explanation for why the request should be rejected. Returned to the client as the error message.

Automatic outbound headers

x-dab-action: create
x-dab-entity: Book
x-dab-source: rest
x-dab-correlation-id: 7b9c5c3e-21d3-4c64-a9e2-4e2e4b0f4f7c

Note

This is valuable for programmability, but also for telemetry and logging.

After

Outbound payload (to the webhook)

{
  "action": "create | read | update | delete | execute",
  "entity": "Book",
  "timestamp": "2026-03-14T18:22:11Z",
  "correlationId": "7b9c5c3e-21d3-4c64-a9e2-4e2e4b0f4f7c",
  "source": "rest | graphql | mcp",
  "userRole": "authenticated",
  "result": "success | error",
  "responseData": {
    "id": 10,
    "title": "Dune",
    "author": "Frank Herbert"
  }
}
Field Description
action Operation that triggered the hook: create, read, update, delete, or execute.
entity Entity name defined in the DAB configuration.
timestamp UTC time when the event occurred.
correlationId Identifier used to correlate the webhook with the originating API request. Generated from the OpenTelemetry trace or span context.
source API surface that triggered the operation: rest, graphql, or mcp.
userRole Role assigned to the caller after DAB authorization.
result Outcome of the database operation: success or error.
responseData Record returned from the operation or the final persisted state of the entity. For read, this may contain query result metadata or returned records.

Inbound payload (from the webhook)

After is fire and forget, so there is no inbound payload.

Automatic outbound headers

x-dab-action: create
x-dab-entity: Book
x-dab-source: rest
x-dab-correlation-id: 7b9c5c3e-21d3-4c64-a9e2-4e2e4b0f4f7c

Note

These headers are identical to those sent for the before webhook.

Configuration

{
  "entities": {
    "Book": {
      "webhooks": {
        "before": {
          "enabled": true,
          "url": "https://example.com/hooks/before",
          "actions": ["*"],
          "timeout-seconds": 5,
          "abort-on-failure": true
        },
        "after": {
          "enabled": true,
          "url": "https://example.com/hooks/after",
          "actions": ["delete"]
        },
        "headers": {
          "x-api-key": "@env('WEBHOOK_SECRET')"
        }
      }
    }
  }
}

Important

This feature supports read, but it is not recommended due to potential performance and event rate impact.

Property Default Description
before.enabled false Enables the before webhook. Disabled by default to avoid unexpected request interception.
before.url "" Endpoint DAB calls before executing the operation. Required when before.enabled is true.
before.actions [] Operations that trigger the before webhook: create, read, update, delete, execute. Empty means no actions are enabled.
before.timeout-seconds 5 Maximum time DAB waits for the webhook response before continuing or failing the request.
before.abort-on-failure true Determines behavior when the webhook cannot be reached or returns a non-2xx response. Does not apply when the webhook explicitly returns stop.
after.enabled false Enables the after webhook, which runs asynchronously after the operation completes.
after.url "" Endpoint DAB calls after the operation completes. Required when after.enabled is true.
after.actions [] Operations that trigger the after webhook: create, read, update, delete, execute. Empty means no actions are enabled.
headers {} Optional HTTP headers included with webhook requests. Applied to both before and after hooks.

abort-on-failure

Failure scenario Example Should abort?
Connection refused Webhook endpoint is down Yes
DNS resolution failure URL is misconfigured Yes
Timeout exceeded Endpoint hangs beyond timeout-seconds Yes
HTTP 5xx Webhook server error Yes
HTTP 4xx Webhook explicitly rejects the operation Yes
HTTP 2xx Success No

Note

The contract is simple: anything other than a 2xx response, or an inability to get one, is treated as a failure.

Important

The abort-on-failure setting is independent of a stop instruction returned in a before webhook response. A stop always rejects the request regardless of the abort-on-failure value.

Command Line

dab update Book --webhooks.before.enabled true
dab update Book --webhooks.before.url "https://example.com/hooks/before"
dab update Book --webhooks.before.actions "create,read,update,delete,execute"
dab update Book --webhooks.before.timeout-seconds 5
dab update Book --webhooks.before.abort-on-failure true

dab update Book --webhooks.after.enabled true
dab update Book --webhooks.after.url "https://example.com/hooks/after"
dab update Book --webhooks.after.actions "create,read,update,delete,execute"

dab update Book --webhooks.headers "x-api-key:@env('WEBHOOK_SECRET')"

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions