💡 Key Takeaways
- The Foundation: Understanding REST Beyond the Buzzword
- Principle 1: Resources Are Nouns, Not Verbs
- Principle 2: HTTP Methods Mean What They Mean
- Principle 3: Status Codes Are Your Communication Protocol
Ba năm trong vai trò Kiến trúc sư API Chính tại một kỳ lân fintech, tôi đã chứng kiến ứng dụng di động của chúng tôi gặp sự cố khủng khiếp trong một buổi giới thiệu sản phẩm với các nhà đầu tư. Thủ phạm? Một điểm API duy nhất trả về 47MB JSON vì ai đó nghĩ rằng "nhiều dữ liệu luôn tốt hơn." Khoảnh khắc xấu hổ đó — và sự trì hoãn tài trợ 2 triệu đô la mà nó gây ra — đã dạy tôi rằng thiết kế API không chỉ là làm cho mọi thứ hoạt động. Đó là về việc làm cho chúng hoạt động một cách thanh lịch, có thể dự đoán được và bền vững theo quy mô.
💡 Những Điểm Chính
- Nền Tảng: Hiểu REST Vượt Qua Cụm Từ
- Nguyên tắc 1: Tài Nguyên Là Danh Từ, Không Phải Động Từ
- Nguyên tắc 2: Các Phương Thức HTTP Có Nghĩa Như Chúng Đã Nói
- Nguyên tắc 3: Mã Trạng Thái Là Giao Thức Giao Tiếp Của Bạn
Tôi là Marcus Chen, và tôi đã dành 12 năm qua để thiết kế API xử lý mọi thứ từ 50 yêu cầu mỗi ngày đến 50 triệu. Tôi đã thấy các kỹ sư xuất sắc tạo ra những API phức tạp đến nỗi ngay cả họ cũng không nhớ cách sử dụng chúng sau sáu tháng. Tôi cũng đã thấy các nhà phát triển cấp dưới tạo ra các giao diện thật trực quan đến mức tài liệu trở nên gần như không cần thiết. Sự khác biệt là một cam kết vào những nguyên tắc cơ bản vượt qua các khuôn khổ, ngôn ngữ và xu hướng kiến trúc.
, tôi đang chia sẻ 10 nguyên tắc đã hướng dẫn mọi API thành công mà tôi đã xây dựng — những nguyên tắc được tôi rèn qua các sự cố sản xuất, phản hồi từ người dùng, và không biết bao nhiêu lần đánh giá mã. Đây không phải là lý tưởng lý thuyết; chúng là những hướng dẫn đã được kiểm chứng trong thực chiến đã cứu đội ngũ của tôi hàng trăm giờ và ngăn chặn không biết bao nhiêu cơn đau đầu về tích hợp.
Nền Tảng: Hiểu REST Vượt Qua Cụm Từ
Trước khi đi vào các nguyên tắc cụ thể, hãy đề cập đến một sự thật không thoải mái: hầu hết "REST APIs" thực sự không phải là RESTful. Chúng là HTTP APIs với câu trả lời JSON, điều đó cũng không sao, nhưng gọi chúng là REST giống như gọi một chiếc xe đạp là xe máy vì cả hai đều có bánh. Luận án REST gốc của Roy Fielding đã phác thảo sáu quy tắc, và hầu hết các API vi phạm ít nhất ba quy tắc trong số đó.
Dưới đây là điều quan trọng trong thực tiễn: REST là một phong cách kiến trúc xem API của bạn như một tập hợp các tài nguyên, mỗi tài nguyên được xác định bằng một URL, được thao tác thông qua các phương thức HTTP tiêu chuẩn. Sự đẹp đẽ của cách tiếp cận này là khả năng dự đoán. Khi tôi thấy GET /users/123, tôi biết chính xác nó làm gì mà không cần đọc tài liệu. Khi tôi thấy POST /users, tôi biết nó tạo ra một người dùng mới. Sự nhất quán này chính là sức mạnh của REST.
Theo kinh nghiệm của tôi, các đội ngũ thực sự hiểu nguyên tắc REST sẽ phát hành API nhanh hơn 40% so với những người xem nó như một mục kiểm tra. Tại sao? Bởi vì REST cung cấp một mô hình tư duy dẫn dắt các quyết định thiết kế. Liệu đây có nên là một điểm cuối mới hay một tham số truy vấn? REST trả lời điều đó. Liệu đây có nên là POST hay PUT? REST cho bạn biết. Các nguyên tắc không phải là rào chắn — chúng là lan can giữ bạn trên con đường đến các API duy trì được và có thể mở rộng.
Tôi đã xem xét hơn 200 thiết kế API trong sự nghiệp của mình, và những thiết kế lâu bền đều có một đặc điểm chung: chúng tôn trọng tư duy dựa trên tài nguyên của REST. Những thiết kế trở thành cơn ác mộng bảo trì? Chúng xem REST như một gợi ý thay vì một khuôn khổ. API của bạn sẽ tồn tại lâu hơn bạn mong đợi — có thể từ 5-7 năm tối thiểu trong môi trường sản xuất. Hãy thiết kế chúng với ý nghĩ về tuổi thọ đó.
Nguyên tắc 1: Tài Nguyên Là Danh Từ, Không Phải Động Từ
Nguyên tắc này có vẻ hiển nhiên cho đến khi bạn thấy những vi phạm trong thực tế. Một lần tôi đã thừa hưởng một API với các điểm cuối như /getUser, /createOrder, và /deleteProduct. Mỗi thao tác là một động từ trong URL, khiến phương thức HTTP trở nên thừa. API này có 127 điểm cuối làm những gì 23 điểm cuối dựa trên tài nguyên có thể làm tốt hơn.
Dưới đây là quy tắc: các URL của bạn nên đại diện cho các thứ (tài nguyên), và các phương thức HTTP nên đại diện cho các hành động trên những thứ đó. Thay vì POST /createUser, hãy sử dụng POST /users. Thay vì GET /getUserOrders, hãy sử dụng GET /users/123/orders. Đây không phải là tính cầu toàn — mà là việc tạo ra một mô hình tư duy nhất quán có thể mở rộng.
Xem xét tải trí tuệ. Với các URL dựa trên động từ, các lập trình viên phải nhớ các tên điểm cuối tùy ý. Với các URL dựa trên tài nguyên, họ theo một mẫu. Trong ứng dụng fintech của chúng tôi, chúng tôi đã giảm thời gian onboarding cho các lập trình viên mới từ 3 tuần xuống còn 1.5 tuần chỉ bằng cách tái cấu trúc với việc đặt tên tài nguyên đúng cách. API trở nên tự tài liệu hóa.
Tất nhiên có những ngoại lệ. Các hành động không phù hợp với các thao tác CRUD — chẳng hạn như POST /payments/123/refund hoặc POST /orders/456/cancel — là chấp nhận được. Đây là các điểm cuối theo kiểu controller, và chúng ổn khi lựa chọn khác sẽ gây khó khăn. Điều quan trọng là sử dụng chúng một cách tiết kiệm và nhất quán. Trong API hiện tại của chúng tôi, 89% các điểm cuối là các thao tác tài nguyên thuần túy, và 11% còn lại là các hành động controller được tài liệu hóa rõ ràng.
Khi đặt tên tài nguyên, hãy sử dụng danh từ số nhiều một cách nhất quán. /users không phải /user, /orders không phải /order. Vâng, GET /users/123 trả về một người dùng duy nhất, và điều đó có thể cảm thấy ngữ pháp lạ, nhưng tính nhất quán quan trọng hơn ngữ pháp. Tôi đã thấy các đội ngũ lãng phí hàng giờ tranh luận về số ít so với số nhiều; hãy chọn số nhiều và tiếp tục.
Nguyên tắc 2: Các Phương Thức HTTP Có Nghĩa Như Chúng Đã Nói
HTTP cung cấp cho chúng ta một từ vựng phong phú: GET, POST, PUT, PATCH, DELETE, và nhiều hơn nữa. Mỗi phương thức có nghĩa cụ thể, và tôn trọng những nghĩa đó khiến API của bạn trở nên dự đoán được và có thể lưu cache. Tuy nhiên, tôi thường thấy các API mà nơi POST làm mọi thứ — tạo, cập nhật, xóa, thậm chí truy xuất dữ liệu. Điều này giống như việc sử dụng búa cho mọi công việc mộc vì bạn không muốn học các công cụ khác.
| Cách Tiếp Cận | Kích Thước Phản Hồi | Hiệu Suất Mạng | Độ Phức Tạp Khách Hàng |
|---|---|---|---|
| Trả Về Tất Cả | 47MB+ mỗi yêu cầu | Chậm - quá tải lớn | Thấp - nhưng lãng phí |
| Chỉ Phân Trang | Biến thiên, không kiểm soát | Vừa phải - vẫn lấy dữ liệu quá nhiều | Thấp - triển khai đơn giản |
| Lọc Trường | Khách hàng kiểm soát | Tốt - lấy những gì bạn cần | Vừa phải - yêu cầu tham số truy vấn |
| Thay Thế GraphQL | Kiểm soát chính xác | Tuyệt vời - không lấy dữ liệu thừa | Cao - cần học hỏi |
| Mặc Định Thông Minh + Mở Rộng | Cơ sở tối ưu hóa | Tuyệt vời - cách tiếp cận cân bằng | Thấp - trực quan cho hầu hết các trường hợp |
Các yêu cầu GET phải an toàn và idempotent. An toàn có nghĩa là chúng không thay đổi trạng thái của máy chủ. Idempotent có nghĩa là gọi chúng nhiều lần sẽ cho ra cùng một kết quả. Điều này không phải lý thuyết — nó cho phép lưu cache, điều có thể giảm tải cho máy chủ của bạn tới 60-80% cho các API có nhiều đọc. Khi tôi tối ưu hóa API hồ sơ người dùng của chúng tôi bằng cách triển khai chính xác nghĩa của GET và lưu cache HTTP, chi phí máy chủ của chúng tôi đã giảm xuống còn 4,200 đô la mỗi tháng.
POST tạo ra các tài nguyên mới. Nó không an toàn cũng không idempotent — việc gọi nó hai lần tạo ra hai tài nguyên. PUT thay thế toàn bộ tài nguyên và là idempotent — gọi nó mười lần sẽ có cùng hiệu ứng như gọi nó một lần. PATCH cập nhật một phần tài nguyên và nên là idempotent. DELETE xóa một tài nguyên và là idempotent. Những sự phân biệt này rất quan trọng cho logic thử lại của khách hàng, các chiến lược cache và cấu hình cổng API.
Dưới đây là một ví dụ thực tế từ API xử lý thanh toán của chúng tôi. Ban đầu chúng tôi đã sử dụng POST cho mọi thứ, bao gồm cả việc kiểm tra trạng thái thanh toán. Khi sự cố mạng khiến khách hàng thử lại các yêu cầu, chúng tôi đã tạo ra các bản ghi thanh toán trùng lặp. Sau khi tái cấu trúc để sử dụng GET cho việc kiểm tra trạng thái và triển khai các khóa idempotency phù hợp cho các yêu cầu POST, các khoản thanh toán trùng lặp đã giảm từ 2.3% xuống 0.01% giao dịch. Đó là tiền thật tiết kiệm và niềm tin của khách hàng được bảo tồn.
Một câu hỏi phổ biến: khi nào bạn nên sử dụng PUT so với PATCH? Sử dụng PUT khi khách hàng gửi toàn bộ biểu diễn tài nguyên. Sử dụng PATCH khi khách hàng chỉ gửi các trường cần thay đổi. Trên thực tế, PATCH thường là lựa chọn phù hợp hơn vì khách hàng hiếm khi muốn gửi mọi trường. Phân tích của chúng tôi cho thấy rằng 94% các thao tác cập nhật của chúng tôi sử dụng PATCH, và việc này đã giúp các ứng dụng di động của chúng tôi hiệu quả hơn bằng cách giảm kích thước gói trung bình 73%.
Nguyên tắc 3: Mã Trạng Thái Là Giao Thức Giao Tiếp Của Bạn
Các mã trạng thái HTTP là một ngôn ngữ tiêu chuẩn hóa cho giao tiếp...