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
    }