NTM Solutions

Chủ Nhật, 13 tháng 9, 2026

📘 LARAVEL 13 — BÀI 37 — NOTIFICATION

Trong Bài 36 — Mail, chúng ta đã học cách Laravel gửi email bằng:

Mail
  ↓
Mailable
  ↓
Blade
  ↓
SMTP
  ↓
Người nhận

Nhưng trong một ứng dụng thực tế, thông báo không chỉ có Email.

Người dùng có thể cần nhận thông báo qua:

  • 📧 Email

  • 🗃️ Database

  • 📱 SMS

  • 💬 Slack

  • 🔔 Các kênh thông báo khác

Đây chính là lúc Notification của Laravel trở nên hữu ích.

Notification giúp chúng ta xây dựng một thông báo theo cách thống nhất, sau đó quyết định thông báo đó sẽ được gửi qua kênh nào.


📚 MỤC LỤC

Trong bài này chúng ta sẽ tìm hiểu:

1. Notification là gì?
2. Notification khác Mail thế nào?
3. Tạo Notification
4. notify()
5. Notifiable
6. Mail Notification
7. Database Notification
8. Đọc Notification
9. Đánh dấu đã đọc
10. Xóa Notification
11. Markdown Notification
12. Notification + Queue
13. Notification + Event
14. Notification theo nhiều kênh
15. Notification trong Blog CMS
16. Bài tập thực hành
17. Tổng kết

1. 🔔 Notification trong Laravel là gì?

Notification là cơ chế của Laravel dùng để gửi thông báo đến một đối tượng nhận thông báo.

Ví dụ:

User đăng ký
     ↓
Notification
     ↓
"Chào mừng bạn!"

Hoặc:

Admin xuất bản bài viết
     ↓
Notification
     ↓
"Có bài viết mới"

Hoặc:

Đơn hàng hoàn tất
     ↓
Notification
     ↓
"Đơn hàng #1001 đã được giao"

Notification đặc biệt hữu ích vì một thông báo có thể được gửi qua nhiều channel.

Ví dụ:

                    Notification
                         │
            ┌────────────┼────────────┐
            ▼            ▼            ▼
          Email       Database      Slack

2. 📧 Notification khác Mail thế nào?

Đây là điểm rất dễ nhầm.

Mail

Mail tập trung vào việc tạo và gửi email.

Mailable
    ↓
Email

Ví dụ:

Mail::to($user->email)
    ->send(new WelcomeUser($user));

Notification

Notification tập trung vào thông báo.

Notification
      ↓
   Channel
      ↓
Email / Database / Slack / ...

Ví dụ:

$user->notify(
    new NewPostNotification($post)
);

Notification có thể chọn nhiều channel:

return ['mail', 'database'];

Vì vậy có thể hiểu đơn giản:

Mailable = xây dựng một email.

Notification = xây dựng một thông báo có thể đi qua nhiều kênh.


3. 👤 Notification cần đối tượng nhận

Notification thường được gửi tới một đối tượng có trait:

Notifiable

Thông thường chúng ta sẽ thấy trait này trong User.

Ví dụ:

use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use Notifiable;
}

Sau đó User có thể nhận Notification:

$user->notify(
    new NewPostNotification($post)
);

Luồng:

User
 │
 └── Notifiable
          │
          ▼
    Notification

4. 🛠️ Tạo Notification

Laravel cung cấp Artisan để tạo Notification:

php artisan make:notification NewPostNotification

Laravel tạo:

app/
└── Notifications/
    └── NewPostNotification.php

Một Notification thường có cấu trúc:

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;

class NewPostNotification extends Notification
{
    use Queueable;

    public function __construct()
    {
        //
    }

    public function via(object $notifiable): array
    {
        return ['mail'];
    }
}

Phần quan trọng nhất là:

via()

Nó quyết định Notification được gửi qua channel nào.


5. 📡 via() — chọn Channel

Ví dụ chỉ gửi Email:

public function via(object $notifiable): array
{
    return ['mail'];
}

Gửi Database:

public function via(object $notifiable): array
{
    return ['database'];
}

Gửi cả hai:

public function via(object $notifiable): array
{
    return [
        'mail',
        'database',
    ];
}

Mô hình:

             Notification
                   │
             ┌─────┴─────┐
             ▼           ▼
           Mail       Database

Đây là một trong những ưu điểm lớn của Notification.


6. 📧 Mail Notification

Ví dụ chúng ta muốn thông báo:

Có bài viết mới được xuất bản.

Notification:

public function via(object $notifiable): array
{
    return ['mail'];
}

Sau đó tạo:

