WordPress is, first and foremost, a platform that empowers publishers to get their content out into the world.
Secondarily, WordPress is a platform upon which developers like me build new applications. As such, there are hundreds of things that developers want to add to the list of WordPress’ features that no publisher will ever know or care about.
It leads to considerable debates in the community – what to or not to add to the system – and the ever-present reminder that, if you spend your days knee-deep in PHP debugging WordPress hooks, you’re probably not the target customer of the product in the first place.
I accept that, and rather than pitch a feature that is a must-have within the ecosystem, I want to explain something that would be nice-to-have from a developer perspective.
Services and Repositories
WordPress’ data abstraction layer lies in a ubiquitous [cci]$wpdb[/cci] object that wraps all of the major MySQL functions we use. WordPress further abstracts MySQL away from developers with handy tools like [cci]get_posts[/cci] and [cci]WP_Query[/cci].
Unfortunately, these abstractions are missing something major – easy accessibility.
I’m a big fan of the repository pattern in code. In my implementations, I’ve built the pattern out of two primary objects:
- A data service
- A data repository
The data service is the code I use within my application. Fetching content from the database is really fetching it from the service.
Collections, individual objects, advanced (filtered) queries – all of this happens on the service level, which can in-turn cache its returns in the interest of speed. Since developers work against items returned from a service, they never have to interact with the data storage layer itself, leading to huge gains in potential abstraction.
The data repository is the component that does all of the heavy lifting with the data itself – translating functional calls from the service layer into actual queries against the real data store. By separating the raw query logic into the repository, you can easily swap out your repository object when you change your data store.
I’ve actually built systems before where you could swap MS SQL for SQLite for MySQL for flat TXT files just by replacing the repository object in the application – no other code needed to change.
Why WordPress?
Firstly, I want to rid WordPress of its tight dependency on MySQL. Coming from a .Net world, I’ve seen a lot of people try (and mostly fail) to run WordPress with other dialects of SQL. Since so much of WordPress contains direct SQL calls, it will be a mess to properly translate everything.
Abstracting the SQL calls to a repository, however, would make swapping data layers easier.
Using a repository pattern also makes unit testing (without a database) far simpler. Rather than installing a database and running actual SQL calls during WordPress’ unit test run, you would provide a “mock” repository that just implements the same code interface – exposes the same method signatures as the real repository. The mock layer allows you to run your code independent of a potentially problematic MySQL system.[ref]Anyone who’s ever unit tested against a real database has seen problems arise where tests will inexplicably pass one moment and fail the next, despite making zero changes to the code. This is most evident in systems attempting to run tests in parallel when the tests work with the same (dynamic) data layer.[/ref]
Patches Welcome
I’ve taken a few runs at building this kind of abstraction into WordPress already. Unfortunately it’s a huge endeavor and will likely take several releases to make it a reality. That said, creating a plan to slowly convert core data access from [cci]$wpdb[/cci] to a new data service is a must before anyone tries to shoulder this effort on their own.
I don’t just want to implement the “new shiny” in WordPress – so I’m not going to pitch this as a wholesale, we-need-a-patch-for-all-the-things-today proposal. Instead, I’d like to see plugin developers start taking this approach in their code.
Repositories could still use [cci]$wpdb[/cci] internally for data access, but we should stop using [cci]global $wpdb[/cci] in the business logic of our code. Any direct queries made against the database should similarly be abstracted away to use an actual API for data access that is independent of the actual storage implementation of the platform.
I suggest services and repositories (ideally queued up by proper factories) as one way around the hard MySQL dependency of WordPress. What other suggestions would you make?