Làm cách nào để ngăn các thay đổi đối với API nội bộ phá vỡ các dự án khác?


8

Chúng tôi có 20 - 30 mô-đun / giải pháp độc lập. Mỗi trong số này có khoảng 7 - 10 dự án với các lớp, thành phần khác nhau, v.v ... Tất cả đều được sử dụng nội bộ cho công ty chúng tôi.

Vấn đề của chúng tôi là khi chúng tôi thực hiện thay đổi trong một mô-đun, sau đó chúng tôi cần đảm bảo cập nhật tất cả các mô-đun khác đang truy cập mã này. Điều này rất khó để biết vì nó nằm trong các cơ sở mã khác nhau.

Làm cách nào chúng tôi có thể ghi lại tất cả các sử dụng bên ngoài của API? Hoặc ngăn chặn những thay đổi nhỏ phá vỡ các mô-đun khác?



6
Làm cách nào để ngăn các thay đổi API phá mã? Ừm ... đừng thay đổi API. Thực sự, câu trả lời nào có thể có khác hơn thế?

@ dan1111 điều gì sẽ xảy ra nếu chúng ta phải thay đổi API và chúng ta không biết những mô-đun nào khác chúng ta sẽ phá vỡ, làm thế nào điều này có thể ngăn chặn được. làm điều đó
Toán học

Có gì sai khi tìm kiếm cơ sở mã của bạn cho các cuộc gọi phương thức? Nếu bạn không có tài liệu về những gì sử dụng những gì, đây là một cách khá tốt để làm điều đó. Bạn có thể dễ dàng viết một tập lệnh nhỏ tìm kiếm tất cả mã của bạn cho tất cả các lệnh gọi và báo cáo API về điều này.

1
bạn có thể cho chúng tôi biết thêm chi tiết? ngôn ngữ lập trình gì? khả năng tương thích sourcecode ok hay bạn cần tương thích nhị phân? Có phải "không thay đổi chữ ký api hiện tại" mà chỉ thêm chữ ký phương thức mới giải quyết vấn đề của bạn? Ngôn ngữ của bạn có hỗ trợ "defaultparameter"
k3b

Câu trả lời:


13

Giải pháp đơn giản nhất, IMO, là có một số lượng thử nghiệm tự động kha khá cho mỗi sản phẩm. Khi bạn cập nhật thư viện, bạn chạy bộ kiểm tra cho từng sản phẩm. Nếu các thử nghiệm thất bại, thì bạn sẽ biết sản phẩm nào cần được cập nhật.


5

Tôi sẽ đề nghị không cố gắng ghi lại tài liệu này (ít nhất là thủ công) vì nếu bạn yêu cầu mọi người cập nhật nó, nó sẽ đòi hỏi mức độ chính xác cao để hoạt động đúng. Nhưng bạn sẽ không bao giờ có được mức độ chính xác đó bởi vì thêm loại tài liệu này sẽ ... không vui và sẽ không có ai làm điều đó.

Một vài lựa chọn tốt hơn:

  • Có một kịch bản tạo ra một danh sách có thể sử dụng của tất cả các lệnh gọi phương thức trong tất cả các mô-đun khác, dựa trên các tiêu chí tìm kiếm. Đơn giản, thô thiển, nhưng có lẽ hiệu quả.
  • Một số loại hệ thống phiên bản mà bạn không phá vỡ tính tương thích ngược ngoại trừ số phiên bản chính. Vì vậy, nếu bạn thay đổi phương thức foo từ phiên bản 2.1 sang 2.2, tất cả mã tham chiếu phiên bản 2.X vẫn sẽ hoạt động. Khi bạn cần phá vỡ tính tương thích này, hãy nâng cấp số phiên bản chính (vì vậy trong trường hợp này là 3.0) và thông báo điều này cho tất cả các chủ dự án chịu trách nhiệm cho các mô-đun khác. Tùy thuộc vào cách quá trình phát hành của bạn hoạt động, việc này có thể đơn giản - hoặc cực kỳ phức tạp - để thực hiện.
  • Có kiểm tra tự động hoặc quy trình xây dựng CI trong đó mỗi lần bạn đẩy mã, bản dựng sẽ chạy các kiểm tra. Điều này sẽ cho phép bạn xác định nơi xảy ra vấn đề. Tôi đoán là với những gì bạn đang mô tả là vấn đề bạn chưa có vấn đề này ..
  • Một số loại hệ thống tài liệu tự động cho tất cả các mô-đun / kho lưu trữ của bạn

Bạn cũng có thể xem xét việc tái cấu trúc từ từ các API không quá dễ vỡ, nhưng tôi hy vọng điều đó nằm ngoài phạm vi của những gì bạn có thể thực hiện một cách hợp lý nếu bạn là một cá nhân và có hơn 20 mô-đun quy mô lớn để làm việc.


1
+1 cho phiên bản, cộng với liên kết đến Phiên bản ngữ nghĩa
xpy

2

Trước hết, một API có sử dụng bên ngoài không nên thay đổi.