public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)
        ->subject('Có bài viết mới')
        ->greeting('Xin chào!')
        ->line('Một bài viết mới vừa được xuất bản.')
        ->action(
            'Xem bài viết',
            url('/blog')
        )
        ->line('Cảm ơn bạn đã theo dõi!');
}

Import:

use Illuminate\Notifications\Messages\MailMessage;

Laravel sẽ xây dựng email từ Notification.


7. 🚀 Gửi Notification

Sau khi có Notification:

$user->notify(
    new NewPostNotification()
);

Hoặc:

$user->notify(
    new NewPostNotification($post)
);

Laravel sẽ gọi:

$user
   ↓
notify()
   ↓
Notification
   ↓
via()
   ↓
mail
   ↓
Email

8. 🗃️ Database Notification

Một tính năng rất hay của Laravel Notification là lưu thông báo vào Database.

Ví dụ:

🔔 Thông báo

Có bài viết mới.

5 phút trước

Notification:

public function via(object $notifiable): array
{
    return [
        'database',
    ];
}

Sau đó định nghĩa:

public function toDatabase(
    object $notifiable
): array {
    return [
        'title' => 'Có bài viết mới',
        'message' => 'Một bài viết vừa được xuất bản.',
    ];
}

Laravel sẽ lưu dữ liệu Notification vào database.


9. 🗄️ Tạo bảng Notifications

Laravel cung cấp Artisan command:

php artisan make:notifications-table

Sau đó:

php artisan migrate

Laravel tạo bảng:

notifications

Bảng này dùng để lưu các Database Notifications.

Một Notification có thể được liên kết với User thông qua hệ thống polymorphic của Laravel.

Mô hình:

users
  │
  │
  ▼
notifications

10. 🔔 Lấy Notification của User

User có thể truy cập các Notification của mình:

$user->notifications

Ví dụ:

foreach ($user->notifications as $notification) {

    echo $notification->data['title'];

}

Dữ liệu trong data chính là dữ liệu mà chúng ta trả về từ:

toDatabase()

Ví dụ:

return [
    'title' => 'Có bài viết mới',
    'message' => 'Laravel 13 đã ra mắt.',
];

11. 🆕 Unread Notifications

Laravel cũng hỗ trợ phân biệt:

Unread
Read

Có thể lấy Notification chưa đọc:

$user->unreadNotifications

Ví dụ:

$count = $user
    ->unreadNotifications
    ->count();

Sau đó hiển thị trên Navbar:

🔔 5

12. 👀 Đánh dấu Notification đã đọc

Khi người dùng mở Notification:

$notification->markAsRead();

Ví dụ:

foreach ($user->unreadNotifications as $notification) {

    $notification->markAsRead();

}

Có thể đánh dấu tất cả:

$user->unreadNotifications
    ->markAsRead();

Mô hình:

NEW
 │
 ▼
Unread
 │
 │ User mở
 ▼
Read

13. 🗑️ Xóa Notification

Notification không nhất thiết phải tồn tại mãi mãi.

Có thể xóa:

$notification->delete();

Hoặc:

$user->notifications()->delete();

Ví dụ trong trang:

🔔 Notifications

Có bài viết mới
Đơn hàng đã giao
Tài khoản đã được cập nhật

[ Xóa tất cả ]

14. 📝 Markdown Notification

Laravel cũng hỗ trợ Notification sử dụng Markdown.

Ví dụ:

return (new MailMessage)
    ->subject('Bài viết mới')
    ->greeting('Xin chào!')
    ->line('Một bài viết mới vừa được xuất bản.')
    ->action(
        'Xem bài viết',
        url('/blog')
    )
    ->line('Cảm ơn bạn!');

Laravel sẽ tạo email dựa trên các thành phần Markdown Mail Notification.

Điều này giúp chúng ta không phải tự xây dựng toàn bộ HTML email.


15. 🔀 Một Notification — nhiều Channel

Đây mới là sức mạnh thực sự.

Ví dụ:

public function via(object $notifiable): array
{
    return [
        'mail',
        'database',
    ];
}

Khi:

$user->notify(
    new NewPostNotification($post)
);

Laravel thực hiện:

                  NewPostNotification
                           │
                           ▼
                         via()
                           │
                  ┌────────┴────────┐
                  ▼                 ▼
                Mail             Database
                  │                 │
                  ▼                 ▼
               Email          Notification

Người dùng vừa nhận email:

📧 Có bài viết mới

vừa có Notification trong website:

🔔 Có bài viết mới

16. ⚡ Notification + Queue

Đây là phần rất quan trọng vì chúng ta vừa học Queue ở Bài 35.

Nếu Notification gửi Email:

User Action
    ↓
Notification
    ↓
Email
    ↓
