Gì là API?
API là một chuẩn mực phổ biến trong cuộc sống hàng ngày, ví dụ như các đầu nối ống nước hay chuẩn USB giúp kết nối thiết bị với máy tính. Jeff Bezos đã áp dụng triệt để văn hóa API tại Amazon bằng việc yêu cầu tất cả hệ thống và đội ngũ phải tương tác thông qua giao diện dịch vụ. Điều này đã dẫn đến sự phát triển của công nghệ điện toán đám mây hiện nay.Nguyên tắc thiết kế API
Thiết kế theo hợp đồng (Design by Contract)
Đây là phương pháp yêu cầu nhà phát triển định nghĩa rõ ràng các điều kiện trước, sau và bất biến cho mỗi thành phần phần mềm. Để tạo ra một API chất lượng, cần trả lời ba câu hỏi chính:- API mong đợi gì từ người sử dụng?
- API đảm bảo điều gì khi xử lý?
- Có yếu tố nào không thay đổi trong quá trình xử lý không?
1. Tách biệt mối quan tâm (Separation of Concerns)
Mỗi API nên tập trung vào một chức năng duy nhất. Tránh tích hợp nhiều tính năng khác nhau hoặc sử dụng các cờ kiểm soát phức tạp.// Sai
type UserService interface {
CreateUser(string, int) error
GetUser(int) (User, error)
UpdateUser(int, string, int) error
DeleteUser(int) error
SendEmail(int, string) error // Gửi email không liên quan đến quản lý người dùng
}
// Đúng
type UserService interface {
CreateUser(string, int) error
GetUser(int) (User, error)
UpdateUser(int, string, int) error
DeleteUser(int) error
}
type EmailService interface {
SendEmail(int, string) error
}
2. Tự diễn đạt (Self-explanatory)
Một API tốt cần dễ hiểu và cung cấp thông tin lỗi rõ ràng. Cụ thể:- Tên gọi API cần trực quan và mô tả đúng chức năng.
- Lỗi cần chỉ ra vấn đề cụ thể và hướng dẫn giải quyết.
3. Liệt kê đầy đủ và không trùng lặp (MECE - Mutually Exclusive and Collectively Exhaustive)
Các API nên tránh chồng chéo chức năng. Ví dụ: nếu có API chỉnh sửa mục đơn hàng thì không cần thêm chức năng này vào API chỉnh sửa toàn bộ đơn hàng.4. Thất bại nhanh chóng (Fail Fast)
Kiểm tra điều kiện ngay từ đầu để phát hiện lỗi sớm, thay vì chờ đến cuối quy trình xử lý.// Kiểm tra phạm vi giá trị
int32 page_num = 3 [(validate.rules).int32.gte = 0]; // Số trang bắt đầu từ 0
5. Tính nhất quán (Idempotency)
Đảm bảo rằng việc gọi đi gọi lại một API không gây ra thay đổi khác biệt so với lần gọi đầu tiên. Các phương pháp bao gồm:- Sử dụng ID độc nhất cho mỗi yêu cầu.
- Áp dụng mô hình trạng thái để kiểm soát luồng xử lý.
- Sử dụng ràng buộc cơ sở dữ liệu để ngăn chặn dữ liệu trùng lặp.
6. Phiên bản hóa (Versioning)
Khi API cần thay đổi, hãy sử dụng phiên bản để đảm bảo tương thích ngược. Có thể truyền phiên bản thông qua URI, header hoặc query parameter.Tối ưu API
1. Xử lý hàng loạt (Batch Processing)
Giảm thiểu số lượng truy vấn mạng bằng cách nhóm các yêu cầu lại với nhau. Ví dụ: sử dụng MGET trong Redis hoặc tối ưu RPC hỗ trợ truy vấn hàng loạt.2. Xử lý bất đồng bộ (Asynchronous Processing)
Chia nhỏ các bước xử lý thành đồng bộ và bất đồng bộ để tăng hiệu suất. Ví dụ: ghi dữ liệu vào cơ sở dữ liệu đồng bộ và gửi thông báo bất đồng bộ.3. Xử lý song song (Parallel Processing)
Phân chia công việc thành các nhiệm vụ con và chạy chúng cùng lúc trên nhiều lõi CPU hoặc hệ thống phân tán.4. Sử dụng không gian đổi lấy thời gian (Space for Time)
Lưu trữ thông tin trong bộ nhớ đệm hoặc cấu trúc dữ liệu hiệu quả hơn để giảm thời gian xử lý.5. Quản lý tài nguyên (Pooling)
Sử dụng pool kết nối hoặc goroutine để tái sử dụng tài nguyên thay vì tạo mới mỗi lần.6. Tiền xử lý (Preprocessing)
Tính toán trước những dữ liệu cần thiết và lưu trữ sẵn để phục vụ nhanh chóng khi yêu cầu.Bảo mật API
1. Mã hóa dữ liệu
Sử dụng mã hóa đối xứng hoặc bất đối xứng để bảo vệ thông tin nhạy cảm.2. Ký và xác thực
Thêm chữ ký cho dữ liệu để đảm bảo tính toàn vẹn và nguồn gốc.3. Xác thực token
Sử dụng JWT để tạo token xác thực mà không cần phụ thuộc vào bộ nhớ cache phân tán.4. Ngăn chặn yêu cầu lại (Anti-replay)
Áp dụng timestamp và nonce để đảm bảo mỗi yêu cầu chỉ được xử lý một lần.5. Giới hạn tốc độ (Rate Limiting)
Sử dụng các thuật toán như token bucket hoặc leaky bucket để kiểm soát tần suất yêu cầu.6. Danh sách trắng/danh sách đen
Quản lý quyền truy cập dựa trên danh sách người dùng được phép hoặc bị cấm.7. Che dấu dữ liệu nhạy cảm
Ẩn thông tin như mật khẩu hoặc số điện thoại bằng cách mã hóa hoặc che một phần nội dung.8. Phòng chống tiêm SQL (SQL Injection Prevention)
Sử dụng truy vấn tham số hóa, ORM hoặc kiểm tra đầu vào chặt chẽ để ngăn chặn các cuộc tấn công SQL injection.Duy trì API
1. Tài liệu
Liên kết tự động giữa mã nguồn và tài liệu để đảm bảo luôn cập nhật.2. Nhật ký (Logging)
In ra thông tin chi tiết về phương thức, tham số và kết quả xử lý kèm theo các thông số quan trọng như userId hoặc traceId.