WordPress powers over 30% of all web sites, but not all websites using WordPress are the same. Since WordPress is open source software that anyone can download and install on their server, there are countless versions of WordPress running unique configurations.
This creates a unique challenge for the WordPress mobile apps: Instead of having a single server with a defined API that we control and manage, we need to support multiple APIs from different WordPress versions and we can never complete trust the data being given back to us.
A short history of WordPress APIs
Why don’t we support a single API in our apps? Wouldn’t that make our lives easier? We could have decided to support only WordPress.com, but that would exclude the broader WordPress community that host their sites on other hosts. Another solution was to only use the API for WordPress.org sites, but that would limit the functionality of the app for the WordPress.com users.
Until recently, WordPress only supported one main API: the XMLRPC API. Yes, you read that right: XML Remote Procedure Calls. Even on WordPress.com, this was the only option available back in the day.
A few years ago on WordPress.com, we implemented Calypso, a brand new user interface that needed a new API to back it. This was the origin of the WordPress.com REST API, which has OAuth authentication and provides JSON responses.
Automattic also develops Jetpack, a plugin that connects instances of self-hosted WordPress to our WordPress.com infrastructure. Jetpack allows self-hosted sites to benefit from WordPress.com features that require server-side infrastructure like push notifications, a media CDN (Content Delivery Network), stats, and centralized management of multiple sites. Using Jetpack as a bridge, we can access those sites using the WordPress.com REST API, but with some limitations.
Finally, with the release of WordPress 4.7, a new REST API was integrated in the core of WordPress. While this was good news, there is still a missing piece to make it a universal API: a central authentication scheme.
On WordPress.com we decided to support this new API. But because of our unique server configuration, we needed to change the base structure of the endpoints. We called this API the WordPress.com REST API v2.
How do we support so many APIs? Layers
While the REST API v2 is the future, there’s no way to migrate every service and sites to this new API in one go – we still need to live with the other APIs for a while. The app needs to support:
- XML RPC API
- WordPress.com REST API v1
- WordPress.com REST API v2
How did we solve this in the WordPress for iOS app? Layers! Lots of layers of service classes. Here’s a diagram for the iOS app:
At the bottom level, we have two API objects: WordPressComRestAPI and WordPressXMLRPCAPI. Each of those objects implements the authentication of requests, the creation of request data, the parsing of responses, and base error handling.
Above the API objects we have a
Remote layer. It provides a standard protocol interface for each API, but internally it adapts the requests to the correct format and parses the answers depending on the specification of each.
On top of the stack, we have the
Service objects that coordinate all the requests to Remote objects and handle the data serialization. Most of the Services are entirely unaware of what kind of remote they are using and rely on the standard interface.
If you’re curious about the code of a Remote and Service objects, you can check out the MediaService class and the MediaServiceRemote class.
What about Jetpack?
At the moment, Jetpack sites use the same API as WordPress.com sites, with some responses handled differently on the remote level for the WordPressCom Rest API.
Version 2 of the REST API is only used when we implement new features that need new endpoints. The differences here are mainly handled on the WordPressComRestAPI object combined with the remote objects.
In the future, we’ll move all our APIs calls to v2 of the REST API and unify all these APIs. This is a long-term plan that will require us to:
- Audit the current use of V1 endpoint and check if the same functionality/data is available on V2 endpoints.
- Implement the necessary V2 endpoints changes for any missing data.
- Port the existing code that uses V1 API to use the equivalent V2 API endpoint.
- Implement or help implement a secure authentication scheme for sites hosted outside of WP.com.
- Remove the existing XMLRPC code and port it to use the new V2 endpoints.
- Test, test, test.
As you can see, providing an app that can connect to 30% of sites on the web has some complex challenges. While we try to isolate our users as best we can, in practice this often has a significant and misunderstood effect on the UX. Some features, like the ability to edit media settings, can only be available on WordPress.com site because the XMLRPC API doesn’t provide an endpoint for this action. This means limiting the actions for our self-hosted sites but still making the feature available for our other users. Getting the balance right can be tricky, which is why our team invests a lot of time into our server APIs.
All of the code for the server communication on iOS is open source and available in the WordPressKit repository. Feel free to use it on your projects if you need to talk with WordPress servers!
Want to help take the WordPress apps to the next level? We’re hiring!