1. Giới thiệu
Tục ngữ Việt Nam có câu “Sai một ly, đi một dặm” để nói về sự cần thiết của việc suy nghĩ thấu đáo trước khi hành động. Không nên vội vàng hành động để tránh hậu quả khó lường và những tổn thất khó bù đắp. Cẩn thận trong công việc là rất cần thiết, đặc biệt là khi làm việc với những thành phần có ảnh hưởng lớn đối với cả hệ thống, ví dụ như API.
API (Application Programming Interface) là một giao diện cho phép các ứng dụng khác nhau giao tiếp và trao đổi dữ liệu với nhau. API giúp các nhóm phát triển có thể tận dụng chức năng của một hệ thống mà không cần phải hiểu rõ chi tiết bên trong của hệ thống đó.

Khi chúng ta phát triển API, những lỗi thường được phát hiện sớm nhờ quy trình kiểm thử và ít khi ảnh hưởng đến người dùng. Tuy nhiên, lỗi API vẫn có thể xảy ra và trong một số trường hợp, chúng có thể ảnh hưởng đến hàng triệu người dùng. Một bài nghiên cứu được trình bày tại Hội thảo Quốc tế lần thứ 24 của IEEE đã thống kê rằng, cùng với sự phát triển của công nghệ, tần suất xảy ra lỗi API cũng tăng dần qua các năm.
Chất lượng của API và hệ thống có thể giảm xuống nếu lỗi xảy ra thường xuyên, và các nhà phát triển sẽ muốn tìm đến những hệ thống khác để thay thế. Do đó, tính ổn định của API là rất quan trọng, nhất là khi thực hiện những thay đổi hay cập nhật phiên bản mới, điều này cần các kỹ sư đặc biệt chú ý. Một API chất lượng tốt có nhiều tính chất tiêu biểu, nhưng nội dung lần này sẽ tập trung vào khả năng tương thích của API. Khả năng tương thích có hai chiều, đó là tương thích ngược (backward compatibility) và tương thích xuôi (forward compatibility), và chúng ảnh hưởng đến tính tin cậy (reliability) cũng như tính linh hoạt (flexibility) của thiết kế API.

Đối với một API có tính tương thích cao, các thay đổi có thể được thực hiện một cách liền mạch và hiệu quả mà không gây ra downtime hay lỗi giữa hệ thống và client. Rủi ro trong quá trình triển khai và sử dụng sẽ được giảm thiểu đáng kể, đặc biệt là đối với các hệ thống cần nhiều thời gian để cập nhật phiên bản mới đến người dùng, ví dụ như back-end API cho các ứng dụng di động.

2. Backward Compatibility - Tương thích ngược
Đặc điểm của tương thích ngược là những thay đổi về API không ảnh hưởng đến sự vận hành bình thường của các client sử dụng phiên bản trước đó của API. Trong ngành sản xuất game, lợi ích của tương thích ngược giúp tăng tốc quá trình xây dựng cơ sở người dùng. Ví dụ, nếu game thủ có thể chơi các game cũ mà họ yêu thích trên một console mới, họ sẽ sẵn lòng đầu tư để nâng cấp console. Trong thiết kế và phát triển API, tính tương thích ngược giúp hệ thống giữ vững được cơ sở người dùng và giảm số lượng outage có thể xảy ra, vì hệ thống có thể cập nhật liên tục mà không gây ảnh hưởng đến người dùng. Ngoài ra, quá trình giữ tương thích ngược cũng tạo ra khoảng thời gian đệm giúp cho client chuyển đổi dần sang API mới, và giúp việc gỡ bỏ phiên bản cũ của API diễn ra suôn sẻ hơn.

a. Thay đổi API có tương thích ngược
(Các ví dụ trong bài viết sẽ sử dụng REST API, nhưng nội dung sẽ được trình bày một cách khái quát nhất có thể để có thể áp dụng được với các loại API khác.)
Dưới đây là ví dụ của một payment API (đã được đơn giản hóa) khi thay đổi mà vẫn giữ được tính tương thích ngược.
trước | sau |
|
|
Chúng ta hay gặp các thay đổi như thêm một trường tùy chọn (optional field) cho request hoặc thêm một trường cho response, và đa phần các thay đổi này đều giữ được tính tương thích ngược. Những thay đổi sau đây thường đảm bảo tính tương thích ngược cho API (đây là những thay đổi an toàn):
- Thêm endpoint mới
- Thêm phương thức HTTP mới vào endpoint cũ
- Thêm header mới
- Thêm query parameter mới
- Thêm trường tùy chọn (không bắt buộc) cho request
- Thêm trường mới cho response
- Đổi một trường request từ bắt buộc thành không bắt buộc
- ...
Nhìn chung, những thay đổi trên sẽ không có ảnh hưởng nghiêm trọng đến client. Tuy nhiên, trong trường hợp client có kiểm tra dạng dữ liệu nghiêm ngặt (strict type checking), thì vẫn có thể xảy ra lỗi.
b. Thay đổi API không tương thích ngược
Cùng là thay đổi cho payment API, nhưng như ví dụ dưới đây thì sẽ xảy ra lỗi tương thích.
trước | sau |
|
|
Việc thay đổi định dạng dữ liệu của các trường request (chẳng hạn từ số tăng dần thành chuỗi UUID cho userId/orderId), cũng như thay đổi mã HTTP, dễ dẫn đến client không kịp chuẩn bị logic cần thiết để xử lý thay đổi, từ đó tạo ra lỗi. Ngoài ra, thêm giá trị cho trường response cũng thường gây ra lỗi, nhưng nếu tài liệu API được chuẩn bị trước và client có thay đổi tương ứng thì có thể tránh được lỗi này. Những trường hợp sau thường được định nghĩa là các thay đổi không tương thích (thay đổi không an toàn) cho API:
- Gỡ bỏ endpoint
- Gỡ bỏ phương thức HTTP có sẵn của endpoint
- Gỡ bỏ một hoặc nhiều trường của request và response
- Thêm một trường bắt buộc trong request
- Đổi một trường không bắt buộc thành bắt buộc trong request
- Đổi một trường bắt buộc thành không bắt buộc trong response
- Thay đổi định dạng dữ liệu của trường response
- Thêm một giá trị vào trường Enum trong response
- Thay đổi cấu trúc của request hoặc response
- Thay đổi URL của API
- Thay đổi header
- Thay đổi mã HTTP status
- ...
Các thay đổi liên quan đến việc xoá hoặc sửa thường dễ dẫn đến lỗi không tương thích ngược, nên các trường hợp này cần được đánh giá và chuẩn bị kỹ càng trước khi thực hiện.