Guzzle for Drupal: SDK Building
For the last few months I’ve (intermittently) been thinking about how to build a nice PHP SDK for working with external APIs from PHP applications, and Drupal in general.
This post is a sort of round up of my thoughts, hopefully I’ll find time to complete this project so I can post a detailed followup.
Selecting Guzzle
I’ve come to the conclusion (as has Amazon) that Guzzle is the perfect HTTP Client framework to build such a thing in PHP. In the mean time, Drupal 8 has gotten fully onboard with the guzzled goodness. So it’s looking increasingly like a go-to library.
Decoupled architecture, careful obedience to the HTTP spec, lots of valuable (and optional) features, and a maintainer with a deep knowledge of cURL’s curlicues makes it a good system to lean on.
Basic Architecture
Guzzle has a very componentized architecture, and in recent months has separated out these components into separately downloadable packages, so you can use Composer to get just the pieces you need.
It also uses a Symphony-driven plugin architecture, which makes many different behaviors easily swappable. Check out the existing plugin library and realize that most of them are ridiculously easy to override with your own version of the plugin, either implementing the interface or extending what’s there.
Laying Out the Client
- Have a single “Client” class namespaced to the API you want to integrate.
- You can use the Service Definition DSL to quickly get something working, but I question the performance of doing so. I have some crazy ideas about coupling a discover service with a Guzzle Mimetype to created an automatic client testing harness.
- You should probably have an abstract “Command” (API Resource) in place to impose any custom behaviors.
- You should probably group “categories” of resources together using a lower level abstract class or interface to impose still more. For example, I want to add some fault tolerance by making certain “change” operations enqueue-for-retry on failure.
Add the Drupal
Using the Adapter interfaces, it took me about 20 minutes apiece to put together Drupal caching and logging plugins. These will be brought in place with the proper use statements in a Drupal-specific Client class I will create as an extension of the generic SDK client.
Similarly, I anticipate extending many of the Command classes with Drupal-specific variants to handle mapping (data conversion) from Drupal entities to the API payload structure.