Why write framework agnostic packages?

A couple of years ago, I wrote an integration for a client’s Drupal Commerce website with an online eBook service as they wanted to sell eBook variations of their products.

They provided me with some example code for different PHP frameworks, each were separate and tightly-coupled to each framework, so there was no code shared between them. Because of this, and because there was no Drupal Commerce example, I wrote my own version.

However, I decided to make my version as reusable and loosely-coupled as possible. This meant that I’d be able to potentially reuse it for other clients and the same code could be used for different implementations.

Reusable code such as the configuration, different types of Requests, value objects for Customers, Orders and OrderItems, were all written within a separate, reusable PHP library. It contains it’s own tests, has it’s own CI pipeline, and it’s own static analysis - ensuring that things work as expected.

With this code separated, the Drupal module was much smaller and responsible only for bridging the library’s code with Drupal Commerce and adding any other Drupal-specific code.

The client is currently considering an upgrade from Drupal 7 to Drupal 9, which would also mean upgrading this module. But, with this approach, there’s a lot less to upgrade. The library code can still be used, and I can focus on any Drupal-specific changes within the Drupal module.

I recently had an enquiry from someone who needs an integration with the same service. Whilst their requirements may be different, I could still re-use the reusable library code, and write any client-specific code within a custom module.

Finally, if I wanted to reuse this code within a different PHP eCommerce framework then I could by installing the library with Composer. This means that I’d get the same code without needing to manually copy it, keeping a single source that can be maintained separately upstream. I’d get the same code that I’m already familiar with, so I could focus only on how to integrate the library with that framework - again meaning less framework-specific code and a much lower development effort.