💡 Key Takeaways
- Principle 1: Design Your API Like a Product, Not a Database Wrapper
- Principle 2: Embrace HTTP Status Codes Properly (But Don't Overthink Them)
- Principle 3: Version Your API From Day One (And Do It Right)
- Principle 4: Design Intuitive Resource Naming and URL Structures
Tôi vẫn nhớ ngày tôi phải giải thích cho CEO của chúng tôi tại sao ứng dụng di động của chúng tôi lại làm tiêu tốn dữ liệu của người dùng nhanh như cháy rừng. Đó là năm 2016, và tôi đã làm việc ba năm trong vai trò Kiến trúc sư API chính tại một công ty khởi nghiệp fintech. REST API của chúng tôi đã gửi lại toàn bộ đối tượng người dùng—bao gồm cả ảnh đại diện mã hóa trong base64—mỗi lần ứng dụng kiểm tra số dư tài khoản. Chúng tôi đã mất hàng loạt khách hàng, và tôi là người đã thiết kế API khiến chúng tôi gặp khó khăn.
💡 Những điểm chính
- Nguyên tắc 1: Thiết kế API của bạn như một sản phẩm, không phải là một lớp bao quanh cơ sở dữ liệu
- Nguyên tắc 2: Sử dụng mã trạng thái HTTP đúng cách (Nhưng đừng nghĩ quá nhiều về chúng)
- Nguyên tắc 3: Phiên bản hóa API của bạn ngay từ ngày đầu tiên (Và làm điều đó đúng)
- Nguyên tắc 4: Thiết kế đặt tên tài nguyên và cấu trúc URL một cách trực quan
Bài học đau đớn đó đã dạy tôi một điều quan trọng: Thiết kế REST API không chỉ là làm cho mọi thứ hoạt động. Nó là làm cho chúng hoạt động tốt, ở quy mô lớn, dưới các điều kiện thực tế mà sách giáo khoa không đề cập. Trong suốt mười hai năm qua, xây dựng API cho các công ty từ các công ty khởi nghiệp 10 người đến các doanh nghiệp Fortune 500, tôi đã thấy những sai lầm giống nhau được lặp lại vô số lần—và tôi đã mắc phải hầu hết trong số đó.
Hôm nay, tôi sẽ chia sẻ mười nguyên tắc đã biến đổi cách tôi thiết kế API. Đây không phải là những khái niệm lý thuyết từ các bài báo học thuật. Chúng là những hướng dẫn đã được thử nghiệm qua chiến đấu, hình thành trong các môi trường sản xuất phục vụ hàng triệu yêu cầu mỗi ngày. Dù bạn đang xây dựng API đầu tiên hay tái cấu trúc API thứ mười, những nguyên tắc này sẽ giúp bạn tạo ra các giao diện mà các nhà phát triển thực sự muốn sử dụng.
Nguyên tắc 1: Thiết kế API của bạn như một sản phẩm, không phải là một lớp bao quanh cơ sở dữ liệu
Sai lầm lớn nhất mà tôi thấy trong thiết kế REST API là coi API như một lớp mỏng trên các bảng cơ sở dữ liệu. Tôi đã xem xét hàng trăm API mà ở đó các điểm cuối ánh xạ một-một với các lược đồ cơ sở dữ liệu, lộ ra các chi tiết thực hiện nội bộ mà không bao giờ đáng thấy ánh sáng. Cách tiếp cận này tạo ra những giao diện mong manh mà hỏng hóc mỗi lần mô hình dữ liệu của bạn thay đổi.
Khi tôi gia nhập công ty hiện tại với vai trò VP Kỹ thuật Nền tảng, API của chúng tôi đã có 47 điểm cuối mà phản ánh trực tiếp lược đồ PostgreSQL của chúng tôi. Thay đổi tên một cột duy nhất yêu cầu điều phối cập nhật giữa 23 ứng dụng khách khác nhau. Nợ kỹ thuật đang làm ngạt thở khả năng đổi mới của chúng tôi.
Thay vào đó, hãy coi API của bạn như một sản phẩm với chu kỳ sống riêng, chiến lược phiên bản và các yếu tố trải nghiệm người dùng. Những người tiêu dùng API của bạn không quan tâm đến chiến lược chuẩn hóa cơ sở dữ liệu của bạn hay kiến trúc microservices nội bộ của bạn. Họ quan tâm đến việc hoàn thành các nhiệm vụ cụ thể một cách hiệu quả.
Ví dụ, thay vì lộ diện các điểm cuối riêng biệt cho /users, /user_profiles, /user_preferences, và /user_settings, hãy xem xét những gì mà người tiêu dùng API của bạn thực sự cần. Trong hầu hết các trường hợp, họ muốn một điểm cuối đồng bộ /users/{id} trả về một tài nguyên được soạn thảo cẩn thận. Sử dụng các tham số truy vấn như ?fields=profile,preferences để cho phép những người tiêu dùng yêu cầu chính xác những gì họ cần.
Tôi đã thực hiện cách tiếp cận này tại một công ty SaaS trong lĩnh vực chăm sóc sức khỏe, nơi chúng tôi đã giảm diện tích API của mình từ 89 điểm cuối xuống còn 34 trong khi thực sự tăng chức năng. Thời gian phản hồi đã giảm 43% bởi vì chúng tôi đã loại bỏ các cuộc trao đổi lặp đi lặp lại phát sinh từ việc yêu cầu nhiều yêu cầu để lắp ghép thông tin cơ bản. Quan trọng hơn, tài liệu API của chúng tôi đã trở nên dễ hiểu, và thời gian hướng dẫn nhà phát triển đã giảm từ hai tuần xuống còn ba ngày.
Chìa khóa là hiểu mô hình miền của API của bạn, mà có thể khác biệt đáng kể với mô hình lưu trữ của bạn. Dành thời gian với những người tiêu dùng API của bạn—dù họ là các nhóm frontend nội bộ hay các đối tác bên ngoài—và hiểu quy trình làm việc của họ. Thiết kế tài nguyên xung quanh mô hình tư duy của họ, không phải các bảng cơ sở dữ liệu của bạn.
Nguyên tắc 2: Sử dụng mã trạng thái HTTP đúng cách (Nhưng đừng nghĩ quá nhiều về chúng)
Các mã trạng thái HTTP là tuyến đầu tiên giao tiếp của API với khách hàng, tuy nhiên tôi liên tục thấy chúng bị sử dụng sai hoặc hoàn toàn bị bỏ qua. Một lần, tôi đã kiểm toán một API trả về 200 OK cho mọi phản hồi, bao gồm cả lỗi, với trạng thái thực sự ẩn sau một trường JSON. Các nhà phát triển nghĩ rằng họ đang giúp đỡ bằng cách "luôn thành công", nhưng thực tế họ đã phá hỏng cách xử lý lỗi của mọi thư viện khách hàng HTTP.
Bạn không cần phải ghi nhớ tất cả 63 mã trạng thái HTTP, nhưng bạn chắc chắn phải sử dụng các mã cốt lõi đúng cách. Dưới đây là phân tích thực tế của tôi dựa trên mười hai năm kinh nghiệm trong sản xuất:
- 200 OK: GET, PUT, hoặc PATCH thành công trả về nội dung
- 201 Created: POST thành công tạo ra một tài nguyên (bao gồm tiêu đề Location)
- 204 No Content: DELETE hoặc cập nhật thành công không trả về gì
- 400 Bad Request: Khách hàng gửi dữ liệu không hợp lệ (bao gồm các lỗi xác thực cụ thể)
- 401 Unauthorized: Cần xác thực hoặc xác thực thất bại
- 403 Forbidden: Đã xác thực nhưng không có quyền
- 404 Not Found: Tài nguyên không tồn tại
- 409 Conflict: Yêu cầu mâu thuẫn với trạng thái hiện tại (tạo bản sao trùng lặp, không khớp phiên bản)
- 422 Unprocessable Entity: Về mặt cú pháp là đúng nhưng về mặt ngữ nghĩa là không hợp lệ
- 429 Too Many Requests: Vượt quá giới hạn tỷ lệ (bao gồm tiêu đề Retry-After)
- 500 Internal Server Error: Một cái gì đó đã hỏng ở phía bạn
- 503 Service Unavailable: Tạm thời không có dịch vụ hoặc bảo trì
Sự khác biệt giữa 401 và 403 làm chao đảo nhiều nhà phát triển. Hãy xem 401 như "Tôi không biết bạn là ai" và 403 như "Tôi biết bạn là ai, nhưng bạn không thể làm điều đó." Điều này quan trọng vì nó cho khách hàng biết liệu việc tái xác thực có thể hữu ích hay không.
Tương tự, 400 với 422 là điều vi tế nhưng hữu ích. Sử dụng 400 cho JSON bị sai định dạng hoặc thiếu các trường bắt buộc—những thứ không thể phân tích cú pháp cơ bản. Sử dụng 422 cho các vi phạm logic kinh doanh như cố gắng chuyển nhiều tiền hơn số tiền có trong tài khoản. Sự phân biệt này giúp khách hàng phân loại lỗi một cách thích hợp.
Tại công ty trước đây của tôi, chúng tôi đã thực hiện việc sử dụng mã trạng thái đúng cách và thấy các phiếu hỗ trợ liên quan đến lỗi API giảm 67% trong quý đầu tiên. Các nhà phát triển cuối cùng đã có thể dựa vào các khái niệm chuẩn của HTTP thay vì phân tích thân phản hồi để xác định thành công hay thất bại.
Nguyên tắc 3: Phiên bản hóa API của bạn ngay từ ngày đầu tiên (Và làm điều đó đúng)
Tôi đã học bài học này theo cách khó khăn. Năm 2014, tôi đã ra mắt một API mà không phiên bản hóa vì "chúng tôi sẽ chỉ duy trì tính tương thích ngược mãi mãi." Sáu tháng sau, chúng tôi cần thực hiện một thay đổi lớn để hỗ trợ yêu cầu kinh doanh quan trọng. Chúng tôi đã có 1.200 người tiêu dùng API hoạt động mà không có cách nào để di chuyển chúng từ từ. Kết quả là một bản nâng cấp bắt buộc đã phá hỏng...