Như @BryanOakley đã đề cập, sử dụng các bài kiểm tra đơn vị tự động là rất quan trọng và tiết kiệm cuộc sống trong những tình huống như vậy. Ngoài ra, một số gợi ý có thể (hoặc có thể không, tùy theo tình huống) giúp bạn

  • Nhiều ngôn ngữ (như Java và C #) cung cấp Function/Method Overriding. Các ngôn ngữ như Python cung cấp cho bạn để chuyển (không giới hạn số lượng) đối số và đối số từ khóa cho một hàm:

    Java:

    public void disp(char c)
    {
         System.out.println(c);
    }
    
    public void disp(char c, int num)  
    { 
         System.out.println(c + " " + num);
    }
    
    disp("A")
    disp("A", 3)

    Con trăn

    def disp(c, *args):
        if args:
            num = args[0]
            print("%s %f" % (c, num))
        else:
            print("%s" % c)
    
    disp("A")
    disp("A", 3)
  • Nhiều ngôn ngữ cung cấp public, privateprotectedphương pháp. Bạn có thể xử lý lệnh gọi hàm trong một publichàm và thực hiện công việc trong các private/protectedhàm.

    Trong python, không có định nghĩa chung / riêng cho các phương thức và hàm, nhưng một dấu gạch dưới hàng đầu ( _) nói rằng một phương thức là riêng tư và không nên được sử dụng bên ngoài. Các lệnh gọi API bên ngoài được truyền theo một phương thức mở ra thế giới bên ngoài và tất cả các tác vụ được thực hiện theo cái gọi là các hàm cục bộ :

    def format_input(a, b, *args, **kwargs):
        # This function is open to anyone. so use *args and **kwargs to get
        # all possible available arguments. Do not change this function
        # definition and function parameters
        a = _evaluate_input(a)
        b  =_evaluate_input(b)
        # c is not used by all APIs and may not documented in all external
        # API docs. So chech if it was sent as a keyword argument. If yes
        # evalaute it too
        if "c" in kwargs:
            c  =_evaluate_input(kwargs.get("c"))
        _check_extra_arguments(args)
        _check_extra_keyward_arguments(kwargs)
    
    def _evaluate_input(value):
        # This is a private method thus should not be called from the
        # outside world. You can change this method and parameter structure 
        # to fit your needs and do not care for outside world since no
        # outer API should use this function directly.
        ...
    
    def _check_extra_arguments(value):
        # We will check if any extra argument is passed and handle them accordingly
        ...

Như tôi đã nói, một định nghĩa API (cũng) được sử dụng bởi các ứng dụng bên ngoài không nên thay đổi quá nhiều. Bạn có thể tìm cách để làm cho các chức năng bên ngoài của mình linh hoạt hơn để bạn có thể thay đổi cách API hoạt động mà không phá vỡ trạng thái hiện tại.


1

Vấn đề của chúng tôi là khi chúng tôi thực hiện thay đổi trong một mô-đun, sau đó chúng tôi cần đảm bảo cập nhật tất cả các mô-đun khác đang truy cập mã này. Điều này rất khó để biết vì nó nằm trong các cơ sở mã khác nhau.

Tôi muốn đề nghị rằng điều này là không thể biết.

Bạn chịu trách nhiệm cho các Thành phần và Giao diện của chúng.
Bạn không chịu trách nhiệm cho bất cứ điều gì và mọi thứ có thể sử dụng chúng.

Làm cách nào chúng tôi có thể ghi lại tất cả các sử dụng bên ngoài của API? Hoặc ngăn chặn những thay đổi nhỏ phá vỡ các mô-đun khác?

Câu trả lời ngắn? Các xét nghiệm.

Viết các bài kiểm tra thực hiện các Giao diện được xuất bản. Chạy lại chúng bất cứ khi nào bạn thực hiện một sự thay đổi. Chừng nào bài kiểm tra "Đạt", bạn đã không làm hỏng bất cứ điều gì. Khi một thử nghiệm bị hỏng (và nó sẽ) hoặc (a) tìm và khắc phục sự cố hoặc (b) nếu bạn có thể biện minh cho sự thay đổi là hợp pháp, sau đó viết lại thử nghiệm để điều chỉnh nó.


0

Tôi đã thấy và mã hóa API với số phiên bản trong đường dẫn hàm và / hoặc tên.

Theo cách này, bạn có thể có sẵn các phiên bản API khác nhau - API hoàn chỉnh và phiên bản khác nhau của các chức năng trong một API.

Điều này đặt công việc giữ tất cả các phiên bản API trong mã cho API - không cần thay đổi mã của các ứng dụng khác ngoài mã mà ứng dụng API mới được sản xuất.

Tôi nghĩ rằng điều này đặc biệt quan trọng khi viết API sẽ được sử dụng bởi các ứng dụng bên ngoài tổ chức của bạn.

Ví dụ, đây là một mẫu mã để gửi SMS bằng api bulksms:

http://developer.bulksms.com/eapi/code-samples/csharp/send_sms/

từ đó là dòng:

string url = ".../submission/send_sms/2/2.0";

trong đó 2 và 2.0 là số phiên bản của API.

Vì API này được sử dụng cho nhiều khách hàng của SMS hàng loạt, nên một thay đổi đối với API này có khả năng phá vỡ nhiều ứng dụng và khiến điện thoại hỗ trợ đổ chuông.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.