NDP Blog

Author
Lisa Haskel
Jon Bamgboye

Creating robust integrations with Drupal 8: Part 1

INTRODUCTION

At NDP we often work with clients who need to integrate back office systems (such as bookings, ecommerce and CRM) with their website. In this post we’ll look at how we approach projects with this requirement, and how they can be architected in Drupal with robust engineering for a predictable and future-proof delivery.

A recent project saw a very substantial integration with a .NET back-office system. This CRM is core to the client’s operations and supports memberships, training, accreditations and work history as well as more standard CRM functions.
 
The integration of this system with a new website allows users to self-service memberships and other services online, reducing the amount of manual back office work involved.
 
As in most such integrations, the CRM is run and hosted totally separately from the Drupal website.  The backoffice system is accessible over a SOAP API which allows both viewing and updating records. For data protection reasons, a key requirement involved making sure that no personal information is stored in Drupal.

For these user management functions therefore, Drupal is a mechanism for displaying information and forms, and passing this information back to the back-office CRM, and does not take on any content mangement functions itself.

APPROACH

We identified the following 4 criteria which provided guiding principles for our code design:

  • Drupal 8 compatible
  • Readable
  • Reusable and Maintainable
  • Future-proof

DRUPAL 8 COMPATIBLE

Drupal 8 represents a shift of emphasis away from being a self-contained framework and towards taking advantage of a broader set of PHP libraries, bringing it close to industry standards in PHP development.  This shift brings new opportunities for the fundamental architecture of a Drupal 8 integration.
 
Specifically for us, the use of PHP libraries installed in a 'vendor' directory and controlled by PHP Composer offered a model and a framework for us to design and build the main body of our code as a custom library external to Drupal; able to act as a ‘middleware’ style layer between Drupal and the API but, crucially, without any dependencies on Drupal.

The result of our implementation of this architecture is a library which is fully responsible for communicating with the API and, via object oriented programming (OOP), exposes methods that can be called succinctly from custom code within Drupal.  This library was created without dependencies on any Drupal-specific implementations. In this way, we achieved a total separation of concerns between custom Drupal code - which is responsible for handling functionality and error conditions relevant to end-users - and the library code which communicates with the API and logs error conditions relevant to the backend CRM administrators.

This solution is compatible with the principles of Drupal 8 through its use of the libraries model, its dependency on Composer to manage those libraries, and the use of OOP to produce readable and reusable code.

READABLE CODE

Given that our custom library interfaces with the internal membership system it was straightforward to design our code to be readable and intuitive.  We adhere to the principle to remain as close as possible to the real-world concepts and language of the client organisation.  So, for example: a typical call to our code from within Drupal might look like this:

if ($membership = $contact->getMembership()) {
  $balance = $membership->getBalance();
  $type = $membership->getMembershipType();
}

No rocket-science here then - but this is the aim. Our library does what OOP is fundamentally designed to do: to hide complexity and expose only succinct, readable and re-usable methods.

RE-USABLE AND MAINTAINABLE

Meanwhile, under the hood, we followed OOP principles of loose coupling and took advantage of fundamental OOP tools such as inheritance to produce well designed objects. As we progressed through the tasks necessary to deliver the website project, we were able to add incrementally to the library without compromising existing code.

We were also able to safely amend or enhance the functionality within each method where and when necessary. This proved invaluable in this project given its long-running nature, and the complexity of the underlying system whose finer details did not always come to light until late on in the development process.

Creating the library resulted in code that is thoroughly re-usable within as many different areas of Drupal as needed.  This characteristic is fundamental to delivering a complex integration within an equally complex new website build.

However, reusability using the code architecture suggested here goes beyond this. By making sure that there are no dependencies on Drupal within the library, this code can potentially be used by other applications.

The OOP code architecture and reduced dependency on Drupal has resulted in other benefits for maintenance. Testing that is useful and effective is often a challenge. By separating code the handles the interactions with the CRM it is also possible to separate testing into discrete concerns.  Together with the library, we developed a suite of PHPUnit tests for the API calling methods that, once again, had no dependencies on Drupal.  Separately, functional tests for the website were developed.

Documentation can also be improved by adherence to OOP standards and OOP designs.  UML format Class Diagrams can be generated which provide an immediate and easily understandable documentation of the library code.

FUTURE-PROOF

CRM and other backoffice systems tend to have a very long life within organisations due to the volume of data they hold and the effort involved in customising them. The lifetime of backoffice systems often exceed the lifetime of websites, and may also be supplemented by additional user-facing applications such as mobile apps.
 
When a large proportion of custom code can be placed in a library and can be free of Drupal dependencies, it means that code can be re-used in unlimited different contexts in a long time period. This level of re-usability adds considerable value for the client.  The testing and documentation as described above enhances this ability to lengthen the shelf-life of code.

EVALUATION AND LESSONS LEARNED

The architecture of Drupal 8 enables a step change in the the quality overall quality of integration solutions.
 
While OOP can easily be used in equivalent Drupal 7 integrations, the structure of Drupal 8 and the use of Composer to manage external dependencies give us the opportunity to take the main parts of the API integration out of Drupal completely,  but easily include it via the library management structure and autoloading  provided by Composer.This separation adds value by increasing re-usability, reducing dependencies and enabling self-contained testing and documentation.
 
The strong structure of this solution has enabled us to respond to ongoing evolution of requirements, and therefore has contributed to our ability to build a collaborative, ongoing relationship with all stakeholders. Together with the re-usability and testability and clear documentation of our code, this offers added value for clients and a better code architecture to maintain and reuse going forward.
 
One lesson from this process has been the need to front-load our work schedule and budget. Implementing an integration in this style requires a greater amount of work at the beginning of a project and this requires planning, commitment and understanding on all sides of the work process.

Look out for the next part of this series; 
SSO with Drupal 8 and SimpleSAMLphp (coming soon)

Written by Jon Bamgboye, Lisa Haskel