Làm thế nào để có một API thật tốt :)

Để thiết kế một API tốt thật sự là một điều rất khó. Tùy vào mỗi hệ thống mà có hướng tiếp cận riêng, tuy nhiên bạn có thể tham khảo cho mình một vài cách "Best practices" để viết API cho hệ thống của riêng mình.


Ảnh copy: API cứ thế là cắm và chạy

Thế nào là một API tốt.

  • Phục vụ được nghiệp vụ của hệ thống
  • Đáp ứng được nhiều người dùng nhất có thể
  • Thân thiện, dễ sử dụng với khách hàng và phần còn lại của thế giới (frontend)
  • Xanh, sạch, đẹp (ý mình là không bugs, rõ ràng, ngắn gọn, dễ bảo trì)

Một API tốt đồng nghĩa là cánh cổng mở ra một thế giới tốt đẹp trở nên dễ dàng hơn bao giờ hết. (xD)

Khách hàng khen ngợi, frontend bớt phàn nàn, ít phải support nhất.


Ảnh mạng: Tôi đang nhìn anh đấy, là anh, chính là anh, chúng tôi thật vinh hạnh khi làm việc với anh, vỗ tay

I. Endpoint

Endpoint luôn là vấn đề cần quan tâm. Chắc chắn phải thể hiện được chức năng mong muốn.

https://example.com/api/{version}/{function_name}/.../
https://api.example.com/{version}/{function_name}/.../

Thật là cố gắng chia thành các endpoint riêng biệt để client hoặc đám frontend dễ dàng nhận biết api đó làm gì.

{vesion}: Là phiên bản của API, lỡ may ngày nào đó có phải update hệ thống lên phiên bản mới thì client có thể cập nhập dễ dàng và không ảnh hưởng tới hệ thống cũ, user cũ.
{function_name}: Có thể là một resource: /user, /classe/.
cũng có thể là một action.

Ví dụ: GET https://api.example.com/user/

II. Method:

POST /user hay PUT /user/:id để tạo người dùng mới.
GET /user để lấy danh sách người dùng.
GET /user/:id để lấy thông tin của một người dùng.
PATCH /user/:id để sửa một bản ghi người dùng đã có.
DELETE /user/:id để xóa một người dùng.

Hãy lựa chọn cho mình một method phù hợp và đúng đắn.
Hãy là một developer thông thái.

III. Request

Chúng ta nên định nghĩa rõ ràng các field và kiểu dữ liệu của nó.
Headers: Content Type, API Key, v.v...
Các giá trị ngoại lệ: null, empty min, max chiều dài mỗi field

 curl -X POST \
   https://www.jinz.com/api/v1/location \
   -H 'Cache-Control: no-cache' \
   -H 'Content-Type: application/json' \
   -H 'x-api-key: example' \
   -d '{
   "requestId": 1530115034585, //long
   "address": "313 Nguyễn Thị Thập,  Quận 7, TP. HCM" //String
  }'

Tên field và kiểu dữ liệu nên giống nhau về mặt ý nghĩa ví dụ như:
Thế này là đúng
{ "count": 1 }
Chứ không nên thế này:
{ "count": "1" }

Mình đã gặp vài trường hợp lỗi ở phía server khi không thể parse được field amount, họ design field là kiểu string với giá trị bên trong là long nhưng nhiều frontend gửi lên kiểu float :xD
Nếu có lỗi lầm thì hãy cố gắng khắc phục ở lần sau

IV. Response

Ảnh trên mạng: Hội những người muốn giết cái đứa viết API này

"Response là thứ tối quan trọng và những thứ khác có hay không không quan trọng" - Khách hàng said .

Có gọi là có trả lời đừng như ai đó gọi rồi lại im.

Không biết bao nhiều lần anh em developer chúng ta đâm vào cảnh vò đầu bứt tóc, đầu đường xó chợ, chửi thề đủ kiểu để nói rằng api như sh**.

Response từ backend làm họ thật sự bối rối, chưa biết là do ai sai nhưng cũng không biết đâu mà lần.

