Controllers

مدیریت منطق کسب و کار و درخواست‌ها در Controllerها

graph TD A[Route] --> B[Controller] B --> C[Form Request Validation] C --> D[Service/Model] D --> E[Business Logic] E --> F[Response] F --> G{Type?} G -->|View| H[Blade View] G -->|JSON| I[JSON Response] G -->|Redirect| J[Redirect Response]

Controllerها کلاس‌هایی هستند که منطق کسب و کار را مدیریت می‌کنند و درخواست‌ها را پردازش می‌کنند. آنها پل ارتباطی بین routes و models هستند و مسئولیت تبدیل درخواست‌های HTTP به actions مناسب را بر عهده دارند.


وظایف Controller:


  • دریافت و پردازش درخواست‌های HTTP
  • اعتبارسنجی داده‌ها با استفاده از Form Requests
  • فراخوانی Service classes و Model methods
  • مدیریت session و flash messages
  • بازگرداندن Response (View، JSON، Redirect)
  • مدیریت errors و exceptions

اصول طراحی Controller:


  • <strong>Thin Controllers, Fat Models</strong>: منطق کسب و کار باید در Service classes یا Models باشد، نه در Controller
  • <strong>Single Responsibility</strong>: هر Controller باید یک resource را مدیریت کند
  • <strong>Dependency Injection</strong>: استفاده از DI برای وابستگی‌ها
  • <strong>Form Request Validation</strong>: استفاده از Form Requests برای validation
  • <strong>Resource Controllers</strong>: استفاده از Resource Controllers برای RESTful operations

انواع Controller:


  • <strong>Basic Controllers</strong>: Controllerهای ساده با methods دلخواه
  • <strong>Resource Controllers</strong>: Controllerهای RESTful با methods استاندارد
  • <strong>API Controllers</strong>: Controllerهای مخصوص API با JSON responses
  • <strong>Single Action Controllers</strong>: Controllerهای تک action با __invoke method

مثال‌ها

Controller ساده

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;

class UserController extends Controller
{
    public function index()
    {
        $users = User::all();
        return view('users.index', compact('users'));
    }
    
    public function show(User $user)
    {
        return view('users.show', compact('user'));
    }
}

یک Controller ساده که کاربران را نمایش می‌دهد.

Controller با Dependency Injection

<?php

namespace App\Http\Controllers;

use App\Services\UserService;
use App\Http\Requests\StoreUserRequest;

class UserController extends Controller
{
    public function __construct(
        private UserService $userService
    ) {}
    
    public function store(StoreUserRequest $request)
    {
        $user = $this->userService->createUser($request->validated());
        
        return redirect()->route('users.show', $user)
            ->with('success', 'User created successfully');
    }
}

Controller با dependency injection و Form Request validation.

API Controller

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Services\UserService;
use Illuminate\Http\JsonResponse;

class UserController extends Controller
{
    public function __construct(
        private UserService $userService
    ) {}
    
    public function index(): JsonResponse
    {
        $users = $this->userService->getAllUsers();
        
        return response()->json([
            'data' => $users,
            'message' => 'Users retrieved successfully'
        ]);
    }
    
    public function show(int $id): JsonResponse
    {
        $user = $this->userService->getUserById($id);
        
        return response()->json([
            'data' => $user,
            'message' => 'User retrieved successfully'
        ]);
    }
}

API Controller که JSON response برمی‌گرداند.

Single Action Controller

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ShowProfileController extends Controller
{
    public function __invoke(Request $request)
    {
        return view('profile', [
            'user' => $request->user()
        ]);
    }
}

// Route:
// Route::get('/profile', ShowProfileController::class);

Single Action Controller با __invoke method.

Controller با Middleware

<?php

namespace App\Http\Controllers;

class UserController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth')->except(['index', 'show']);
        $this->middleware('admin')->only(['destroy']);
        $this->middleware('throttle:60,1')->only(['store']);
    }
    
    public function index()
    {
        // Public access
    }
    
    public function store()
    {
        // Requires auth, rate limited
    }
    
    public function destroy()
    {
        // Requires auth and admin role
    }
}

اعمال middleware در constructor.

