Hooks (Before & After)
Hooks let you attach edge function logic to database mutations. There are two types:
| Hook Type | Timing | Execution | Use Cases |
|---|---|---|---|
| Before hook | Before the DB mutation | Synchronous — can block or modify | Validation, enrichment, business rule enforcement |
| After hook | After successful DB mutation | Asynchronous — non-blocking | Notifications, analytics, cascade actions |
Before Hooks
Section titled “Before Hooks”A before hook is called synchronously by pulsabase-core before the SQL query is executed. The hook receives the incoming payload and can:
- Allow the operation (return normally)
- Block the operation (return an error or non-2xx status)
- (Future) Modify the payload before it hits the database
Common Use Cases
Section titled “Common Use Cases”- Enforce business rules beyond what RLS can express (e.g., “a user can only be in 5 rooms”)
- Validate computed fields that span multiple tables
- Block mutations outside business hours or maintenance windows
Configuring a Before Hook
Section titled “Configuring a Before Hook”- Go to Dashboard → Edge Functions → Hooks
- Click New Hook
- Select Before as the hook type
- Choose the target table and action (
INSERT,UPDATE, orDELETE) - Select the edge function to invoke
Example: Enforce Room Limit
Section titled “Example: Enforce Room Limit”Function: check-room-limit
Step 1: get_count → [Database] SELECT COUNT(*) as count FROM room_members WHERE user_id = {{jwt.sub}}
Step 2: check → [Condition] {{steps.get_count.body.count}} >= 5
If TRUE → return { "error": "MAX_ROOMS_REACHED", "status": 400 } If FALSE → continue (allow the INSERT)When a user tries to join a 6th room, the before hook returns a 400 response and the INSERT is never executed.
After Hooks
Section titled “After Hooks”An after hook is triggered asynchronously via NATS after a successful database mutation. The original operation completes immediately — the hook runs in the background.
Common Use Cases
Section titled “Common Use Cases”- Send a notification when a new message is inserted
- Update a materialized view or a denormalized counter
- Log to an external analytics system
- Trigger a cascade delete on an external service
Configuring an After Hook
Section titled “Configuring an After Hook”- Go to Dashboard → Edge Functions → Hooks
- Click New Hook
- Select After as the hook type
- Choose the target table and action
- Select the edge function to invoke
Example: New Message Notification
Section titled “Example: New Message Notification”Hook: after INSERT on messages
Function: notify-room-members
Step 1: get_members → [Database] SELECT user_id FROM room_members WHERE room_id = {{input.room_id}}
Step 2: send → [HTTP] POST https://push.example.com/notify Body: { "users": {{steps.get_members.body}}, "message": "New message in {{input.room_name}}" }Sync vs. Async Execution
Section titled “Sync vs. Async Execution”By default, edge functions invoked via hooks run asynchronously (after hooks) or synchronously (before hooks). When you invoke a function directly via the SDK, you can explicitly choose:
// Synchronous invocation — waits for the full resultconst result = await pb.edge('check-room-limit').invoke({ userId, roomId });
// Async invocation — fire and forget, does not wait for resultawait pb.edge('send-welcome-email').invokeAsync({ userId });