[API Design] Phần 1 - Tổng quan về API Design
1. Thiết kế API là gì?
1.1. Hậu quả tồi tệ của việc thiết kế API tồi
Bạn sẽ làm gì khi sử dụng một vật dụng hằng ngày mà trước đây bạn chưa từng sử dụng? Đó là việc bạn cần xem xét kỹ giao diện của nó để xác định mục đích và cách sử dụng của nó dựa trên những gì bạn có thể thấy và kinh nghiệm trước đây của bạn.
Hãy xem xét một ví dụ giả định dưới đây: Một thiết bị có tên UDRC 1138. Thiết bị này có thể là gì? Mục đích của nó có thể là gì?
Trước hết, nhìn vào tên UDRC 1138, ta khó có thể biết được thiết bị này là gì. Vậy hãy thử nhìn vào giao diện của chúng dưới đây.
Ở bên phải có 6 nút và không được gán nhãn. Dựa vào kinh nghiệm bản thân, có thể chúng có ý nghĩa gì đó giống như start / stop chẳng hạn (giống như các nút của trình phát đa phương tiện). Một vài nút với hình dạng khác lạ khó có thể biết được mục đích sử dụng là gì.
Trên màn hình hiển thị, có các đơn vị như ft, rad, NM, km/h. Ta có thể đoán được ft có thể là feet. km/h là tốc độ. Còn NM và rad là gì, thực sự khó để đoán được.
Và ở cuối màn hình LCD, cũng có 1 thông báo cảnh báo rắc rối nếu chúng ta nhập các giá trị ngoài phạm vi mà không cần kiểm soát an toàn.
OK, giao diện trên chắc chắn khó để hiểu nó là gì và thực sự không trực quan lắm. Chúng ta hãy đi xem tài liệu mô tả kỹ thuật để hiểu hơn về thiết bị ở hình dưới đây.
Theo như mô tả, chúng ta biết rằng:
Đây là 1 thiết bị điều khiển drone từ xa
Thông số ft: Khoảng cách đến mặt đất tính bằng feet
Thông số NM: Chiều cao tính bằng hải lý
Thông số Rad: Định hướng của drone
Thông số km/h: Tốc độ bay của drone
Các nút ở phía bên phải lần lượt là: Tăng tốc độ Tăng độ cao Giảm độ cao Rẽ trái Rẽ phải Giảm tốc độ
Có một vài nhận xét về thiết kế của thiết bị này:
Tên của thiết bị (UDRC 1138) không gợi cho chúng ta hiểu được công dụng của thiết bị là gì.
Theo các bộ phim về máy bay tôi đã xem, feet để đo chiều cao, hải lý để đo khoảng cách. Chứ không phải là ngược lại.
Các nút cũng được sắp xếp theo thứ tự lộn xộn, gây khó khăn cho người sử dụng. Các hình tượng trưng cũng khó để liên tưởng đến chức năng của nó, vì tôi chưa bao giờ bắt gặp các nút có hình như vậy ở các thiết bị khác.
Lời cảnh báo của thiết bị: dường như thiết bị này chỉ hoạt động trong phạm vi 50 meter. Phạm vi này được tính toán dựa trên khoảng cách mặt đất và độ cao do màn LCD cung cấp. ⇒ What, nghĩa là người sử dụng cần tự tính khoảng cách đến thiết bị bằng định lý Pytago?
Vậy nếu là bạn, liệu bạn có muốn mua và sử dụng thiết bị này không?
Trong trường hợp bạn không có lựa chọn nào khác ngoài việc sử dụng thiết bị khủng khiếp này, tôi chúc bạn những điều may mắn nhất và sớm sử dụng được nó.
Có phải bạn đang nghĩ, làm sao một thiết kế tồi tệ như vậy lại được đưa vào sản xuất chứ? Nhưng hãy đối mặt với sự thật: những thiết kế kém hiệu quả vẫn luôn được sản xuất.
Đã bao nhiêu lần bạn phàn nàn khi sử dụng một thiết bị nào đó, hoặc khi truy cập 1 trang web nào đó có thiết kế không tốt? Đã bao nhiêu lần bạn quyết định không mua hay không sử dụng một thiết bị vì thiết kế kém hiệu quả của nó?
Một sản phẩm được thiết kế kém, có thể bị sử dụng sai, hoặc thậm chí không được sử dụng. Đôi khi người dùng còn không thể phát hiện ra rằng mình đã dùng sai ngay lần sử dụng đầu tiên.
Thật không may, API cũng giống như vậy, nó có thể bị thiết kế kém hiệu quả.
1.2. Tại sao thiết kế API lại quan trọng
Dưới đây là những lý do giải thích tại sao việc thiết kế API lại quan trọng:
Trải nghiệm của developer:
Dễ sử dụng và dễ hiểu: Một API được thiết kế tốt sẽ dễ dàng để các nhà phát triển khác hiểu và sử dụng. Điều này làm giảm thời gian học hỏi và tăng tốc quá trình phát triển ứng dụng.
Tài liệu chi tiết: Một API tốt đi kèm với tài liệu chi tiết, rõ ràng, giúp nhà phát triển nhanh chóng nắm bắt được cách thức hoạt động và cách sử dụng các endpoint.
Tính bảo trì và mở rộng:
Tính nhất quán: API nhất quán giúp dễ dàng duy trì và cập nhật. Khi các quy tắc và cấu trúc API được thiết lập một cách rõ ràng, việc thay đổi hay thêm mới tính năng sẽ trở nên dễ dàng hơn
Khả năng mở rộng: API thiết kế tốt có khả năng mở rộng dễ dàng để đáp ứng nhu cầu thay đổi của doanh nghiệp và người dùng.
Hiệu suất và bảo mật:
Hiệu suất: Một API được thiết kế tốt có thể tối ưu hóa hiệu suất thông qua việc giảm thiểu yêu cầu không cần thiết và cải thiện cách dữ liệu được truyền tải.
Bảo mật: Thiết kế API cần tính đến các khía cạnh bảo mật để bảo vệ dữ liệu và hệ thống khỏi các lỗ hổng và tấn công tiềm ẩn
Tích hợp
Khả năng tích hợp: API đóng vai trò quan trọng trong việc tích hợp các hệ thống khác nhau. Một API tốt giúp dễ dàng kết nối và trao đổi dữ liệu giữa các hệ thống, hỗ trợ hợp tác và phát triển sản phẩm mới
Sự phát triển của hệ sinh thái: API tốt giúp xây dựng một hệ sinh thái xung quanh sản phẩm, khuyến khích bên thứ ba phát triển các ứng dụng hoặc dịch vụ bổ sung
1.3. Các thành phần của việc thiết kế API
1.3.1. Học các nguyên tắc về thiết kế một interface
Khi một nhà thiết kế giỏi đặt 1 nút vào 1 vị trí cụ thể, chắc chắn phải có nguyên do của nó.
Có thể bạn đã nghe về RPC, SOAP, REST, gRPC hay GraphQL. Bạn có thể tạo API bằng tất cả các kiểu API này. Mỗi kiểu API có thể đi kèm với một số phương pháp phổ biến mà bạn có thể làm theo, nhưng điều này không ngăn cản việc bạn vẫn có thể mắc lỗi.
Việc biết các nguyên tắc cơ bản của thiết kế API mang lại cho bạn nền tảng vững chắc để thiết kế API theo bất kỳ phong cách nào và đối mặt với mọi thách thức thiết kế.
1.3.2. Khám phá tất cả các khía cạnh của thiết kế API
Đối với thiết kế UI:
Việc thiết kế cần hiểu được mục đích của nó và người dùng muốn đạt được điều gì. Giao diện phải dễ sử dụng, dễ hiểu và quan trọng nhất là an toàn.
Ví dụ UDRC 1138 là một giao diện thiết kế tồi với màn hình và các nút phức tạp, và thiếu chức năng an toàn.
Việc thiết kế cần tính đến cả ngữ cảnh khi sử dụng (ví dụ: người điều khiển UDRC 1138 cần đeo găng tay trong thời tiết lạnh) và cả những hạn chế về công nghệ (giới hạn về tần suất truyền lệnh)
Thiết kế kém có thể do thiếu đào tạo, thiếu kiểm tra hoặc bỏ qua ý tưởng của người thiết kế.
Người dùng thường quen với giao diện cũ, nên việc thay đổi cần cẩn trọng để tránh họ phải học lại cách sử dụng.
Đối với thiết kế API:
Tương tự như thiết kế UI, thiết kế API không chỉ cần dễ hiểu, dễ dùng mà còn cần bảo mật, tránh lộ dữ liệu nhạy cảm
Cần tính đến ngữ cảnh, hạn chế, người dùng, cách xây dựng, khả năng phát triển của API
Nhà thiết kế cần tham gia vào toàn bộ vòng đời của API, từ thảo luận ban đầu đến phát triển, tài liệu, cập nhật và ngừng sử dụng.
Các API Designer trong tổ chức cần phối hợp với nhau để đảm bảo tất cả các API có tính nhất quán, giúp người dùng dễ dàng sử dụng tổng thể các API
2. Thiết kế API cho người dùng của nó
2.1. Quan điểm đúng đắn để thiết kế giao diện sử người dùng
Các nhà thiết kế API phải học hỏi nhiều điều từ việc thiết kế giao diện người dùng hằng ngày, cho dù đó là giao diện của các đối tượng vật lý (cửa, thiết bị nhà bếp, điều khiển từ xa…) hay các đối tượng ảo (trang web, ứng dụng di động).
Việc chọn đúng quan điểm thiết kế, đúng góc nhìn là một trong những khía cạnh quan trọng nhất của việc thiết kế API.
2.1.1. Tập trung vào cách mọi thứ hoạt động sẽ dẫn đến các thiết kế phức tạp
Để tôi giới thiệu cho bạn, thiết bị Kitchen Radar 3000.
Vậy thiết bị này là gì, tại sao nó lại có tên Kitchen Radar 3000 (nghe giống như 1 thiết bị quân sự nào đó)? Ở bên phải của thiết bị có 1 nút “Magnetron On”. Điều gì sẽ xảy ra nếu chúng ta kích hoạt nút này?
Giờ hãy nhìn xem hướng dẫn sử dụng của thiết bị:
OK theo như hướng dẫn, chúng ta biết rằng:
Kitchen Radar 3000 dường như là một loại lò nướng mới, sử dụng vi sóng để hâm nóng thức ăn. Nó được phát minh bởi người đang làm việc trên radar nên mới có tên như vậy
Khi nhấn nút Magnetron On, nó sẽ bật một bộ phận có tên là magnetron. Nhiệm vụ của bộ phận này là tạo ra vi sóng vô tuyến. Những vi sóng này tạo ra nhiệt khi chúng đi qua thức ăn.
Sau khi thức ăn chín, người dùng có thể nhả nút để tắt máy phát này.
Hãy cùng có 1 vài nhận xét cho thiết bị trên:
Đặt tên dựa trên lịch sử và hoàn toàn che giấu mục đích sử dụng thực sự là 1 điều khủng khiếp.
Người dùng sẽ phải tự canh thời gian thức ăn chín để nhả nút sau khi nhấn nút.
Nếu người dùng chỉ muốn sử dụng một phần sức mạnh của lò thì sao, có thể điều chỉnh được không? Hay người dùng phải nhấp nhả liên tục để tương ứng với công suất làm nóng mong muốn
Kết luận, việc thiết kế này hoàn toàn dựa trên cách hoạt động của thiết bị. Việc tập trung vào cách hoạt động sẽ dẫn đến cách sử dụng khó hiểu, thiếu chính xác.
2.1.2. Tập trung vào cách người sử dụng có thể làm sẽ dẫn đến các thiết kế đơn giản
Vậy hãy xem nếu tập trung vào cách người sử dụng có thể làm, thì việc thiết kế có tốt hơn không?
Trước hết, chúng ta có thể đổi lại tên cho dễ hiểu:
Kitchen Radar 3000 → Microwave Oven
Magnetron On → Heat
Chỉ cần thay đổi nhãn của thiết bị, tôi đã thấy thiết bị này dễ hiểu hơn rất nhiều rồi đấy. Hãy cùng xem các cải tiến tiếp theo.
Lò vi sóng này vẫn mang lại trải nghiệm tồi tệ cho người dùng, nhất là trong trường hợp người dùng chỉ muốn hâm nóng lượng nhỏ thức ăn mà vẫn phải dùng đến toàn bộ công suất của máy ⇒ Người dùng vẫn cần nắm vững tốc độ nhấp/nhả để làm nóng chậm hơn.
Vậy thiết kế sau sẽ đơn giản hoá việc đó:
Mọi người thường hâm nóng thức ăn bằng lò nướng như thế nào? Họ sẽ làm nóng thức ăn trong 1 khoảng thời gian nhất định, và với mức công suất nhất định.
Vậy chúng ta sẽ thay thế nút làm nóng duy nhất thành 2 nút cho phép chọn thời gian và công suất. Và việc xử lý chúng như thế nào là thuộc về nội tại của máy.
Thiết bị làm nóng này giờ đây có thể dễ hiểu và dễ sử dụng, bởi vì giao diện của nó không dựa vào cách thức hoạt động của máy, mà dựa vào những gì người dùng có thể làm với nó.
Nếu bạn giữ tư duy này cho việc thiết kế API, bạn sẽ là 1 nhà thiết kế API tuyệt vời. Bời vì API về cơ bản là bảng điều khiển cho các phần mềm và phải tuân theo các quy tắc giống như bất kỳ giao diện hằng ngày nào.
2.2. Tránh quan điểm từ nhà cung cấp khi thiết kế API
Cho dù bạn đang thiết kế API từ đầu hay dựa trên các hệ thống hiện có, quan điểm của nhà cung cấp chắc chắn sẽ hiển thị trong mọi giai đoạn thiết kế.
Các ảnh hưởng của việc thiết kế API từ quan điểm nhà cung cấp bao gồm:
Dữ liệu
Code và logic nghiệp vụ
Kiến trúc hệ thống
Tổ chức nhân sự
2.2.1. Tránh ảnh hưởng từ dữ liệu
Giả sử việc triển khai API shopping của chúng tôi xử lý thông tin trên 2 bảng CUSA và CUSB (đừng hỏi tôi tại sao lại như vậy).
Một thiết kế API bị ảnh hưởng bởi dữ liệu là:
API đọc CUSA
API đọc CUSB
Vậy nếu người tiêu dùng sẽ phải tích hợp với cả 2 API này để có thể lấy hết được thông tin khách hàng. Việc thiết kế API theo mô hình CSDL là dấu hiệu rõ ràng cho thấy quan điểm của nhà cung cấp, và đây có thể là 1 cách triển khai không hiệu quả.
Hình dưới đây mô tả cách sửa chữa sai lầm này: Chỉ sử dụng một API duy nhất Get customer’s information để lấy thông tin customer trên hệ thống.
2.2.2. Tránh ảnh hưởng của code và logic nghiệp vụ
Code và logic nghiệp vụ cũng có thể ảnh hưởng đến việc thiết kế API. Hãy xem ví dụ sau đây:
Vẫn là bộ API cho hệ thống Shopping ở trên. Giờ đây, mỗi khách hàng sẽ có 1 active address. Người dùng có thể cập nhật 1 địa chỉ mới cho mình. Nhưng các địa chỉ cũ thì không được xoá trên hệ thống, mà phải đặt thành trạng thái inactive để phục vụ cho các nghiệp vụ khác.
Với quan điểm của nhà cung cấp, chúng ta sẽ thiết kế ra 3 API như sau:
API lấy danh sách các địa chỉ (bao gồm cả active và inactive)
API thêm 1 địa chỉ vào hệ thống
API cập nhật trạng thái của địa chỉ
Những API này thể hiện ra cách dữ liệu được xử lý bên trong, và người dùng cần biết và tích hợp các logic này để hệ thống xử lý được đúng đắn:
Người dùng lấy tất cả các địa chỉ của họ
Người dùng lựa chọn địa chỉ đang active, cập nhật trạng thái về inactive
Thêm mới 1 địa chỉ mới
Nghe các bước có vẻ đơn giản đúng không? Không hề, điều gì sẽ xảy ra nếu người dùng không đặt các địa chỉ cũ thành trạng thái inactive - điều này có thể dẫn tới ảnh hưởng đến tính toàn vẹn của dữ liệu.
Vậy làm sao để sửa chữa được sai lầm này, rất đơn giản thôi, chúng ta có 1 API cập nhật địa chỉ của khách hàng. API này sẽ thực hiện việc đặt địa chỉ cũ về inactive, và thêm mới địa chỉ mới. Người dùng sẽ không cần quan tâm đến việc đó.
2.2.3. Tránh ảnh hưởng từ kiến trúc phần mềm
Trong hệ thống shopping, chúng tôi quyết định xử lý các mô tả sản phẩm và giá sản phẩm ở 2 application khác nhau (Có nhiều lý do tốt và xấu để thực hiện điều này, nhưng đó không phải vấn đề ở đây).
API được thiết kế theo quan điểm nhà cung cấp có thể hiện thị 2 API:
API lấy thông tin mô tả sản phẩm
API lấy thông tin giá sản phẩm
Nhưng điều này mang lại lợi ích gì cho người tiêu dùng? Nó chẳng mang lại lợi ích gì cả, người dùng sẽ phải call cả 2 API để lấy được đầy đủ thông tin về sản phẩm.
Rõ ràng việc thiết kế này bị ảnh hưởng bởi kiến trúc của hệ thống, và nó không hề thân thiện với người dùng.
Điều mà người dùng muốn, đó là với 1 API duy nhất, hệ thống trả ra toàn bộ thông tin của sản phẩm, bao gồm mô tả và cả giá của nó. Và đó chính là cách để sửa chữa sai lầm này.
2.2.4. Tránh ảnh hưởng bởi tổ chức nhân sự
Miễn là có nhiều hơn 1 người trong 1 tổ chức cung cấp API. Bạn sẽ phải đối mặt với khía cạnh tổ chức con người khi thiết kế API từ quan điểm của nhà cung cấp. Định luật Conway đã chỉ ra rằng hệ thống của tổ chức sẽ có cấu trúc là bản sao của cấu trúc giao tiếp trong tổ chức đó.
Định luật Conway: “Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization’s communication structure”
Trong tổ chức, mọi người sẽ được gom lại thành các nhóm, các phòng ban. Tất cả các nhóm khác nhau này sẽ tương tác với nhau theo những cách khác nhau, sử dụng các quy trình khác nhau. Việc này sẽ định hình thành các hệ thống khác nhau trong tổ chức, bao gồm cả API.
Giả sử công ty Shopping của chúng tôi được chia thành 3 bộ phận khác nhau:
Bộ phận đơn: xử lý đơn đặt hàng
Bộ phận kho: xử lý hàng trong kho và đóng gói
Bộ phận vận chuyển: xử lý việc vận chuyển các gói hàng cho khách.
Hình dưới đây cho thấy API Shopping được thiết kế từ quan điểm của nhà cung cấp. Các API được đưa ra cho người sử dụng, bộc lộ hoạt động bên trong của tổ chức theo cách hoàn toàn không cần thiết.
Nếu người dùng muốn đặt hàng, họ sẽ phải sử dụng các API:
Thêm hàng vào giỏ
Check out
Chuẩn bị đơn
Giao hàng
Không có lý do gì để người tiêu dùng cần sử dụng API Chuẩn bị đơn và Giao hàng cả.
Nếu thiết kế theo quan điểm của người tiêu dùng, Người dùng chỉ cần Thêm hàng vào giỏ và Check out là được. Quá trình đóng gói và giao hàng sẽ được xử lý nội bộ bên trong hệ thống.
Kết luận, khi thiết kế API, bạn phải luôn kiểm tra xem những gì người tiêu dùng cần thực hiện. Từ đó tránh được việc thiết kế API từ quan điểm của nhà cung cấp.
3. Tóm tắt lại
Ở bài viết này, mình đã chỉ ra:
Hậu quả của việc thiết kế API tồi sẽ dẫn đến API có thể khó để hiểu, khó để sử dụng hoặc hoàn toàn không được sử dụng. Gây khó khăn và khó chịu cho các bên tích hợp nó, từ đó cũng gián tiếp ảnh hưởng đến hiệu quả làm việc, kết quả kinh doanh của công ty.
Chỉ ra các lý do cho việc tại sao thiết kế API lại quan trọng, nó mang lại những lợi ích gì và các thành phần của việc thiết kế API.
Đưa ra góc nhìn đúng đắn cho việc thiết kế API là góc nhìn từ người tiêu dùng, tránh các sai lầm khi thiết kế API bị ảnh hưởng bởi góc nhìn của nhà cung cấp. Từ đó đưa ra các API thân thiện với người tiêu dùng, dễ hiểu, dễ sử dụng.
Ở phần tiếp theo, mình sẽ trình bày các bước, các nguyên tắc cụ thể của việc thiết kế API hiệu quả.
Reference: The Design of Web APIs - Arnaud Lauret.
Subscribe to my newsletter
Read articles from Sơn Phạm Quang directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Sơn Phạm Quang
Sơn Phạm Quang
Experienced Software Engineer Love, want to learn and share about Data Structures & Algorithm, Design Pattern, Optimize Performance... Strong passion for exploration and travel