Disclaimer: I wrap the middleware of my own company...
There are multiple claims here, so I will address them separately.
Wrapping also makes it easier to mock out third-party calls when you are testing your own code.
There are several benefits here, specifically when mocking just counting the number of calls helps. Some will argue that the number of calls is not functional and therefore should not be tested; however I have seen people introducing changes which multiplied the number of calls by a factor of 10x or 100x, and the performance implications are not trivial. This is especially true when...
... some 3rd party libraries come with a lot of dependencies (network connection, complicated configuration file) and only by mocking can you easily inject errors, among other specific situations you wish to test for.
Of course, at this point, wrapping is more down to get rid of an unwanted dependency (connection, configuration file) than anything else.
..In fact, wrapping third-party APIs is a best practice. When you wrap a third-party API, you minimize your dependencies upon it: You can choose to move to a different library in the future without much penalty.
This should go hand in hand with the DRY principle and with abstraction.
When calling a 3rd party library to parse a XML document, then navigate it to extract some pieces of data, the caller:
- is not interested in which 3rd party library you use
- is probably not interested in the structure of the XML document
as a result, you will wrap this into some code of your own, which has the double benefits of elevating the abstraction level (it's not a XML document, it's a request to buy 4 vanilla ice creams, with caramel on top).
If you repeatedly decode XML documents, quite rapidly you will naturally fuse parts of the decoding code which comes up over and over. This is just DRY.
As a result, I find than wrapping 3rd party components come naturally: whenever I use the same call twice or thrice, I tend to extract the code in a common function, which somehow becomes a wrapper.
(unasked question about boundaries and business model)
A 3rd party API is a foreigner, it does not speak your language.
There is a boundary between your own code and the 3rd party code: you use different objects. For example, you may model your server as a string (IPv4) and integer (port) but the underlying API expects just a string (IPv4:port), or vice versa. As a result, a transformation needs to be applied when talking to this foreign API.
Ideally, you want to maximize the amount of code dealing with your own data:
- you understand it
- you control it (invariants are checked and meaningful for your app.)
this requires pushing the boundaries of foreign code as far as possible.
Also, because each translation carries its own mismatch impedance risk, you want to reduce the number of places in the code where such translation occur.
In both cases, this argues for a thin layer between your application code and 3rd party APIs.