SMTP

Request có thể phải chờ.

Thay vào đó, Notification có thể được đưa vào Queue.

Một Notification có thể implement:

ShouldQueue

Ví dụ:

use Illuminate\Contracts\Queue\ShouldQueue;

class NewPostNotification
    extends Notification
    implements ShouldQueue
{
    use Queueable;
}

Khi đó:

User
 ↓
Notification
 ↓
Queue
 ↓
Response ngay
 ↓
Queue Worker
 ↓
Email / Database / ...

Đây là mô hình rất phù hợp với hệ thống production.


17. 🔄 Event + Listener + Notification

Chúng ta đã học:

Bài 33
Observer

Bài 34
Event & Listener

Bài 35
Queue

Bài 36
Mail

Bây giờ Bài 37 kết nối tất cả:

                 User Action
                     │
                     ▼
                   Event
                     │
                     ▼
                  Listener
                     │
                     ▼
               Notification
                     │
              ┌──────┴──────┐
              ▼             ▼
            Email        Database
              │
              ▼
            Queue

Ví dụ:

Admin publish Post
        ↓
PostPublished
        ↓
SendNewPostNotification
        ↓
NewPostNotification
        ↓
Queue
        ↓
Subscribers

Đây là kiến trúc rất đẹp cho Blog CMS.


18. 📰 Notification trong Blog CMS

Hãy áp dụng vào dự án Blog CMS chúng ta đang xây dựng.

Giả sử có:

User
Post
Category

Một User có thể đăng ký nhận thông báo.

Khi Admin xuất bản Post:

Admin
  │
  ▼
Publish Post
  │
  ▼
Event
  │
  ▼
Listener
  │
  ▼
Notification
  │
  ├───────────────┐
  ▼               ▼
Email          Database

Database Notification:

🔔 Thông báo

Bài viết mới:
Laravel 13 — Notification

[Xem bài viết]

19. 📊 Notification Badge

Một ứng dụng thực tế thường hiển thị số Notification chưa đọc.

Ví dụ Blade:

<a href="{{ route('notifications.index') }}">

    🔔

    @if(auth()->user()->unreadNotifications->count())
        <span>
            {{ auth()->user()->unreadNotifications->count() }}
        </span>
    @endif

</a>

Kết quả:

┌───────────────┐
│ 🔔 3          │
└───────────────┘

Người dùng click:

🔔
 ↓
Notifications
 ↓
Mark as Read

20. 📋 Trang Notification

Có thể tạo:

resources/views/notifications/index.blade.php

Ví dụ:

<h1>Thông báo</h1>

@forelse(auth()->user()->notifications as $notification)

    <div>

        <strong>
            {{ $notification->data['title'] }}
        </strong>

        <p>
            {{ $notification->data['message'] }}
        </p>

    </div>

@empty

    <p>Không có thông báo.</p>

@endforelse

21. 🧱 Notification nên chứa gì?

Không nên nhồi quá nhiều dữ liệu vào Notification.

Ví dụ tốt:

return [
    'title' => 'Bài viết mới',
    'message' => 'Laravel 13 — Notification',
    'post_id' => $post->id,
];

Sau đó có thể dùng:

$post = Post::find(
    $notification->data['post_id']
);

Hoặc tốt hơn, xây dựng URL từ ID:

url('/posts/' . $notification->data['post_id'])

Mục tiêu là Notification chỉ chứa những thông tin cần thiết.


22. 🧠 Notification không thay thế Event

Hai khái niệm này khác nhau.

Event

Mô tả:

Một chuyện gì đó đã xảy ra.

Ví dụ:

PostPublished

Notification

Mô tả:

Thông báo cho ai đó về chuyện đó.

Ví dụ:

NewPostNotification

Có thể hình dung:

EVENT
"Post đã được publish"
       │
       ▼
LISTENER
"Thông báo cho subscribers"
       │
       ▼
NOTIFICATION
"Có bài viết mới"

23. 📧 Notification hay Mailable?

Có thể dùng quy tắc đơn giản:

Dùng Mailable khi:

Email phức tạp
Hóa đơn
Báo giá
PDF
Email marketing
Email template riêng

Dùng Notification khi:

Thông báo hệ thống
Thông báo bài viết
Thông báo đơn hàng
Thông báo tài khoản
Unread notification
Nhiều channel

Ví dụ:

Invoice
   ↓
Mailable

Trong khi:

"Đơn hàng của bạn đã được giao"
   ↓
Notification
   ├── Email
   └── Database

24. 🧪 Test Notification

Khi viết Test, chúng ta không muốn gửi Notification thật.

Laravel cung cấp:

Notification::fake();

Sau đó:

