Skip to main content

FlowStateResource

JSON resource class for transforming FlowState models into structured API responses. This resource provides a consistent format for state data with conditional relation loading.

Namespace

JobMetric\Flow\Http\Resources\FlowStateResource

Overview

The FlowStateResource transforms FlowState model instances into structured JSON responses. It includes:

  • Core state properties
  • Multi-language translations
  • Type and status information
  • Terminal state indicators
  • ISO 8601 formatted timestamps
  • Conditional relation loading

Base Properties

The resource always includes these properties:

PropertyTypeDescription
idintState ID
flow_idintParent flow ID
typestringState type (start, middle, end)
statusstring|nullStatus value (from flow's driver enum)
configobject|nullCustom configuration object
is_startboolWhether this is a START state
is_endboolWhether this is a terminal/END state
created_atstringISO 8601 formatted creation date
updated_atstringISO 8601 formatted update date

Conditional Properties

These properties are only included when their relations are loaded:

PropertyRelationTypeDescription
translationstranslationsobjectMulti-language translations
flowflowobjectFlowResource for parent flow
outgoingoutgoingarrayCollection of FlowTransitionResource (transitions from this state)
incomingincomingarrayCollection of FlowTransitionResource (transitions to this state)
taskstasksarrayCollection of FlowTaskResource

Type Handling

The type property is normalized to handle enum objects:

// If type is an enum object
$type = $this->type->value; // Extract value

// If type is a string
$type = $this->type; // Use directly

Terminal State Detection

The is_end property is determined by:

  1. Checking the is_end attribute if available
  2. Otherwise, checking config.is_terminal === true
'is_end' => (bool)($this->is_end ?? ($this->config?->is_terminal === true))

Usage Examples

Basic Usage

use JobMetric\Flow\Http\Resources\FlowStateResource;
use JobMetric\Flow\Models\FlowState;

$state = FlowState::find(1);

return FlowStateResource::make($state);

With Relations

$state = FlowState::with([
'flow',
'outgoing',
'incoming',
'tasks',
])->find(1);

return FlowStateResource::make($state);

In Collections

$states = FlowState::with('flow')->get();

return FlowStateResource::collection($states);

In API Responses

use JobMetric\Flow\Facades\FlowState;

public function show($id)
{
$state = FlowState::query()
->with(['flow', 'outgoing', 'incoming'])
->findOrFail($id);

return new FlowStateResource($state);
}

Response Examples

Basic Response

{
"id": 1,
"flow_id": 1,
"type": "start",
"status": null,
"config": null,
"is_start": true,
"is_end": false,
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
}

With Translations

{
"id": 1,
"translations": {
"en": {
"name": "Pending Review",
"description": "Order is pending review"
},
"fa": {
"name": "در انتظار بررسی",
"description": "سفارش در انتظار بررسی است"
}
},
"flow_id": 1,
"type": "middle",
"status": "pending",
// ... other fields
}

With Relations

{
"id": 1,
"flow_id": 1,
"type": "middle",
"status": "pending",
"flow": {
"id": 1,
"subject_type": "App\\Models\\Order",
// ... FlowResource fields
},
"outgoing": [
{
"id": 1,
"flow_id": 1,
"from": 1,
"to": 2,
// ... FlowTransitionResource fields
}
],
"incoming": [
{
"id": 2,
"flow_id": 1,
"from": 0,
"to": 1,
// ... FlowTransitionResource fields
}
],
"tasks": [
{
"id": 1,
"flow_transition_id": 1,
"driver": "App\\FlowTasks\\SendEmailTask",
// ... FlowTaskResource fields
}
]
}

Terminal State

{
"id": 5,
"flow_id": 1,
"type": "middle",
"status": "completed",
"config": {
"is_terminal": true,
"color": "#10B981",
"icon": "fas fa-check-circle"
},
"is_start": false,
"is_end": true,
// ... other fields
}

Relation Loading

Eager Loading Relations

// Load all relations
$state = FlowState::with([
'translations',
'flow',
'outgoing',
'incoming',
'tasks',
])->find(1);

Selective Loading

// Load only needed relations
$state = FlowState::with(['flow', 'outgoing'])->find(1);

Nested Relations

// Load nested relations
$state = FlowState::with([
'outgoing.toState',
'incoming.fromState',
'tasks.transition',
])->find(1);

Best Practices

  1. Load Relations Efficiently: Only load relations you need

    // ✅ Good
    FlowState::with(['flow', 'outgoing'])->get();

    // ❌ Bad
    FlowState::with(['flow', 'outgoing', 'incoming', 'tasks'])->get();
  2. Handle Status Values: Status can be null or enum value

    if ($state->status) {
    // Handle status
    }
  3. Check Terminal States: Use is_end for terminal state detection

    if ($state->is_end) {
    // Handle terminal state
    }