0
0
Lập trình
Hưng Nguyễn Xuân 1
Hưng Nguyễn Xuân 1xuanhungptithcm

Thiết kế hệ thống vững mạnh trước sự thay đổi của API bên ngoài

Đăng vào 3 ngày trước

• 8 phút đọc

Giới thiệu

API bên ngoài là thành phần quan trọng trong các hệ thống backend hiện đại, cho phép các dịch vụ giao tiếp và chia sẻ dữ liệu với nhau. Tuy nhiên, các API này không phải là cố định; chúng có thể thay đổi, giới thiệu các tính năng mới, ngưng hỗ trợ những tính năng cũ hoặc thay đổi cấu trúc dữ liệu. Việc thiết kế hệ thống của bạn để dự đoán và xử lý những thay đổi này là điều cần thiết để duy trì sự ổn định và giảm thiểu công việc không mong muốn cho nhóm phát triển của bạn. Một thiết kế vững mạnh đảm bảo rằng ứng dụng của bạn vẫn hoạt động và dự đoán được ngay cả khi các phụ thuộc bên ngoài thay đổi.

Tách biệt các tương tác với API bên ngoài

Việc gọi trực tiếp một API bên ngoài từ nhiều phần khác nhau trong ứng dụng của bạn tạo ra sự liên kết chặt chẽ. Khi API thay đổi, bạn sẽ phải thực hiện một nhiệm vụ phức tạp để tìm kiếm và thay thế trong toàn bộ mã nguồn.

Chiến lược: Thực hiện một lớp tách biệt. Tạo một dịch vụ hoặc kho lưu trữ chuyên trách cho tất cả các giao tiếp với một API bên ngoài cụ thể. Dịch vụ này sẽ chuyển đổi các phản hồi của API bên ngoài thành các mô hình dữ liệu nội bộ của ứng dụng bạn, bảo vệ phần còn lại của hệ thống khỏi những chi tiết cụ thể của API bên ngoài.

Ví dụ (PHP/Laravel):

php Copy
// app/Services/ExternalUserService.php
class ExternalUserService
{
    private $httpClient;

    public function __construct(HttpClient $httpClient)
    {
        $this->httpClient = $httpClient; // Guzzle hoặc tương tự
    }

    public function getUserData(string $userId): array
    {
        try {
            $response = $this->httpClient->get("/users/{$userId}");
            $externalData = json_decode($response->getBody()->getContents(), true);

            // Chuyển đổi định dạng API bên ngoài sang định dạng nội bộ
            return [
                'id' => $externalData['id'],
                'name' => $externalData['displayName'],
                'email' => $externalData['contactEmail'],
                // Ánh xạ các trường khác liên quan
            ];
        } catch (Exception $e) {
            // Xử lý lỗi khi gọi API
            throw new ExternalApiException("Không thể lấy dữ liệu người dùng.", 0, $e);
        }
    }
}

// Trong ứng dụng của bạn, chỉ cần tương tác với ExternalUserService
$userData = app(ExternalUserService::class)->getUserData('some_external_id');

Nếu API người dùng bên ngoài thay đổi trường displayName thành fullName, bạn chỉ cần cập nhật ExternalUserService mà không cần chạm vào bất kỳ phần nào khác của ứng dụng sử dụng dữ liệu người dùng.

Triển khai xử lý lỗi vững mạnh và các phương pháp thay thế

API bên ngoài có thể gặp lỗi vì nhiều lý do: sự cố mạng, hạn chế tốc độ, hoặc lỗi máy chủ nội bộ từ phía họ. Hệ thống của bạn phải chuẩn bị cho những tình huống này.

Chiến lược:

  • Bắt lỗi cụ thể: Phân biệt giữa lỗi mạng, lỗi của người dùng (4xx) và lỗi máy chủ (5xx).
  • Cơ chế thử lại: Triển khai cơ chế thử lại theo cấp số nhân cho các lỗi tạm thời, nhưng tránh thử lại vô hạn.
  • Bộ ngắt mạch: Ngăn hệ thống của bạn gọi liên tục một API đang gặp vấn đề, cho phép nó phục hồi và ngăn chặn các lỗi lan truyền.
  • Giá trị mặc định hoặc dữ liệu đã lưu trữ: Nếu một cuộc gọi API không quan trọng và thất bại, hãy sử dụng dữ liệu mặc định hợp lý hoặc một phiên bản đã lưu vào bộ nhớ để duy trì chức năng một phần.

Phiên bản hóa API bên ngoài

Nhiều API bên ngoài cung cấp phiên bản, chẳng hạn như /v1/users hoặc /v2/users. Đây là cách chính mà các nhà cung cấp API quản lý sự thay đổi.

Chiến lược:

  • Chỉ định rõ ràng các phiên bản: Luôn nhắm đến một phiên bản API cụ thể trong các yêu cầu của bạn. Tránh để cho API tự động chuyển sang phiên bản mới nhất, điều này có thể thay đổi một cách bất ngờ.
  • Lập kế hoạch cho việc nâng cấp: Khi một phiên bản mới của API bên ngoài được phát hành, hãy đánh giá tác động. Nếu có những thay đổi đáng kể, hãy phát triển một client mới cho phiên bản đó trong lớp tách biệt của bạn, và từ từ di chuyển việc sử dụng ứng dụng của bạn.
  • Cách tiếp cận hai client: Trong quá trình di chuyển, lớp tách biệt của bạn có thể tạm thời hỗ trợ cả phiên bản API cũ và mới, cho phép triển khai dần dần.