Ví dụ điển hình là trường hợp anh chàng nọ gọi một API và trả về một câu thông báo to tướng: Dữ liệu sai định dạng cùng với dòng code: 400. Ảnh không biết lỗi ở đâu mặc dù đã làm theo tài liệu, 2h sáng anh gọi backend không nghe máy :))

Vậy thì thế nào để đáp ứng, đôi lúc cũng nên sống chậm lại, suy nghĩ về nước Mĩ, yêu thương nhiều lên và tất yếu là nên phục vụ đúng mong muốn cho mấy ảnh.

1. Trả đúng http status code và nhẹ nhàng thêm một vài dòng mô tả lỗi trong body response thế là chúng ta được thêm điểm cộng trong mắt mọi người.

Mình biết sẽ là khá khó chịu khi phải viết thêm code để trả về lỗi sai của người nào đó nhưng tốt nhất hãy để mọi thứ thật tốt đẹp :) trong đó có mình.

Bởi vậy thay vì chỉ

    POST: 4xx, 5xx 

Mà là:

{
  "status_code": 401,
  "description": "Thiếu api key"
}

Tiếp là

{
  "status_code": 400,
  "message": "Dữ liệu sai định dạng",
  "details": [{
  	"field":"address",
  	"description": "Địa chỉ không thể để trống"
  	}]
}

Sau tất cả:

{
  "status_code": 200,
  "longitude": 10.738372,
  "latitude": 106.715598
}

Tips: Các bạn thấy không bên trên mình toàn trả lỗi 4xx, ko có 5xx. Vì mình biết code mình không có lỗi, lỗi tại định mệnh :p

2. Body trong response nên có một định dạng trả về chung, có nghĩa đâu đó trong code backend chúng ta có tồn tại exception hay bất kỳ lý do gì đó thì cũng nên trả đúng format đó. Vì có những ngôn ngữ cần biết trước data trả về như thế nào để parse qua dạng object. Chúng ta dễ bị chửi thề ở đoạn này, lúc trả này trả thế này, lúc trả thế kia.
Hãy cố gắng thật dịu dàng để có thể làm dâu trăm họ

V. Document

Có lẽ điều tuyệt vời nhất đối với developer chúng ta khi tiếp xúc với repository trên GIT là một README.MD xanh, sạch, đẹp. Tương tự như vậy còn gì tuyệt vời hơn khi làm việc với API mà có một bộ documents đầy đủ.

Có thể bạn ghét đọc hoặc viết documents nhưng đó phần cuộc sống của chúng ta.

"Thử hỏi xem cảm giác của bạn khi đang là sinh viên lúc tiếp cận một công nghệ mới hoặc chuẩn bị làm việc với các hệ thống external khác như Google, Facebook, Payment, SMS, ... như thế nào " - Một chàng trai từng trải qua nhiều cảm giác khó khăn chia sẻ :(

Thế nào được gọi một documents tốt cho sức khỏe và không chửi thề:

  • Mô tả cách hoạt động của hệ thống (nếu có)
  • Giới thiệu về chức năng của API
  • Các cấu hình để có thể chạy API: api key, allow ip, ..
  • Mô tả request/response: tên field, kiểu dữ liệu, ngoại lệ, ý nghĩa từng field - Dạng table
  • Ví dụ về request và reponse
  • Mô tả lỗi
  • Các câu hỏi thường gặp
  • Nếu có hẳn 1 bộ collections POST MAN nữa là tuyệt vời.

Tiện thể ở đây mình giới thiệu một số công cụ có thể các bạn thừa biết để:

Tạo API Document từ code của mình:

Opensource tạo website viết document Internal/Public

  • GitBook: Cái này dùng để viết sách nhưng có thể sài ké làm trang document cũng khá hay
  • Docusaurus: Cái này của Facebook hiện đang áp dụng cho khá nhiều project FB: React, React Native https://reactjs.org/
  • MkDocs: Cái này cũng dễ dùng

Các opensource trên đều hỗ trợ viết bài bằng Markdown, chia version, tùy biến giao diện.
Đối với mình thế là đủ, anh em cần thì có thể vô trang chủ đọc tài liệu nó tạo cho mình một document thật chuyên nghiệp.

Hi vọng bài viết có thể giúp phần nào cuộc sống anh em trở nên dễ dàng.