Controller با Response Helpers

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    public function index()
    {
        return view('users.index', ['users' => User::all()]);
    }
    
    public function store(Request $request)
    {
        // Redirect with message
        return redirect()->route('users.index')
            ->with('success', 'User created');
    }
    
    public function update(Request $request, User $user)
    {
        // JSON response
        return response()->json([
            'message' => 'User updated',
            'user' => $user
        ]);
    }
    
    public function destroy(User $user)
    {
        // Redirect back
        return back()->with('success', 'User deleted');
    }
}

استفاده از response helpers برای انواع مختلف response.

Controller با Service Layer

<?php

namespace App\Http\Controllers;

use App\Services\OrderService;
use App\Http\Requests\StoreOrderRequest;

class OrderController extends Controller
{
    public function __construct(
        private OrderService $orderService
    ) {}
    
    public function store(StoreOrderRequest $request)
    {
        try {
            $order = $this->orderService->createOrder(
                $request->validated(),
                $request->user()
            );
            
            return redirect()->route('orders.show', $order)
                ->with('success', 'Order created successfully');
        } catch (\Exception $e) {
            return back()->withErrors(['error' => $e->getMessage()]);
        }
    }
}

Controller با service layer که business logic را handle می‌کند.

Controller Testing

<?php

namespace Tests\Feature;

use Tests\TestCase;
use App\Models\User;

class UserControllerTest extends TestCase
{
    public function test_index_returns_users()
    {
        User::factory()->count(3)->create();
        
        $response = $this->get('/users');
        
        $response->assertStatus(200);
        $response->assertViewIs('users.index');
        $response->assertViewHas('users');
    }
    
    public function test_store_creates_user()
    {
        $userData = [
            'name' => 'John Doe',
            'email' => 'john@example.com',
            'password' => 'password123'
        ];
        
        $response = $this->post('/users', $userData);
        
        $response->assertRedirect();
        $this->assertDatabaseHas('users', ['email' => 'john@example.com']);
    }
}

Testing Controller با feature tests.

موارد استفاده

  • مدیریت HTTP requests و responses
  • اعتبارسنجی داده‌ها با Form Requests
  • فراخوانی service classes برای business logic
  • مدیریت session و flash messages
  • بازگرداندن views، JSON یا redirects
  • مدیریت errors و exceptions

اشتباهات رایج

  • قرار دادن business logic در Controller که باید در Service باشد
  • عدم استفاده از Form Requests برای validation
  • Fat Controllers که Single Responsibility را نقض می‌کنند
  • عدم استفاده از Dependency Injection
  • Hard-coding logic که باید configurable باشد
  • عدم handle کردن errors و exceptions

بهترین روش‌ها

  • از Thin Controllers استفاده کنید - logic را در Services قرار دهید
  • از Form Requests برای validation استفاده کنید
  • از Dependency Injection برای وابستگی‌ها استفاده کنید
  • از Resource Controllers برای RESTful operations استفاده کنید
  • Response helpers را برای consistency استفاده کنید
  • Errors و exceptions را به درستی handle کنید
  • Controllerها را test کنید

موارد خاص

  • Controller با complex business logic
  • Controller با multiple dependencies
  • Controller با conditional responses
  • Controller در API که JSON response نیاز دارد
  • Controller با file uploads
  • Controller با long-running operations

نکات عملکرد

  • Thin Controllers سریع‌تر از Fat Controllers هستند
  • از eager loading برای relationships استفاده کنید
  • از caching برای expensive operations استفاده کنید
  • Response time می‌تواند با service layer optimization بهبود یابد

نکات امنیتی

  • همیشه از Form Requests برای validation استفاده کنید
  • Authorization checks را در Form Request یا Policy انجام دهید
  • مطمئن شوید که sensitive data به درستی protected است
  • از middleware برای authentication و authorization استفاده کنید
  • Input sanitization را در validation انجام دهید

نکات مصاحبه

  • تفاوت بین Thin و Fat Controller چیست؟
  • چرا باید از Form Requests استفاده کرد؟
  • Single Action Controller چیست و چه زمانی استفاده می‌شود؟
  • چگونه می‌توان Controller را test کرد؟
  • تفاوت بین Web و API Controller چیست؟
  • چرا باید business logic را در Controller قرار نداد؟

یادداشت‌های نسخه

  • Laravel 11.x: بهبود performance در Controller execution
  • Laravel 11.x: پشتیبانی بهتر از type-hinted responses
  • Laravel 10.x: بهبود resource controllers
  • Laravel 9.x: بهبود single action controllers