Skip to content

On Writing Wrapper Libraries

A wrapper library is a thin layer of abstraction around an existing library, dependency, or functionality. A wrapper library offers a better and cleaner interface or rather hides the dependency or library. Writing a wrapper library can be a hard decision since it requires more work and expands the project scope. On the other hand, it has long-term benefits like better validation, good default parameters, and the ability to replace existing wrapped artifacts. I’d like to discuss some of the aspects of writing a wrapper library in this post.

Writing Wrapper Libraries

When to Write

Nowadays most of the projects depend on open source projects a lot. One can’t just write wrapper libraries around all 3rd party libraries and dependencies. At the end of the day, writing and maintaining wrapper libraries has its costs and can be a technical debt in the future. Thus, we have to make a call when to write them. I believe the following scenarios justify writing wrapper libraries.

  • When you only use a small subset of the third-party library, you may want to hide the third-party library. You can then prevent exposing a huge API to your own codebase.
  • When you expect the third-party library to change a lot, you may want to expose your own interface. It’s easier to adapt to changes in one place rather than many codebases.
  • When you expect to change the underlying technology altogether, you may want to encapsulate details of the dependent technology.
  • When you need additional functionality or validation around the existing dependency, you may want to handle these improvements in the wrapper.
  • When you cope with a poor or complicated interface, you may want to get around it by having a layer of abstraction. You can then avoid binding this poor/complicated dependency to your project.
  • When you have an incompatibility between the library and your codebase, you may want to deal with the compatibility issues in the wrapper.

When Not to Write

The economy of writing wrapper libraries depends on one shop to another. If you are working in a big shop, it might be easy to decide since you have more people to benefit from the wrapper. However, if you are working in a small shop, writing a wrapper library can be an immense waste of time. So, writing wrapper libraries can be largely about the environment. Nevertheless, I believe one shouldn’t write wrapper libraries for the following scenarios.

  • When your dependent library is battle proof and exposing a consistent interface that rarely changes, you shouldn’t need a wrapper.
  • When you depend on a library as one of your core components, you should reflect on future changes rather than dealing with the wrapper.
  • When your project is small enough that writing a wrapper can’t be justified at all. In this case, you should avoid the wrapper. Perhaps, you can apply the façade pattern.

Additional Advantages of Wrapper Library

The need for a wrapper already demonstrates its advantages. A wrapper library can give further positive leverage to the project. I’d like to visit some of these extra advantages of wrapper libraries.

  • Defining interface of the wrapper can be independent of the wrapped dependency.
  • Testing can become much easier i.e. mocking your own wrapper vs. third-party library.
  • Requesting an additional functionality from wrapper author becomes an option.

A Practical Example

I’d like to briefly touch on a practical example where you want to provide a company-wide key/value store infrastructure. There are many technologies to choose like Memcached, Redis, MongoDB, or simply MySQL. We don’t want to tie the company to any of the technologies but we also need a solution. In this case, we can simply have an interface for a key/value store as simple as the following.

package com.yusufaytas.database;
/**
 * A simple interface for key/value database
 */
public interface KeyValueDatabase
{
    /**
     * Returns payload associated with the key
     *
     * @param key
     * @return payload
     */
    String get(String key);

    /**
     * Stores the payload with the associated key
     *
     * @param key
     * @param payload
     */
    void put(String key, String payload);
}

This example is nothing more than a simple interface. You can potentially apply the inversion of control pattern to attach different implementations of the key/value store. In the actual implementations, you can handle the connection to the different technologies. Moreover, you can apply various different configurations options that are relevant to your shop e.g. performance optimizations. The consumer of the wrapper library doesn’t need to know anything about the technology stack. The consumer can also easily mock the above interface for testing purposes. The interface can be further improved like adding multi put operations. All in all, the wrapper gives huge flexibility.

In consequence, I’ve tried to explain when it’s appropriate to write a wrapper library around a dependency or technology. I’ve then briefly discussed additional advantages of having a wrapper library as well as a simple practical example. Before rushing into writing one, I highly suggest holding a meeting to discuss the pros and cons.

Stay updated!

Receive insights on tech, leadership, and growth.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.