---
title: Separate Parsing From Controllers
impact: HIGH
impactDescription: keeps controllers thin and focused on HTTP orchestration
tags: controller, parsing, transformation, patterns, quality, php
---

## Separate Parsing From Controllers

Controllers should be "thin" and focus only on orchestrating HTTP concerns: receiving requests, calling services, and returning responses. Complex data transformation or parsing logic should be extracted into dedicated classes like Resources, Transformers, or Mappers.

**Incorrect (transformation logic in Controller):**

```php
class UserController extends Controller {
    public function show($id) {
        $user = User::findOrFail($id);
        
        // Complex transformation in controller
        return response()->json([
            'id' => $user->id,
            'full_name' => $user->first_name . ' ' . $user->last_name,
            'email' => strtolower($user->email),
            'member_since' => $user->created_at->format('Y-m-d'),
            'can_delete' => $user->id !== auth()->id()
        ]);
    }
}
```

**Correct (using a Resource or Transformer):**

```php
/**
 * Using Laravel API Resources (Recommended)
 */
class UserResource extends JsonResource {
    public function toArray($request) {
        return [
            'id' => $this->id,
            'full_name' => $this->first_name . ' ' . $this->last_name,
            'email' => strtolower($this->email),
            'member_since' => $this->created_at->format('Y-m-d'),
            'can_delete' => $this->id !== auth()->id()
        ];
    }
}

/**
 * Clean Controller
 */
class UserController extends Controller {
    public function show($id) {
        $user = User::findOrFail($id);
        return new UserResource($user);
    }
}
```

**Benefits:**
- **Reusability**: Use the same transformation logic in different controllers or for nested relationships.
- **Maintainability**: Changing the API response format only requires editing one resource class.
- **Testability**: You can unit test the Resource/Transformer class independently of the HTTP request.
- **Separation of Concerns**: Controllers handle "How to respond", Resources handle "What the response looks like".

**Tools:** Laravel API Resources, league/fractal, Spatie Data Transfer Objects, PR review
