Skip to content

Flow Validation

Overview

The Flow Validation system ensures flows meet specific requirements before they can be saved or executed. This document explains how validation works and how to create your own custom validation rules.

Core Components

FlowValidationRule Interface

All validation rules must implement this interface with three required methods:

  • validate(Collection $nodes, string $flowName): Performs the validation logic
  • getId(): Returns a unique identifier for the rule
  • getMessage(): Returns the error message when validation fails
php
<?php

namespace Modules\FlowBuilder\Contracts;

use Illuminate\Support\Collection;
use Modules\FlowBuilder\Responses\ValidationResponse;
use Modules\FlowBuilder\Support\DrawflowNode;

interface FlowValidationRule
{
    /**
     * Validate a flow against this rule
     *
     * @param Collection<DrawflowNode> $nodes The nodes in the flow
     * @param string $flowName The name of the flow
     * @return ValidationResponse Validation result with valid status and message if invalid
     */
    public function validate(Collection $nodes, string $flowName): ValidationResponse;

    /**
     * Get the unique identifier for this validation rule
     */
    public function getId(): string;

    /**
     * Get the error message for this validation rule
     */
    public function getMessage(): string;
}

BaseFlowValidationRule Class

For easier implementation of validation rules, a base class is provided. Instead of implementing the FlowValidationRule interface directly, it's now recommended to extend this base class:

The base class implements common functionality:

  • Properties for $id and $message that you can set in your child class
  • Implementations of getId() and getMessage() methods
  • A helper makeResponse() method to create ValidationResponse objects

ValidationResponse Class

A simple data object that standardizes validation results:

  • valid (bool): Whether validation passed
  • message (string): Error message when validation fails
  • nodesWithErrors (nullable array): Nodes that failed validation, if applicable

FlowValidator Facade

Provides a convenient way to register and use validation rules:

php
// Register a rule
FlowValidator::register(YourValidationRule::class);

// Validate a flow
$result = FlowValidator::validate($nodes, $flowSlug);

Node-Specific Validation Rules

Nodes can have their own validation rules which will be automatically registered with the system. This is done by defining a $validationRules property in the node class:

php
class HttpNode extends BaseNode implements CanBeExecuted
{
    public string $id = 'http_node';
    
    // Other node properties...
    
    public ?array $validationRules = [
        HttpJsonFieldsValidationRule::class,
    ];
    
    // Implementation...
}

Creating Custom Validation Rules

Step 1: Create the Rule Class

php
<?php

namespace Modules\YourModule\ValidationRules;

use Illuminate\Support\Collection;
use Modules\FlowBuilder\Responses\ValidationResponse;
use Modules\FlowBuilder\Support\BaseFlowValidationRule;
use Modules\FlowBuilder\Support\DrawflowNode;

class YourValidationRule extends BaseFlowValidationRule
{
    protected ?string $id = 'your-validation-rule-id';

    public function validate(Collection $nodes, string $flowName): ValidationResponse
    {
        // Implement your validation logic
        $isValid = true; // Replace it with actual validation
        
        // Example: check if the flow has at least 3 nodes
        $isValid = $nodes->count() >= 3;

        return $this->makeResponse(valid: $isValid);
    }
    
    public function getMessage(): string
    {
        return __('Your custom validation message here');
    }
}

Step 2: Register the Rule

Add this to your module's service provider:

php
use Modules\FlowBuilder\Facades\FlowValidator;
use Modules\YourModule\ValidationRules\YourValidationRule;

public function boot(): void
{
    FlowValidator::register(YourValidationRule::class);
}

Complete Validation Rule Example

Here's a complete example of a validation rule that checks if a flow contains at least one trigger node:

php
class TriggerValidationRule extends BaseFlowValidationRule
{
    protected ?string $id = 'trigger-validation-rule';

    public function validate(Collection $nodes, string $flowName): ValidationResponse
    {
        return $this->makeResponse(
            valid: $nodes->contains(
                fn (DrawflowNode $node) => str_contains(strtolower($node->getClass()), 'trigger')
            ),
        );
    }

    public function getMessage(): string
    {
        return __('Flow must have at least one trigger node');
    }
}

Another Examples:

  • HttpJsonFieldsValidationRule: Validates that HTTP nodes have required JSON fields.
  • TriggerValidationRule: Ensures at least one trigger node exists in the flow.
  • CronIsValidValidationRule: Checks if cron nodes have valid cron expressions.

When Validation is Executed

The validation system is automatically executed when a user tries to save a flow through the Flow Builder UI.