Maintaining Backward Compatibility: About the Iceberg's Waterline

Before we start talking about the design principles of an extensible API, we should discuss the hygiene minimum. A huge number of problems would not have happened if the API developers were a little more responsible in identifying their area of ​​responsibility.





1. Provide the minimum amount of functionality





At any given time, your API is like an iceberg: it has a visible (documented) part and an invisible undocumented part. In a good API, these two parts relate to each other roughly like the surface and underwater part of a real iceberg, 1 to 10. Why is this? For two obvious reasons.





  • Computers exist to make complex things easy, not vice versa. The code that developers will write on top of your API should describe the solution to a complex problem in simple and concise terms. If developers are forced to write more code in your API than you wrote yourself, something went wrong here. Perhaps such an API is simply not needed.





  • Removing functionality from the API is impossible without serious losses. If you have promised to provide some functionality, you now have to provide it "forever" (until the end of support for this major version of the API). Declaring functionality unsupported is a complex process, fraught with potential conflicts with the consumer.





Rule # 1 is the simplest: if you don't have to expose some functionality, then you don't need to expose it. It can be formulated as follows: every entity, every field, every method in the public API is a product solution. There must be good reasons why an entity is documented.





2. Avoid gray areas and understatement





, . , . , , , «» - , β€” API, , . «» . .





API , :





  • ;





  • β€” , , ..;





. , , .





3.





. , : - , , ?





1. SDK .





//  
let order = api.createOrder();
//   
let status = api.getStatus(order.id);

      
      



, - . , id 404



, , . , strong eventual.





? , . , β€” . , β€” .





: Β«, !Β» β€” , , . , , createOrder



, SDK - :





let order = api.createOrder();
let status;
while (true) {
    try {
        status = api.getStatus(order.id);
    } catch (e) {
        if (e.httpStatusCode != 404 || timeoutExceeded()) {
            break;
        }
    }
}
if (status) {
    …
}

      
      



, , , . API, createOrder



SDK , getStatus



.





β€” API. , , .





2. :





let resolve;
let promise = new Promise(
    function (innerResolve) {
        resolve = innerResolve;
    }
);
resolve();

      
      



, callback-, new Promise



, resolve



resolve()



. : new Promise



callback-.





, , . API β€” . , ; , , API. .





3. , API , :





//    
//     
//   
object.animateWidth('100px', '500px', '1s');
//     
object.observe('widthchange', observerFunction);

      
      



: observerFunction



? , SDK 10 β€” observerFunction 10 '140px', '180px' .. '500px'. API β€” , observerFunction



.





- β€” , , , , SDK 10 . , , observerFunction



'500px' - β€” - .





β€” callback β€” .





4. , , :





GET /v1/orders/{id}/events/history
β†’
{
    "event_history": [
        {
            "iso_datetime": "2020-12-29T00:35:00+03:00",
            "new_status": "created"
        },
        {
            "iso_datetime": "2020-12-29T00:35:10+03:00",
            "new_status": "payment_approved"
        },
        {
            "iso_datetime": "2020-12-29T00:35:20+03:00",
            "new_status": "preparing_started"
        },
        {
            "iso_datetime": "2020-12-29T00:35:30+03:00",
            "new_status": "ready"
        }
    ]
}

      
      



, - Β« Β», . .. "preparing_started", "ready", "payment_approved". , - β€” , . , , .





, (, - ) - , - β€” , . , - , . . - ; , .





-, ; -, "payment_approved" "preparing_started" ( β€” , , ) .





.





4.





, , β€” . - , .





, , - . - , «». , , . - , .. -, , , - , .





Β« -Β» β€” , , - , . . «» β€” API; β€” Β« Β», III.






This is a draft for a future chapter of the book on API development. The work is done on Github . The English version of the same chapter is published on medium . I would appreciate it if you can share it on reddit - I myself cannot according to the platform's policy.








All Articles