1. 10:56 07/08/2026
Một lỗi khá phổ biến khi làm web/app là nghĩ rằng: “Form này do mình thiết kế, người dùng chỉ nhập được những gì mình cho phép”. Thực tế, dữ liệu gửi lên server có thể bị chỉnh bằng DevTools, Postman, script tự động hoặc một client cũ chưa cập nhật. Vì vậy, validate dữ liệu không chỉ là việc làm đẹp giao diện, mà là một lớp bảo vệ quan trọng cho tính đúng đắn và an toàn của hệ thống.
Validate nên có ở cả client và server
Client-side validation giúp trải nghiệm tốt hơn: báo lỗi ngay khi người dùng nhập sai, giảm số lần gửi request không cần thiết. Ví dụ: email sai định dạng, mật khẩu quá ngắn, ngày kết thúc nhỏ hơn ngày bắt đầu.
Server-side validation mới là lớp bắt buộc. Server phải xem mọi dữ liệu nhận được là không đáng tin cho đến khi kiểm tra xong. Dù giao diện đã chặn nhập số âm cho trường “số lượng”, API vẫn phải kiểm tra lại vì request có thể được gửi trực tiếp.
Ví dụ thực tế: tạo đơn hàng
Giả sử API tạo đơn hàng nhận dữ liệu như sau:
- productId
- quantity
- shippingAddress
- couponCode
Một số kiểm tra nên có:
- productId có tồn tại không?
- Sản phẩm còn được bán không?
- quantity có phải số nguyên dương không?
- quantity có vượt tồn kho hoặc giới hạn mua không?
- shippingAddress có đủ thông tin tối thiểu không?
- couponCode có hợp lệ, còn hạn, đúng điều kiện áp dụng không?
Nếu chỉ kiểm tra quantity trên giao diện, người dùng vẫn có thể gửi quantity = -10 hoặc quantity = 999999. Nếu hệ thống không chặn, lỗi có thể lan sang tồn kho, thanh toán, báo cáo doanh thu hoặc hoàn tiền.
Phân biệt validation và business rule
Validation cơ bản thường kiểm tra hình dạng dữ liệu: kiểu dữ liệu, độ dài, định dạng, bắt buộc hay không. Ví dụ: email phải giống email, tên không quá 100 ký tự, ngày sinh phải là ngày hợp lệ.
Business rule kiểm tra theo ngữ cảnh nghiệp vụ. Ví dụ: người dùng chỉ được hủy đơn khi đơn chưa giao, mã giảm giá chỉ áp dụng cho đơn từ một mức tiền nhất định, tài khoản miễn phí chỉ được tạo tối đa 3 dự án.
Tách hai phần này giúp code dễ đọc hơn. Đừng nhồi toàn bộ vào một hàm “validate” khổng lồ rồi vài tháng sau không ai dám sửa.
Chuẩn hóa dữ liệu trước khi lưu
Ngoài kiểm tra đúng sai, nên chuẩn hóa dữ liệu để tránh rác dữ liệu tích tụ lâu dài. Ví dụ:
- Trim khoảng trắng ở đầu/cuối tên, email, mã nhập vào.
- Chuyển email về chữ thường nếu hệ thống coi email là không phân biệt hoa thường.
- Chuẩn hóa số điện thoại theo định dạng nội bộ.
- Chuyển ngày giờ về timezone thống nhất khi lưu.
- Loại bỏ ký tự không mong muốn trong các trường mã, slug, username.
Một ví dụ nhỏ: nếu không trim email, “user@example.com” và “ user@example.com ” có thể bị xem là hai giá trị khác nhau. Người dùng thì thấy vô lý, còn đội kỹ thuật phải xử lý dữ liệu bẩn về sau.
Thông báo lỗi nên giúp người dùng sửa được
Một lỗi validation tốt không nên chỉ nói “Dữ liệu không hợp lệ”. Hãy nói rõ trường nào sai và sai vì sao:
- “Email không đúng định dạng.”
- “Mật khẩu cần ít nhất 8 ký tự.”
- “Ngày kết thúc phải sau ngày bắt đầu.”
- “Số lượng phải từ 1 đến 10.”
Với API, nên trả lỗi có cấu trúc ổn định để frontend dễ hiển thị. Ví dụ mỗi lỗi gồm field, code và message. Message có thể thay đổi theo ngôn ngữ, nhưng code nên ổn định để client xử lý logic.
Đừng lộ thông tin nhạy cảm qua lỗi
Có những trường hợp thông báo quá chi tiết lại gây rủi ro. Ví dụ với đăng nhập, nếu báo “Email không tồn tại” và “Sai mật khẩu” riêng biệt, kẻ xấu có thể dò xem email nào đã đăng ký. Tùy sản phẩm, có thể dùng thông báo chung như “Email hoặc mật khẩu không đúng”.
Tương tự, khi validate quyền truy cập tài nguyên, không phải lúc nào cũng nên nói “Bạn không có quyền xem tài liệu này” nếu việc tài liệu tồn tại cũng là thông tin nhạy cảm.
Một số lời khuyên có thể áp dụng ngay
- Luôn validate ở server, kể cả khi client đã validate rất kỹ.
- Dùng schema rõ ràng cho request body, query và params.
- Không để validation nằm rải rác khó tìm; nên có lớp hoặc module riêng.
- Chuẩn hóa dữ liệu trước khi lưu, nhưng cần cẩn thận để không làm mất ý nghĩa dữ liệu gốc.
- Viết test cho các case biên: chuỗi rỗng, null, số âm, số quá lớn, ngày không hợp lệ, mảng quá dài.
- Trả lỗi có cấu trúc nhất quán để frontend xử lý dễ dàng.
- Log lỗi validation ở mức hợp lý; không nên ghi toàn bộ dữ liệu nhạy cảm như mật khẩu, token, thông tin thanh toán.
Kết luận
Validation không phải phần phụ của form, mà là hợp đồng đầu vào của hệ thống. Làm tốt từ đầu sẽ giảm lỗi dữ liệu, giảm bug khó truy vết và giúp cả frontend lẫn backend phối hợp rõ ràng hơn. Một nguyên tắc đơn giản nhưng rất đáng nhớ: giao diện có thể hỗ trợ người dùng nhập đúng, nhưng server mới là nơi quyết định dữ liệu có được tin hay không.