Kinh nghiệm thiết kế và làm việc với API
Api (Application Program Interface) là những chuẩn đầu ra, đầu vào cho phép 2 hay nhiều hệ thống hoặc các phần của cùng 1 hệ thống tương tác với nhau. Api cho phép những thành phần độc lập hoạt động với nhau, giúp chia nhỏ 1 nhiệm vụ lớn thành nhiều nhiệm vụ đơn giản hơn. Tuy nhiên, việc thiết kế và sử dụng Api không phải lúc nào cũng suôn sẻ. Dưới đây là một số kinh nghiệm của tác giả giúp cho việc sử dụng Api hiệu quả hơn. Bài viết chủ yếu tập trung vào khả năng sử dụng và bảo trì, tạm thời bỏ qua các vấn đề bảo mật hệ thống và tối ưu tài nguyên. Hy vọng bài viết sẽ có ích cho bạn trên con đường lập trình đầy gian nan.
Tránh tập trung chủ yếu vào trường hợp đúng, quên đi tầm quan trọng của trường hợp sai.
Con người có xu hướng tập trung vào thành công hơn là vào thất bại. Với rất nhiều người, thất bại có nghĩa là tất cả dừng lại, bắt đầu một công việc khác mà không nhận ra rằng ngay cả trong thất bại, người ta cũng có rất nhiều việc có thể làm để tránh thất bại lần sau, hoặc giúp cho người khác không bị thất bại giống mình.
Thiết kế Api cũng vậy. Với rất nhiều hệ thống, khi xảy ra lỗi, hệ thống đơn giản dừng toàn bộ hoạt động và thông báo lại cho người dùng. Tuy nhiên chúng ta hoàn toàn có thể làm nhiều hơn thế.
Ví dụ: Trong trường hợp lỗi xảy ra do một bad record trong database, chúng ta hoàn toàn có thể xóa bản ghi đó đi, hoặc chuẩn hóa lại nó, để api có thể hoạt động bình thường trong các lần gọi sau.
Suggest: Điều tra nguyên nhân lỗi, sửa nó nếu có thể. Chú ý roll back nếu làm việc với DB.
Tránh đánh đồng tất cả các trường hợp sai.
Có một xu thế đã ăn sâu vào tiềm thức của rất nhiều người: Đã thất bại thì dù bạn đã làm gì cũng không quan trọng, kết quả quyết định tất cả. Dù bạn có làm 99 việc tốt, việc cuối cùng xấu thì bạn vẫn là người xấu. Tuy nhiên, thực tế không đơn giản như vậy, nếu con đường dẫn tới chân lý có 1 thì con đường dẫn tới sai trái là hàng trăm, thậm chí hàng nghìn. Vì vậy việc phân loại và xử lý các trường hợp sai là một công việc thiết yếu.
VD: Gọi Api để insert 1 bản ghi và nhận được thông báo lỗi. Lỗi này có thể là do dữ liệu không chuẩn hoặc dữ liệu đã tồn tại. Với các nguyên nhân khác nhau, bên gọi cần có các xử lý khác nhau. Tuy nhiên, nếu thông báo từ bên nhận dữ liệu không rõ ràng, bên gọi sẽ lúng túng không biết nên xử lý thế nào.
Suggest: Ngoài status (success or fail), api nên hỗ trợ thêm error_code. Hệ thống error_code có thể được tiến hóa trong suốt quá trình phát triển api.
Đầu ra, đầu vào mềm dẻo nhất có thể.
Thông thường mỗi api có một chuẩn đầu vào, đầu ra quy định từ trước. Nhưng có một thực tế là dữ liệu có thể được thu thập từ nhiều nguồn khác nhau, sẽ thuận tiện hơn rất nhiều nếu api có thể chấp nhận nhiều chuẩn khác nhau: Json, xml, file, serialize. Việc thiết kế api mềm dẻo cũng có ích trong các trường hợp database migration, change requirement.
Tiết kiệm đường truyền.
Xem xét 2 mảng dữ liệu:
[{idfa:1,auid:2,email:3,phone:4},{idfa:5,auid:6,email:7,phone:8}]
{idfa:[1,5],auid:[2,6],email:[3,7],phone:[4,8]}
Với cùng 1 lượng thông tin, dữ liệu thứ 2 tiết kiệm đáng kể tài nguyên vì hạn chế được việc lặp lại các key idfa, auid, email, phone. Nhiều người nghĩ rằng sự chênh lệch này là không đáng kể nhưng khi làm việc với hàng triệu bản ghi, chúng ta sẽ thấy được sự khác biệt. Mọi vấn đề, dù là nhỏ nhất, nếu không được quan tâm thích đáng, sẽ đến lúc nó tạo ra lỗi lớn không thể khống chế được.
Suggest: Đưa ra tất cả các phương án khả thi, lựa chọn phương án tối ưu nhất.
Chấp nhận lỗi tối đa có thể
Xem xét ví dụ:
Yêu cầu Api xử lý mảng dữ liệu: [Object1, Object2, Object3, Object4]
Trong đó, 1,2,4 là hợp lệ, còn 3 là bất hợp lệ.
Trong các thiết kế thông thường, hệ thống sẽ thông báo là toàn bộ dữ liệu này là bất hợp lệ, ngừng xử lý. Tuy nhiên trong trường hợp các dữ liệu này là tương đối độc lập, chúng ta hoàn toàn có thể xử lý cho các đối tượng 1,2,4 rồi thông báo lại cho [success:[1,2,4],fail:[3]]. Như vậy không những giúp hệ thống tối ưu hơn mà còn giúp phía gọi có thể phán đoán và xử lý tốt hơn vì trong đa số trường hợp, object3 là rác hệ thống do các quá trình test, lỗi, data migration.