API Development with X Autoload API Development with X Autoload Jul. 27th, 2017 Allan Chappell
Banner image: Tech Tip Thursday

API Development with X Autoload

July 27th, 2017

As a native PHP Developer, I find coding in Drupal 7 sometimes limiting, because I want to use the advanced patterns I learned way back when working with Zend Framework, Code Igniter, and Symphony. Some may argue for performance reasons we should limit the number of just for developer’ modules we use, but I find myself spending less time—and having more fun—by adding one in particular: X Autoload.

Make Drupal 7 development intuitive and fun!

The Challenge

Our client, Meredith Agrimedia, had a problem. They needed to get the information from the USDA-NASS Quickstats API into a map format that worked for the farmers and agribusiness—men and women who peruse their site. The challenge was that we are talking about a ton of data… megabytes even… of statistics about corn crops, their progress, yield, and the like.

Who better than the resident good ol’ country boy in overalls to whip up a custom API wrapping module? Some people would use feeds to bring in data, some people would maybe use some kind of custom migration using Migrate, but this one… this one was different with it’s own very non-REST like structure, and custom query string system that allows you to query data in what can be best described as giant spreadsheets of survey data.

The Proposed Solution

In situations like this, it is very easy to jump on the “Let’s Roll Out Our Own” bandwagon—you get all the joy of building something from scratch and can make a masterpiece, or end up with a brand new flavor of code spaghetti. I took a hint from several query builders in the past, and decided to go that direction, since the API could somewhat handle different conditions and what not. You can take a look at the documentation to see for yourself. If you are curious what I mean by “query builder,” take a look at the select portion of the Drupal Database API. Code-wise, I’m following the same ideals. But building this in D7, with include files (like ctools and views), just feels wrong… doesn’t it? Enter X Autoload.

Building a Drupal 7 Module Using PSR-4

If you have had a taste of Drupal 8 coding, and you are like me, it’s hard to go back. So let’s map out what I needed:

  • overall Service connector object
  • Authentication object to pass to the connector (basically a substitute for a configuration entity you would build in Drupal 8)
  • Query object to house selection options any conditions and build a query
  • Condition object to house the operations to do on specific properties in the query
  • Requester object interface just for fun, because I considered extending it out and allowing for fixtures (but ran out of time)
  • implementation of the requester interface

So how does that look?

So, in case you don’t know what PSR-4 is, it’s a Proposed Standards Recommendation that basically says after specifying a root namespace that maps to a directory (in this case defined by X Autoload which uses Drupal Coding standards), automatically load a PHP file that matches the same file structure as the namespace.

Example: in my code I create the Auth class under the Drupal\sfg_crop_maps\NassApi namespace. According to the rules X Autoload defines, we will load the file /path/to/sfg_crops_maps/src/NassApi/Auth.php. This is very exciting to me because it provides some serious structure to my code and keeps me from having to define more files in my sfg_crops_maps.info and I don’t have to worry about class/function name collisions nearly as much. I now have my own sandbox to work in. All of this is available simply by adding X Autoload as a dependency, no configuration needed.

Guidelines On Architecture for Query Builders

The query builder pattern is pretty much the hinge to this whole project. Following is a bit of a structure that you would want to build to and some hints to implement in your module

Main Service Class

Here, always build this to perform the global functions. In this case… the constructor should be initialized with an Auth and Requester object.

 

Requester Class

The Requester will be used later on in the query when the query executes, so this class literally just holds instances for you to use in a singleton pattern. This allows you to do something like the following:

 

Query Class

Your Query class should take your Auth, Requester, and any endpoint identifying bits that define the object you want to query. In my case, I only have one endpoint so I skipped that last bit. The  Query class should have a factory method in it that will either create conditions or allow you to add conditions and possibly condition groups. The Quick Stats API doesn’t allow anything more advanced than an AND operation, so I skipped condition groups.

 

Condition Class

Every query has a condition. It should handle a parameter, the value, and determine how operators are built. In hindsight, I could have moved the functionality that does the query string translation into the requester, but who hasn’t wanted to improve their code!?

 

Requester Classes

Lastly, the Requester object needs to translate and build the query object into something that it can then use to request information from the API.

Ultimately, I went with drupal_http_request because I wasn’t using Guzzle for anything else and that would be yet another library for me to depend on and figure out how to load. Ideally, we could have used Guzzle by telling X Autoload to load libraries also, but I didn’t mess with that. If I was using Composer for this project, I would have definitely went that route.

What Does That Hard Work Do?

So, you’re wondering… “What does a query look like then? After all that hard work, what does that get me?”

Before I show you, keep a few things in mind:

  • Always cache API data, even if it is for seconds. There is rarely a case where you are going to need up-to-date data every time someone hits the page.
  • Document what’s going on. A newbie—or even you may not know what’s going on down the road. Do yourself a favor and document.
  • Know your API’s limitations. There is nothing like building all of this and then realizing that the API only allows one of each parameter and therefore isn’t like a real query. Find out as much as you can early on and then plan on how to follow the query pattern above.

I ended up with something like this in my module getting specific data for the map shown at the top of the article:

Final Thoughts

So what do corn, autoloaders, and Drupal all have in common? Nothing so witty that this developer in overalls would burn a wheel in his head faster than a squirrel could hide a nut, but it sure as heck was a lot more fun, organized, and applicable to the everyday world of coding than making some flat module. Seriously, this could be pushed out as a library if I changed out the DrupalHTTPRequester object.

So, what have we’ve learned from this? Use X Autoload. Make it easier on yourself by using more modern practices and design patterns. Finally… really… have fun when you code.

Comments