All posts
Tối ưu kiến trúc 4 tầng Laravel
laravelcleancode

Tối ưu kiến trúc 4 tầng Laravel

Hao Nguyen K.'s avatarHao Nguyen K.
Table of Contents8 sections

Khi một dự án Laravel bắt đầu phình to với hàng trăm tính năng, mô hình MVC (Model-View-Controller) mặc định sẽ lộ rõ những giới hạn. Controller ngày càng phình to vì phải gánh vác cả việc validate, xử lý logic, đến gọi database. Model thì ngập tràn các câu lệnh query phức tạp.

Để giải quyết bài toán này, các hệ thống Enterprise thường nâng cấp lên Kiến trúc 4 tầng (Layered Architecture) bao gồm: Controller - Service - Repository - Model.

Kiến trúc này chia cắt hệ thống thành các lớp độc lập, giúp mã nguồn cực kỳ sạch sẽ, dễ bảo trì và dễ viết Unit Test. Hãy cùng mổ xẻ chi tiết xem mỗi tầng thực chất làm những gì và dòng chảy dữ liệu vận hành ra sao.

1. Toàn cảnh dòng chảy dữ liệu (Data Flow)

Để dễ hình dung, hãy tưởng tượng kiến trúc này giống như một nhà hàng cao cấp:

  • ControllerPhục vụ bàn (Tiếp nhận yêu cầu từ khách).

  • ServiceBếp trưởng (Xử lý chế biến món ăn - Nghiệp vụ chính).

  • RepositoryPhụ bếp phụ trách kho (Tìm kiếm và chuẩn bị nguyên liệu).

  • ModelTủ thực phẩm (Nơi chứa dữ liệu thô).

Dòng chảy của một Request sẽ đi tuần tự từ ngoài vào trong và trả kết quả ngược từ trong ra ngoài:

Client -> Controller -> Service -> Repository -> Model/Database

2. Chi tiết trách nhiệm của từng tầng

Hãy cùng phân tích một tính năng thực tế: Đăng ký thẻ thành viên VIP cho khách hàng.

Tầng 1: Controller

Nhiệm vụ: Chỉ làm nhiệm vụ giao tiếp với thế giới bên ngoài (HTTP Request/Response). Controller nhận request, kiểm tra tính hợp lệ của dữ liệu (Validation), chuyển dữ liệu vào tầng Service và trả về kết quả (JSON hoặc View).

  • Điều cấm kỵ: Không viết bất kỳ dòng logic nghiệp vụ (if/else tính toán) hay câu lệnh Query Database nào ở đây.

PHP

namespace App\Http\Controllers;

use App\Http\Requests\VipRegistrationRequest;
use App\Services\VipMemberService;

class VipRegistrationController extends Controller
{
    public function __construct(protected VipMemberService $vipService) {}

    public function __invoke(VipRegistrationRequest $request)
    {
        // 1. Controller chỉ nhận dữ liệu đã qua validate
        $data = $request->validated();

        // 2. Đẩy trách nhiệm xử lý cho Service
        $member = $this->vipService->register($data);

        // 3. Trả về response cho Client
        return response()->json(['message' => 'Đăng ký VIP thành công', 'data' => $member]);
    }
}

Tầng 2: Service (Business Logic)

Nhiệm vụ: Đây là nơi chứa toàn bộ "luật chơi" của doanh nghiệp. Tính toán, kiểm tra điều kiện, phối hợp giữa các Repository, gửi Mail, bắn Event... đều nằm ở đây.

  • Điều cấm kỵ: Không được biết về HTTP Request (không dùng $request->input()), không được tự viết câu lệnh SQL.

PHP

namespace App\Services;

use App\Repositories\Interfaces\UserRepositoryInterface;
use App\Repositories\Interfaces\VipCardRepositoryInterface;
use Exception;
use Illuminate\Support\Facades\DB;

class VipMemberService
{
    public function __construct(
        protected UserRepositoryInterface $userRepo,
        protected VipCardRepositoryInterface $vipCardRepo
    ) {}

    public function register(array $data)
    {
        // Service giữ Logic nghiệp vụ: Chỉ cho phép User có điểm tích lũy > 1000 lên VIP
        $user = $this->userRepo->getById($data['user_id']);
        
        if ($user->loyalty_points < 1000) {
            throw new Exception("Chưa đủ điểm tích lũy để thăng hạng VIP.");
        }

        // Quản lý Transaction cho chuỗi hành động kế tiếp
        return DB::transaction(function () use ($user) {
            $this->userRepo->updateStatus($user->id, 'vip');
            return $this->vipCardRepo->issueNewCard($user->id);
        });
    }
}

Tầng 3: Repository

Nhiệm vụ: Lớp trừu tượng nằm giữa Business Logic và Database. Nó chịu trách nhiệm viết các câu lệnh truy vấn dữ liệu (Eloquent, Query Builder, SQL thuần). Nếu sau này hệ thống đổi từ MySQL sang MongoDB, bạn chỉ cần sửa tầng này, tầng Service hoàn toàn không bị ảnh hưởng.

PHP

namespace App\Repositories;

use App\Repositories\Interfaces\UserRepositoryInterface;
use App\Models\User;

class UserRepository implements UserRepositoryInterface
{
    public function getById(int $id): User
    {
        return User::findOrFail($id);
    }

    public function updateStatus(int $id, string $status): bool
    {
        return User::where('id', $id)->update(['status' => $status]);
    }
}

Tầng 4: Model

Nhiệm vụ: Trong kiến trúc này, Eloquent Model được trả về đúng với bản chất của nó — một thực thể dữ liệu (Data Entity). Model chỉ chứa cấu hình bảng, cấu hình các mối quan hệ (hasMany, belongsTo), casts dữ liệu hoặc các scopes cơ bản.

PHP

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;

class User extends Model
{
    protected $fillable = ['name', 'email', 'status', 'loyalty_points'];

    // Model chỉ định nghĩa mối quan hệ và cấu hình thực thể
    public function vipCard(): HasOne
    {
        return $this->hasOne(VipCard::class);
    }
}

3. Lợi ích cốt lõi của việc phân rã 4 tầng

  1. Tính tái sử dụng cực cao (Reusability): Hàm register() trong VipMemberService giờ đây có thể được gọi từ VipRegistrationController, từ một trang Admin khác, hoặc từ một lệnh chạy ngầm Artisan Command mà không cần viết lại một dòng code logic nào.

  2. Dễ dàng viết Unit Test: Bạn có thể dễ dàng test riêng tầng Service bằng cách "giả lập" (Mock) tầng Repository mà không cần tạo dữ liệu thật dưới Database, giúp tốc độ chạy test nhanh chỉ trong vài mili-giây.

  3. Phát triển song song (Parallel Development): Trong một team, một lập trình viên có thể tập trung viết các câu query phức tạp ở tầng Repository, trong khi lập trình viên khác có thể tập trung dựng giao diện và validate ở tầng Controller.

Lời kết

Việc phân chia rõ ràng trách nhiệm Controller - Service - Repository - Model là viên gạch đầu tiên để xây dựng một hệ thống Laravel chuẩn Enterprise. Nó đòi hỏi bạn phải viết nhiều file hơn ở giai đoạn đầu, nhưng sẽ tiết kiệm hàng trăm giờ bảo trì khi dự án bước vào giai đoạn tăng trưởng.