4 Balancing flexibility and complexity

 

This chapter covers

  • Flexibility and extensibility versus cost of maintenance and complexity of APIs
  • Providing maximum extensibility with the listener and hooks APIs
  • Tackling complexity and guarding against unpredictable usage

When designing our systems and APIs, we want to find a balance between a set of features that it supports and the maintenance cost that arises from those features’ complexity. In an ideal world, every API change, such as adding a new feature, would be backed by empirical studies. For example, we can analyze the traffic on our website and, according to a need, add a new feature. We can also conduct A/B (http://mng.bz/ragJ) testing to decide which feature should be retained and which is not needed. Based on the results of A/B testing, we can remove features that are not needed.

However, it is essential to note that removing functionality from a public API may be problematic or not feasible. If we need to keep backward compatibility, for example, removing a feature is a breaking change, and often we cannot do it. We can try to deprecate and migrate our clients to a new API without the removed elements, but this is a complex task. You will find more on compatibility in chapter 12.

4.1 A robust but not extensible API

4.1.1 Designing a new component

4.1.2 Starting with the most straightforward code

4.2 Allowing clients to provide their own metrics framework

4.3 Providing extensibility of your APIs via hooks

4.3.1 Guarding against unpredictable usage of the hooks API

4.3.2 Performance impact of the hook API

4.4 Providing extensibility of your APIs via listeners

4.4.1 Using listeners vs. hooks

4.4.2 Immutability of our design

4.5 Flexibility analysis of an API vs. the cost of maintenance

Summary