Giám sát và cảnh báo

Việc phát hiện các vấn đề nhanh chóng là rất quan trọng để duy trì tính vững mạnh.

Chiến lược:

  • Ghi lại các yêu cầu và phản hồi API: Bao gồm chi tiết yêu cầu, mã trạng thái phản hồi và thời gian thực thi.
  • Thiết lập cảnh báo: Giám sát tỷ lệ thành công của các cuộc gọi API, độ trễ và các mã lỗi cụ thể. Kích hoạt cảnh báo cho các khoảng thời gian dài có lỗi hoặc suy giảm hiệu suất.
  • Trang trạng thái bên ngoài: Đăng ký các trang trạng thái do nhà cung cấp API bên ngoài cung cấp để nhận thông báo về các sự cố hoặc bảo trì đã lên kế hoạch của họ.

Kiểm tra tự động

Các bài kiểm tra đơn vị và tích hợp là rất quan trọng để xác nhận rằng các client API của bạn hoạt động như mong đợi.

Chiến lược:

  • Giả lập phản hồi từ API bên ngoài: Đối với các bài kiểm tra đơn vị, hãy giả lập dịch vụ API bên ngoài để đảm bảo rằng logic nội bộ của bạn xử lý các phản hồi khác nhau một cách chính xác.
  • Kiểm tra hợp đồng: Nếu có thể, sử dụng kiểm tra hợp đồng (ví dụ: Pact) để xác định và xác minh hợp đồng mong đợi giữa dịch vụ của bạn và API bên ngoài. Điều này có thể phát hiện các thay đổi phá vỡ sớm.
  • Kiểm tra tích hợp: Chạy các bài kiểm tra tích hợp cụ thể với một môi trường thử nghiệm hoặc staging của API bên ngoài, nếu có sẵn. Điều này xác minh kết nối và ánh xạ dữ liệu từ đầu đến cuối.

Giao tiếp và tài liệu

Giữ thông tin về các thay đổi sắp tới từ các nhà cung cấp API bên ngoài.

Chiến lược:

  • Đọc tài liệu API: Thường xuyên xem xét tài liệu để biết thông báo cập nhật hoặc thông báo ngừng hỗ trợ.
  • Đăng ký nhận bản tin / diễn đàn: Nhiều nhà cung cấp API sử dụng các kênh này để giao tiếp các thay đổi quan trọng.
  • Thiết lập liên lạc: Nếu bạn là người dùng có khối lượng lớn, hãy xem xét việc thiết lập một kênh giao tiếp trực tiếp với hỗ trợ hoặc nhóm kỹ thuật của nhà cung cấp API.

Mẹo và thủ thuật

  • Đừng thiết kế quá phức tạp cho mọi thay đổi có thể xảy ra ngay lập tức. Tập trung vào việc tách biệt các cuộc gọi và xử lý các chế độ lỗi phổ biến. Thêm các yếu tố phức tạp cho các rủi ro đã biết hoặc sau khi gặp sự cố.
  • Rõ ràng về hợp đồng dữ liệu. Khi thiết kế các mô hình dữ liệu nội bộ, hãy rõ ràng về các trường nào được mong đợi từ API bên ngoài và các trường nào là tùy chọn.
  • Xem xét một cổng API dành riêng cho các tình huống phức tạp. Nếu bạn tích hợp với nhiều API bên ngoài hoặc cần áp dụng các chính sách chung (giới hạn tốc độ, xác thực, biến đổi), một cổng API có thể tập trung hóa logic này.
  • Tránh lồng ghép sâu trong các cuộc gọi API. Cố gắng làm cho các cuộc gọi của bạn càng phẳng càng tốt. Các cuộc gọi nối tiếp phức tạp đến một API bên ngoài làm tăng diện tích bề mặt cho lỗi và làm cho việc xử lý lỗi trở nên khó khăn hơn.
  • Sử dụng các thao tác idempotent khi có thể. Đối với các thao tác ghi, hãy thiết kế các yêu cầu của bạn để trở thành idempotent. Điều này có nghĩa là thực hiện cùng một yêu cầu nhiều lần có hiệu ứng giống như thực hiện một lần, điều này đơn giản hóa logic thử lại.

Kết luận

Việc tích hợp vững mạnh với các API bên ngoài đang tiến hóa phụ thuộc vào thiết kế và giám sát chủ động. Tách biệt các tương tác bên ngoài phía sau một dịch vụ chuyên biệt, triển khai xử lý lỗi toàn diện với các cơ chế thử lại và bộ ngắt mạch, và quản lý phiên bản API một cách rõ ràng. Kết hợp những chiến lược kỹ thuật này với giám sát kỹ lưỡng, kiểm tra tự động và giao tiếp tích cực với các nhà cung cấp API để đảm bảo hệ thống của bạn luôn ổn định và thích nghi.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào