Trong nhiều dự án web/app, validation thường bị xem là phần “phụ”: frontend kiểm tra ô bắt buộc, email đúng định dạng, mật khẩu đủ dài là xong. Nhưng trên thực tế, validation là một lớp bảo vệ quan trọng cho cả trải nghiệm người dùng, tính đúng đắn của dữ liệu và độ an toàn của hệ thống. Một nguyên tắc nên nhớ: frontend validation giúp người dùng nhập đúng nhanh hơn, còn backend validation mới là nơi quyết định dữ liệu có được chấp nhận hay không. Vì sao không thể chỉ validation ở frontend? Frontend nằm trong tay người dùng. Họ có thể tắt JavaScript, sửa request bằng DevTools, dùng Postman/cURL gọi thẳng API, hoặc một client cũ vẫn gửi dữ liệu theo định dạng trước đây. Nếu backend tin hoàn toàn vào dữ liệu từ frontend, hệ thống rất dễ nhận dữ liệu sai. Ví dụ: form tạo mã giảm giá có trường discountPercent. Frontend giới hạn từ 1 đến 50. Nhưng nếu backend không kiểm tra, người dùng có thể gửi 500 hoặc -20. Kết quả có thể là giảm giá sai, lỗi tính toán, hoặc dữ liệu rác trong database. Các lớp validation nên có 1. Validation ở giao diện Mục tiêu là phản hồi nhanh và thân thiện: - Báo trường bắt buộc trước khi gửi form. - Kiểm tra định dạng cơ bản như email, số điện thoại, URL. - Giới hạn độ dài nhập liệu để tránh người dùng gõ quá nhiều. - Hiển thị lỗi ngay gần trường liên quan. Ví dụ thực tế: khi người dùng nhập mật khẩu quá ngắn, frontend nên báo ngay “Mật khẩu cần ít nhất 8 ký tự” thay vì để họ bấm gửi rồi mới biết. 2. Validation ở API/backend Đây là lớp bắt buộc. Backend cần kiểm tra lại toàn bộ dữ liệu quan trọng: - Kiểu dữ liệu: string, number, boolean, array. - Khoảng giá trị: số lượng sản phẩm phải lớn hơn 0. - Độ dài: tên hiển thị không quá 50 ký tự. - Quy tắc nghiệp vụ: người dùng không được tự đổi role thành admin. - Quan hệ dữ liệu: productId phải tồn tại và còn được bán. - Quyền truy cập: user chỉ được sửa tài nguyên thuộc về mình. Một lỗi phổ biến là chỉ kiểm tra “có userId trong request hay không”, nhưng không kiểm tra user đó có quyền thao tác trên dữ liệu hay không. Đây không chỉ là validation mà còn liên quan đến authorization. 3. Ràng buộc ở database Database nên là tuyến phòng thủ cuối cùng: - NOT NULL cho trường bắt buộc. - UNIQUE cho email, username, slug. - FOREIGN KEY cho quan hệ dữ liệu. - CHECK constraint nếu hệ quản trị hỗ trợ, ví dụ giá sản phẩm phải lớn hơn hoặc bằng 0. Không nên dồn toàn bộ logic vào database, nhưng cũng không nên để database quá “dễ dãi”. Nếu API có bug, ràng buộc database vẫn giúp hạn chế dữ liệu hỏng. Thiết kế thông báo lỗi sao cho dễ dùng Một response lỗi validation nên đủ rõ để frontend hiển thị đúng chỗ. Thay vì trả về chung chung: “Dữ liệu không hợp lệ” Nên trả về cấu trúc có thể xử lý được, ví dụ theo ý tưởng: - message: “Vui lòng kiểm tra lại thông tin” - errors.email: “Email không đúng định dạng” - errors.password: “Mật khẩu cần ít nhất 8 ký tự” Điều này giúp frontend không phải đoán lỗi và cũng giúp trải nghiệm nhất quán hơn. Một số lỗi validation thường gặp - Tin vào dữ liệu ẩn trên form, ví dụ price, role, userId. Các giá trị quan trọng nên lấy từ server hoặc session, không lấy từ client. - Chỉ validate khi tạo mới, quên validate khi cập nhật. - Cho phép partial update nhưng không phân biệt trường vắng mặt và trường cố tình gửi null. - Không chuẩn hóa dữ liệu trước khi lưu, ví dụ email có khoảng trắng đầu/cuối hoặc viết hoa viết thường lẫn lộn. - Thông báo lỗi quá kỹ cho các chức năng nhạy cảm, ví dụ đăng nhập báo “email tồn tại nhưng sai mật khẩu”, có thể làm lộ thông tin tài khoản. Gợi ý áp dụng trong dự án - Viết schema validation rõ ràng cho từng API endpoint. - Dùng chung quy tắc validation giữa frontend và backend nếu stack cho phép, nhưng vẫn phải validate ở backend. - Chuẩn hóa dữ liệu trước khi lưu: trim chuỗi, chuyển email về lowercase nếu phù hợp. - Tách lỗi validation, lỗi quyền truy cập và lỗi hệ thống thành các nhóm khác nhau. - Viết test cho các trường hợp dữ liệu sai, không chỉ test luồng thành công. Kết luận Validation tốt không chỉ là vài dòng kiểm tra form. Nó là sự phối hợp giữa frontend, backend và database để đảm bảo dữ liệu đi vào hệ thống là hợp lệ, an toàn và có thể tin cậy. Làm kỹ từ đầu sẽ giảm rất nhiều lỗi khó truy vết về sau, đặc biệt khi ứng dụng có nhiều client, nhiều API và nhiều luồng nghiệp vụ phức tạp.