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ậnNhư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ết1. 🔔 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 Slack2. 📧 Notification khác Mail thế nào?
Đây là điểm rất dễ nhầm.
Mail tập trung vào việc tạo và gửi email.
Mailable
↓
EmailVí 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:
NotifiableThô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
│
▼
Notification4. 🛠️ Tạo Notification
Laravel cung cấp Artisan để tạo Notification:
php artisan make:notification NewPostNotificationLaravel tạo:
app/
└── Notifications/
└── NewPostNotification.phpMộ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
↓
Email8. 🗃️ 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ướcNotification:
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-tableSau đó:
php artisan migrateLaravel tạo bảng:
notificationsBả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
│
│
▼
notifications10. 🔔 Lấy Notification của User
User có thể truy cập các Notification của mình:
$user->notificationsVí 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
ReadCó thể lấy Notification chưa đọc:
$user->unreadNotificationsVí dụ:
$count = $user
->unreadNotifications
->count();Sau đó hiển thị trên Navbar:
🔔 512. 👀 Đá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ở
▼
Read13. 🗑️ 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 NotificationNgười dùng vừa nhận email:
📧 Có bài viết mớivừa có Notification trong website:
🔔 Có bài viết mới16. ⚡ 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
↓
SMTPRequest có thể phải chờ.
Thay vào đó, Notification có thể được đưa vào Queue.
Một Notification có thể implement:
ShouldQueueVí 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
MailBây giờ Bài 37 kết nối tất cả:
User Action
│
▼
Event
│
▼
Listener
│
▼
Notification
│
┌──────┴──────┐
▼ ▼
Email Database
│
▼
QueueVí 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
CategoryMộ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 DatabaseDatabase 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 Read20. 📋 Trang Notification
Có thể tạo:
resources/views/notifications/index.blade.phpVí 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>
@endforelse21. 🧱 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ụ:
PostPublishedNotification
Mô tả:
Thông báo cho ai đó về chuyện đó.
Ví dụ:
NewPostNotificationCó 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êngDù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 channelVí dụ:
Invoice
↓
MailableTrong khi:
"Đơn hàng của bạn đã được giao"
↓
Notification
├── Email
└── Database24. 🧪 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
↓
AssertKhô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 NewPostNotificationBướ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 ShouldQueueSau đó chạy:
php artisan queue:workKhi đó hệ thống sẽ có:
Publish Post
↓
Notification
↓
Queue
↓
Worker
├── Email
└── Database26. 🏆 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
↓
Viewmà đã 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ần | Vai trò |
|---|---|
Notification | Đại diện cho một thông báo |
Notifiable | Cho 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 |
notifications | Các Notification của User |
unreadNotifications | Notification 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
│
▼
UserVà 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