Logic Recipe
A Recipe enables citizen developers to associate business logic with entity events in Dataverse. It dictates when and how to apply particular logic during an entity's lifecycle - create, update, or delete. Recipes are the bridge between your business logic (Logic Blocks and Flows) and Dataverse entity operations.
The Challenge: Scattered Plugin Logic
In traditional Dataverse development, business logic tied to entity events is implemented through plugins and workflows. This approach has several challenges:
- Technical Barrier: Plugins require C# development skills, putting them out of reach for citizen developers
- Deployment Complexity: Plugin changes require compilation, registration, and deployment
- Scattered Logic: Business rules are spread across multiple plugins, making them hard to understand and maintain
- Limited Visibility: Non-developers can't easily see what logic runs when records are created, updated, or deleted
- Testing Difficulty: Plugins must be tested in context of Dataverse, making unit testing challenging
The Solution: Centralized Recipe Configuration
Recipes provide a no-code, centralized way to define what happens when entity records are created, updated, or deleted. Instead of writing plugin code, you configure recipes that:
- Validate data before changes are committed
- Execute logic at precise points in the entity lifecycle
- Orchestrate existing Logic Blocks and Flows
- Control execution synchronously or asynchronously
Recipe Structure
A Recipe is defined for a specific entity and consists of three main event sections:
| Component | Description |
|---|---|
| Name | Unique identifier for the recipe |
| Project | The Flowon Project this recipe belongs to |
| Entity | The Dataverse entity this recipe responds to (Account, Contact, Opportunity, custom entities, etc.) |
| Create | Logic to execute when a record is created |
| Update | Logic to execute when a record is updated |
| Delete | Logic to execute when a record is deleted |
Event Lifecycle Phases
Each event (Create, Update, Delete) has distinct phases where you can inject logic:
┌──────────────────────────────────────────────────────────────────────────────┐
│ ENTITY EVENT LIFECYCLE │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌──────────────┐ │
│ │ VALIDATION │ ──► │ PRE-EVENT │ ──► │ DATABASE │ │
│ │ Phase │ │ Phase │ │ OPERATION │ │
│ └─────────────┘ └─────────────┘ └──────────────┘ │
│ │ │ │ │
│ │ │ ▼ │
│ │ │ ┌──────────────┐ │
│ │ │ │ POST-EVENT │ │
│ │ │ │ Phase │ │
│ │ │ └──────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ Run Logic Blocks Run Flows/BPs Run Flows/BPs │
│ (Validation) (Sync or Async) (Sync or Async) │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
Phase Details
Validation Phase
The Validation phase runs first, before any database operation occurs. This is where you enforce business rules that must pass before the operation can proceed.
| Property | Description |
|---|---|
| Purpose | Validate data and enforce business rules |
| Executes | Logic Blocks only (Validations, Validation Sets, Decision Tables, etc.) |
| Timing | Before any database changes |
| On Failure | Operation is cancelled; error message returned to user |
| Transaction | Within the database transaction (rollback on failure) |
Use Cases:
- Ensure required fields have valid values
- Validate business rule compliance (credit limits, approval thresholds)
- Check referential integrity across related records
- Enforce data format requirements
Pre-Event Phase
The Pre-Event phase runs after validation passes but before the database operation commits. This allows you to modify data or perform related operations that must complete before the main operation.
| Property | Description |
|---|---|
| Purpose | Execute logic before the database operation |
| Executes | Logic Flows or Business Processes |
| Execution Mode | Synchronous or Asynchronous |
| Timing | After validation, before database commit |
| Transaction | Sync: Within transaction / Async: Separate transaction |
Use Cases:
- Auto-populate calculated fields
- Set default values based on business logic
- Create related records that must exist before the main record
- Log audit information
- Notify systems that need to prepare for the change
Post-Event Phase
The Post-Event phase runs after the database operation has successfully completed. This is for actions that depend on the record existing in its new state.
| Property | Description |
|---|---|
| Purpose | Execute logic after the database operation completes |
| Executes | Logic Flows or Business Processes |
| Execution Mode | Synchronous or Asynchronous |
| Timing | After database commit |
| Transaction | Sync: Extended transaction / Async: Separate transaction |
Use Cases:
- Send notification emails
- Update related records
- Sync data to external systems
- Trigger downstream workflows
- Generate documents
- Update aggregated/rollup data
Synchronous vs. Asynchronous Execution
For Pre-Event and Post-Event phases, you choose whether each Flow or Business Process runs synchronously or asynchronously:
| Mode | Behavior | Best For |
|---|---|---|
| Synchronous | User waits for completion; failures can roll back the transaction | Critical operations that must complete; operations where user needs immediate feedback |
| Asynchronous | Executes in background; user doesn't wait; failures don't affect main operation | Long-running processes; non-critical updates; external system integrations; email notifications |
Execution Order
When an entity event triggers, the Recipe executes in this precise order:
For Create Events:
- Validation Logic Blocks (in order defined) → If any fails, operation cancelled
- Pre-Create Flows/BPs (in order defined) → Sync waits; Async queued
- Database INSERT operation
- Post-Create Flows/BPs (in order defined) → Sync waits; Async queued
For Update Events:
- Validation Logic Blocks (in order defined) → If any fails, operation cancelled
- Pre-Update Flows/BPs (in order defined) → Sync waits; Async queued
- Database UPDATE operation
- Post-Update Flows/BPs (in order defined) → Sync waits; Async queued
For Delete Events:
- Validation Logic Blocks (in order defined) → If any fails, operation cancelled
- Pre-Delete Flows/BPs (in order defined) → Sync waits; Async queued
- Database DELETE operation
- Post-Delete Flows/BPs (in order defined) → Sync waits; Async queued
Data Available in Each Phase
Different data is available depending on the event and phase:
| Event | Phase | Available Data |
|---|---|---|
| Create | Validation | New record values (before save) |
| Create | Pre-Create | New record values (before save) |
| Create | Post-Create | Created record with ID |
| Update | Validation | Changed fields, pre-image (before), post-image (after) |
| Update | Pre-Update | Changed fields, pre-image, post-image |
| Update | Post-Update | Updated record, pre-image |
| Delete | Validation | Record to be deleted (pre-image) |
| Delete | Pre-Delete | Record to be deleted (pre-image) |
| Delete | Post-Delete | Deleted record ID, pre-image (snapshot before deletion) |
Try It Live
Watch the full Recipe lifecycle run automatically - validation gates the operation, pre-event flows prepare the data, the database commits, then post-event flows execute downstream logic. The simulator cycles through all three event types and shows what happens when validation fails.
Best Practices
Keep Validation Logic Fast: Validation runs synchronously and blocks the user. Use efficient Logic Blocks that execute quickly. Complex validations that query many records should be optimized.
Use Async for Non-Critical Operations: Email notifications, external system syncs, and logging don't need to block the user. Run them asynchronously.
Use Sync for Data Integrity: Operations that must complete for data consistency (calculating totals, creating required related records) should run synchronously.
Order Matters: Logic Blocks and Flows execute in the order defined. Place dependencies before dependents.
Handle Async Failures Gracefully: Asynchronous operations can fail without affecting the main operation. Implement error handling and retry logic in your Flows.
One Recipe Per Entity: Define one comprehensive Recipe per entity rather than multiple overlapping recipes. This keeps logic centralized and predictable.
Test Validation Thoroughly: Validation failures are visible to users. Ensure error messages are clear and helpful. Test edge cases.
Consider Performance: Many synchronous operations slow down the user experience. Balance between data integrity needs and user experience.
Document Your Recipe: Use descriptions to document why each Logic Block and Flow is included. Future maintainers will thank you.