$user->notify(
    new NewPostNotification($post)
);

Kiểm tra:

Notification::assertSentTo(
    $user,
    NewPostNotification::class
);

Mô hình:

Test
 ↓
Notification::fake()
 ↓
Action
 ↓
Notification
 ↓
Assert

Không có email thật được gửi đi.


25. 🎯 Bài tập thực hành

Bây giờ hãy xây dựng Notification cho Blog CMS.

Bước 1 — Tạo Notification

php artisan make:notification NewPostNotification

Bước 2 — Notification nhận Post

public function __construct(
    public Post $post
) {}

Bước 3 — Chọn channel

public function via(object $notifiable): array
{
    return [
        'mail',
        'database',
    ];
}

Bước 4 — Mail

public function toMail(
    object $notifiable
): MailMessage {

    return (new MailMessage)
        ->subject('Có bài viết mới')
        ->greeting('Xin chào!')
        ->line(
            'Một bài viết mới vừa được xuất bản.'
        )
        ->action(
            'Xem bài viết',
            url('/posts/' . $this->post->id)
        );
}

Bước 5 — Database

public function toDatabase(
    object $notifiable
): array {

    return [
        'title' => 'Có bài viết mới',
        'message' => $this->post->title,
        'post_id' => $this->post->id,
    ];
}

Bước 6 — Gửi Notification

$user->notify(
    new NewPostNotification($post)
);

Bước 7 — Queue

Sau khi Notification hoạt động ổn định, chuyển sang:

implements ShouldQueue

Sau đó chạy:

php artisan queue:work

Khi đó hệ thống sẽ có:

Publish Post
     ↓
Notification
     ↓
Queue
     ↓
Worker
     ├── Email
     └── Database

26. 🏆 Kiến trúc Blog CMS sau Bài 37

Sau 37 bài, dự án của chúng ta bắt đầu có kiến trúc khá hoàn chỉnh:

                         BLOG CMS
                             │
              ┌──────────────┼──────────────┐
              │              │              │
              ▼              ▼              ▼
           Request         Event          Model
              │              │              │
              ▼              ▼              ▼
         Controller       Listener       Eloquent
              │              │
              │              ▼
              │         Notification
              │              │
              │       ┌──────┴──────┐
              │       ▼             ▼
              │     Mail         Database
              │       │
              │       ▼
              │     Queue
              │       │
              └───────┴──────────────► User

Đây không còn đơn thuần là:

Route
 ↓
Controller
 ↓
View

mà đã bắt đầu trở thành một ứng dụng có kiến trúc thực tế.


27. 📌 Những kiến thức cần nhớ

Thành phầnVai trò
NotificationĐại diện cho một thông báo
NotifiableCho phép đối tượng nhận Notification
notify()Gửi Notification
via()Chọn channel
toMail()Nội dung Mail Notification
toDatabase()Dữ liệu Database Notification
notificationsCác Notification của User
unreadNotificationsNotification chưa đọc
markAsRead()Đánh dấu đã đọc
ShouldQueueĐưa Notification vào Queue
Notification::fake()Fake Notification khi Test

28. 🔥 Tổng kết Bài 37

Notification giải quyết một bài toán rất phổ biến:

Làm thế nào để thông báo cho người dùng mà không phải tự xây dựng một hệ thống riêng cho từng loại thông báo?

Laravel cho phép chúng ta xây dựng:

                    🔔 Notification
                           │
              ┌────────────┼────────────┐
              ▼            ▼            ▼
           📧 Mail      🗃️ Database   💬 Channel khác
              │            │
              ▼            ▼
           Email       Notification
                           │
                           ▼
                         User

Và khi kết hợp với Queue:

Event
  ↓
Listener
  ↓
Notification
  ↓
Queue
  ↓
Worker
  ↓
Mail / Database

Đây là một trong những mô hình rất đáng học vì nó kết nối trực tiếp những kiến thức chúng ta đã học từ Bài 33 → Bài 37:

33 — Observer
       ↓
34 — Event & Listener
       ↓
35 — Queue
       ↓
36 — Mail
       ↓
37 — Notification

📘 Bài tiếp theo — Bài 38: Cache

Chúng ta sẽ chuyển từ bài toán:

"Làm sao thông báo cho User?"

sang:

"Làm sao để Laravel không phải truy vấn Database liên tục?"

và bắt đầu tìm hiểu:

Cache
Redis
File Cache
Database Cache
remember()
forget()
flush()
Cache::put()
Cache::get()

Đây sẽ là bước đầu tiên để tối ưu hiệu năng Laravel 13.

Không có nhận xét nào:

Đăng nhận xét

Facebook Youtube RSS