REST API Roadmap

If you’ve been following WordPress development this year, you may be wondering “what’s been happening with the REST API focus?” We’ve been a little under-the-radar for most of the year so far, so we thought publishing an update and roadmap might be a good idea.

For new contributors looking to get involved with the REST API focus or WordPress generally, there’s never been a better time, and we’d love to have your help on our projects. Read on to see what we’ve been doing, where we’re going, and how you can get involved.

Since 4.7

Since the REST API was merged into core in WordPress 4.7, development activity has unfortunately been light. The merge into core was a huge effort, and after shipping in 4.7 we saw a drop-off in contribution and overall momentum as many API contributors took a break to recover from the stress of the merge. These contributions have not returned to previous levels, and there’s a few factors behind this: the move to Trac, lack of a forward roadmap, and overall fatigue have hampered our ability to move forward quickly.

The core REST API focus goal is to utilise the REST API within the WordPress admin. Defining the scope of this project has involved auditing all admin-ajax calls, as well as the filters used inside these calls, and where they are used. In addition, we’ve been working on the low-level JavaScript utilities we need to offer conceptual compatibility: while we can deprecate and remove old PHP filters, we need to offer new JS-based filters to replace them.

The admin-ajax audit revealed that the majority of ajax requests can be grouped into four categories: Media, Themes, the Editor, and List Tables. The code for both Media and the Editor will gradually switch to the REST API moving forward with development around Gutenberg, and likewise endpoints for better managing Themes are expected to be incorporated into Customizer work.

Rather than simply refactor the existing code for the other actions in a piecemeal fashion, we’ve been working on prototyping bigger groups of related changes and features, starting with the New List Tables and Live Settings.

A significant portion of existing admin-ajax code is for handling list table actions. The existing JS code for these actions is particularly difficult to work with, and the existing list table actions user experience is frustratingly inconsistent (for example, deleting a comment happens inline, whereas deleting a post causes a page refresh). A reworking of the code has the potential to improve UX significantly. New List Tables allows us to explore ideas around how we can improve the content organisation and management experience in the admin. This is a prototyping plugin where we’ve been exploring backwards compatibility techniques, and thinking about how a theoretical new management interface would look.

The Live Settings prototype uses the REST API settings endpoints to add live saving to the Settings screens. This dovetails with the work underway by the Accessibility team to switch to the Settings API, and the two projects will be able to work together in the future.

In addition to these API team projects, work has continued on REST API-related pieces on other teams, notably the Customizer and Multisite teams, who are working on API endpoints in their respective components.

Renewing our focus

Moving forward with the REST API, there’s a few key items we’re going to be focussing on. These items will have their own dedicated subteams and development cycles, and will work in parallel. The two broad goals are to use the API in the admin, and to solve authentication for external applications.

API in the Admin

Getting the API used in the WordPress admin is our primary focus. While it is technically possible to directly switch from admin-ajax calls to REST API calls, this is essentially refactoring with no real user benefit. Instead, we want to focus on changes that can improve the user experience.

For the feature prototypes (New List Tables, and Live Settings), we’re engaging members of the Design team to lead these features from a UX perspective. So far, these prototypes have been primarily about proving out the features and ensuring it’s actually technically possible to migrate these features to use the REST API; with the initial success on the technical side, we need to switch focus to delivering compelling user experiences.

New List Tables will be working with the goal of prototyping improved content management, using the REST API. This includes unifying and standardising existing interactions, and improving the perceived performance. This is a React-based prototype, and uses the existing REST API endpoints.

Live Settings will be working with the goal of making settings changes seamless. We’ve seen huge strides forward with the Customizer for updating your site, and the backend settings deserve a better experience to match. Live Settings touches on similar areas as the Settings API Enhanced project spearheaded by the Accessibility team; we plan to continue working independently to avoid blocking each other, while keeping in touch about the respective projects.

Work on converting existing admin-ajax code to use the REST API will continue, however this won’t be a priority, as it generally doesn’t provide a strong benefit to end users. Most admin-ajax actions will naturally be deprecated as part of progress by other focuses, including Gutenberg and plans around the Media Library. We’ll continue working with other teams and focuses on their efforts here.

Authentication

External authentication is an unsolved problem, and one that’s crucial to API use outside of WordPress core itself, including the official WordPress apps.

There are two key problems to solve here: how do apps act on behalf of a user (authentication), and how do sites recognise valid apps (initial connection). We have existing solutions to both these problems (OAuth 1.0a and the Broker system respectively), however these are not the easiest solutions, and aren’t adequate for all use cases.

To date the most complete authentication solution maintained by the REST API team has been a plugin providing OAuth 1.0a authentication. Moving forward, we are switching authentication focus to OAuth 2. As Matt announced last year, we are going to begin shipping HTTPS-only features in WordPress: this allows us to switch to OAuth 2. Work started during the WordCamp Europe contributor day on a new official OAuth 2 provider plugin which is now under ongoing development.

Simplifying the initial connection is a much harder piece, and this is a long-term project. Eventually, this should be as simple as a “Connect to WordPress” button, requiring minimal effort for app developers and no effort for users. This is a complex problem to solve, and no similar software has to work on the same scale we have. In the meantime however, we’re going to investigate pre-configuring Core to recognize and permit authentication from certain default apps, including the official WordPress mobile applications. Whitelisting applications in core is a practical expedient but this solution is not sustainable in the long-term, and should be replaced with a better system as soon as feasible. Work on solving this issue will be in the mid-term, however, as we need to ensure we have solid basics first.

Help Us!

The toughest challenge facing the REST API team right now is resourcing. There are only a few people working on the API regularly, and we need help to build out our projects—which is hopefully where you come in. We need people of all skillsets to help on New List Tables, Live Settings, and OAuth 2. This includes regular contributors, JS developers, and designers. And all of this will need documentation, too: following a productive contributor day at WordCamp Europe we are making progress expanding and reorganizing the REST API developer handbook, and would gladly welcome any interested docs contributors.

Our plan is to release the first public beta of each of these projects within the next month, with regular releases from each project following that. New List Tables and Live Settings could be part of either a 4.9 or 5.0 release, while OAuth 2 will remain as a plugin until fully proven out, and would likely target a core release next year. This also requires coordination with the Mobile team, and finalising the approach to usage inside the apps.

If you’re interested in getting involved, we’d love to get your help. The API holds weekly meetings every Wednesday at 13:00 UTC (next meeting at Wednesday at 13:00 UTC), and we’re always happy to spend time helping people get started contributing.

#rest-api, #roadmap

API Chat Summary: January 9th (4.8 kickoff)

We’ve had an early kickoff meeting for the REST API for 4.8 (Slack archive) to establish some of the new workflows and structure for the team heading into 4.8.

Development Process for 4.8

  • There are three big areas for the API moving forward: usage in core, usage in apps, and general expansion
  • Focus for 4.8 core development will be on usage in core
  • Other areas will continue development in Feature Projects where they need to, but won’t be the focus of the core API team
  • Feature Projects for the API:
    • Two additional requirements:
      1. Project must have a reviewer, who needs to be a core committer
      2. Project must have a design doc with a few specifics
    • Exactly what is required in the design doc will be laid out in the future, will include detailed merging plan
    • These changes based on our own experiences being a feature project
  • Project Organisation (including feature projects and core projects)
    • Overview and tracking of features will use Trello (mainly for our own internal usage)
    • Projects will have their own teams with a point-person to organise
    • Projects can have their own meetings, and will report their progress in the main API meeting
    • Our first core project is the Multisite API, @jnylen0 has been volunteered for point-person 😉

4.8 Focus: Admin

  • Attacking the problem from multiple fronts: lots of JS work, backend/new endpoints also required
  • New endpoints
    • “Appearance” menu is largest area lacking API support
    • Will work with the Customiser team closely here, including work on Widgets and Menus
  • Frontend work
    • Press This is great candidate, and work is already underway in #38343
    • Large amount of work around List Tables required
    • Work here can start with Quick Edit and Quick Delete
    • These will act as smaller areas to help establish process, including dealing with backwards compatibility

Documentation and Support

As noted, we’re trying out some new things with API development for this cycle. Those may stick, or they may not, and we’ll be continuing to improve and refine the process as we go.

REST API Merge Proposal, Part 2: Content API

Hi everyone, it’s your friendly REST API team here with our second merge proposal for WordPress core. (WordPress 4.4 included the REST API Infrastructure, if you’d like to check out our previous merge proposal.) Even if you’re familiar with the REST API right now, we’ve made some changes to how the project is organised, so it’s worth reading everything here.

(If you haven’t done so already, now would be a great time to install the REST API and OAuth plugins from WordPress.org.)

A brief history of the REST API

The REST API was created as a proof-of-concept by Ryan McCue (hey, that’s me!) at the WordPress Contributor Summit in 2012, but the project kicked off during the 2013 Google Summer of Code. The end result was Version 1.0, which grew into a community supported initiative that saw adoption and provided for a solid learning platform. The team used Version 1 to test out the fundamental ideas behind the API, and then iterated with Version 2, which made some major breaking changes, including explicit versioning, the introduction of namespacing for forwards compatibility, and a restructure of the internals. Version 2 also led to the infrastructure of the REST API being committed to WordPress core in 4.4.

This infrastructure is the core of the REST API, and provides the external interface to send and receive RESTful HTTP requests. Since shipping in 4.4, the infrastructure is now used by WordPress Core for oEmbed responses, and by plugins like WooCommerce and Jetpack, enabling anyone to create their own REST API endpoints.

The team has also been hard at work on the API endpoints. This has included core changes to WordPress to support the API, including deeper changes to both settings and meta.

Today the REST API team is proposing the inclusion of a collection of endpoints that we term the “Content API” into WordPress Core.

Proposals for Merge

Content Endpoints

For WordPress 4.7 the API team proposes to merge API endpoints for WordPress content types. These endpoints provide machine-readable external access to your WordPress site with a clear, standards-driven interface, allowing new and innovative apps for interacting with your site. These endpoints support all of the following:

  • Content:
    • Posts: Read and write access to all post data, for all types of post-based data, including pages and media.
    • Comments: Read and write access to all comment data. This includes pingbacks and trackbacks.
    • Terms: Read and write access to all term data.
    • Users: Read and write access to all user data. This includes public access to some data for post authors.
    • Meta: Read and write access to metadata for posts, comments, terms, and users, on an opt-in basis from plugins.
  • Management:
    • Settings: Read and write access to settings, on an opt-in basis from plugins and core. This enables API management of key site content values that are technically stored in options, such as site title and byline.

This merge proposal represents a complete and functional Content API, providing the necessary endpoints for mobile apps and frontends, and lays the groundwork for future releases focused on providing a Management API interface for full site administration.

Content API endpoints support both public and authenticated access. Authenticated access allows both read and write access to anything your user has access to, including post meta and settings. Public access is available for any already-public data, such as posts, terms, and limited user data for published post authors. To avoid potential privacy issues we’ve taken pains to ensure that everything we’re exposing is already public, and the API uses WordPress’ capability system extensively to ensure that all data is properly secured.

Just like the rest of WordPress, the Content API is fully extensible, supporting custom post meta, as well as allowing more complex data to be added via register_rest_field. The API is built around standard parts of WordPress, including the capability system and filters, so extending the API in plugins should feel as familiar to developers as extending any other part of WordPress.

This Content API is targeted at a few primary use cases, including enhancing themes with interactivity, creating powerful plugin interfaces, building mobile and desktop applications, and providing alternative authoring experiences. We’ve been working on first-party examples of these, including a mobile app using React Native and a liveblogging web app, as well as getting feedback from others, including WIRED, the New York Times, and The Times of London. Based on experience building on the API, we’ve polished the endpoints and expanded to support settings endpoints, which are included as the first part of the Management API.

Authentication

The API Infrastructure already in WordPress core includes support for regular cookie-based authentication. This is useful for plugins and themes that want to use the API, but requires access to cookies and nonces, and is hence only useful for internal usage.

To complement the Content Endpoints, for WordPress 4.7 the API team also proposes merging the REST API OAuth 1 server plugin into WordPress Core. This plugin provides remote authentication via the OAuth 1 protocol, allowing remote servers and applications to interact securely with the WordPress API.

OAuth is a standardised system for delegated authorisation. With OAuth, rather than providing your password to a third-party app, you can authorise it to operate on your behalf. Apps are also required to be registered with the site beforehand, which gives site administrators control over third-party access. Access to these apps can be revoked by the user if they are no longer using the app, or by a site administrator. This also allows apps with known vulnerabilities to have compromised credentials revoked to protect users.

We’ve chosen OAuth 1 over the newer OAuth 2 protocol because OAuth 1 includes a complex system for request signing to ensure credentials remain secure even over unsecured HTTP, while OAuth 2 requires HTTPS with a modern version of TLS. While it is strongly encouraged for sites to use HTTPS whenever possible (Let’s Encrypt makes it easier than ever to do so), WordPress itself does not require HTTPS and we do not believe WordPress should make HTTPS a requirement for using the API. The additional complexity that OAuth 1 adds can be easily supported by a library, and many such libraries already exist in most programming languages. OAuth 1 remains supported around the web, including for the Twitter API, and we also provide extensive documentation on using it.

Authentication Beyond 4.7

One issue with OAuth over direct username and password authentication is that it requires applications to be registered on the site. For centralized OAuth servers this wouldn’t be a problem, but the distributed nature of WordPress installations makes this tough to handle: your application must be independently registered with every WordPress site it connects to. If you’ve ever had to create a Twitter or Facebook app just to use an existing plugin on your site, you’ll know this can be a less-than-optimal experience for users.

To solve this distribution problem, we’ve created a solution called brokered authentication. This allows a centralised server (called the “broker”) to handle app registration and to vouch for these apps to individual sites. It simplifies app registration by allowing app developers to register once for all sites, and improves security by allowing the broker to vet applications and revoke them across the entire network. The system is designed to allow multiple brokers; while the main broker is run at apps.wp-api.org, organisations can run their own broker for internal usage, and developers can run a broker locally for testing.

While the broker system has been running live at apps.wp-api.org for months, we want to stay conservative in our approach to the API, especially where security is concerned. We are therefore proposing brokered authentication for WordPress 4.8 to ensure we have further time to continue testing and refining the broker system. In addition, this will require an installation of the broker on a centralised server to act as the canonical broker for out-of-the-box WordPress. While apps.wp-api.org is currently acting in this role, this is currently hosted by a third-party (Human Made) on behalf of the API team. For long-term usage the broker should instead be hosted on WordPress.org, alongside the existing plugin and theme repositories. This migration will take time but we remain committed to continuing to develop and support the broker.

After Merge

After merging the REST API, the team plans to continue developing the API as before. We expect that integrating the REST API into WordPress core will bring additional feedback, and we plan on incorporating this feedback through the rest of the 4.7 cycle.

During the remaining parts of this release cycle and through into the 4.8 cycle, additional work will go into other parts of the API. This includes further work and refinement on the broker authentication system, including work on WordPress.org infrastructure. Additionally, we plan to continue working on the Management API endpoints, including theme and appearance endpoints to support the Customiser team. Both of these components will be maintained as separate feature projects on GitHub until they’re ready for merge into core.

The team remains committed to supporting the API in core, and the Content API will switch from GitHub to Trac for project management and contributions. This same process occurred for the API Infrastructure in WordPress 4.4.

Reviews and Feedback

With this merge proposal, we’re looking for feedback and review of the project. In particular, we’re focussing on feedback on the security of the API and OAuth projects, and are also reaching out to specific people for reviews. (We take the security of the API seriously, and bug reports are welcomed on HackerOne at any time.) Design and accessibility reviews for the OAuth authorisation UI are also welcomed to ensure we maintain the high standards of WordPress core.

Both the REST API plugin and the OAuth plugin are available on WordPress.org, and issues can be reported to the GitHub tracker for the API and the OAuth plugin respectively. We have released a final beta (Beta 15 “International Drainage Commission”) which includes the meta and settings endpoints.

With Love from Us

As always, this is a merge proposal, and is not final until 4.7 is released. We’re eager to hear your thoughts and feedback; the comments below are a perfect place for that, or you can pop along to one of our regular meetings. We’re also always available in the #core-restapi room on Slack.

We’d like to thank every single one of our contributors, including 88 contributors to the main repository and 23 contributors to the OAuth repository. Particular thanks goes to my (@rmccue) wonderful co-lead Rachel Baker (@rachelbaker), our 2.0 release leads Daniel Bachhuber (@danielbachuber) and Joe Hoyle (@joehoyle), and our key contributors for the 4.7 cycle: Adam Silverstein (@adamsilverstein), Brian Krogsgard (@krogsgard), David Remer (@websupporter), Edwin Cromley (@chopinbach), and K. Adam White (@kadamwhite). Thanks also to the core committers helping us out through the 4.7 cycle, including Aaron D. Campbell (@aaroncampbell) and Aaron Jorbin (@aaronjorbin), and to the fantastic release lead, Helen Hou-Sandí (@helen).

Thanks also to everyone who has used the REST API, and to you for reading this. We built the REST API for you, and we hope you like it.

With love, The REST API Team

#feature-plugins, #json-api, #merge-proposals, #rest-api

HTTP API in 4.6

For WordPress 4.6, the HTTP API (wp_remote_request() and family) have undergone a large internal change. Rather than using a WordPress-specific HTTP library, WordPress now uses the open-source independent Requests library, developed by yours truly.

Why Requests?

The WP_HTTP library in previous releases has been primarily maintained by myself and @dd32, with my support time split between the two libraries. Both libraries are very similar, and code has been shared between them (when licensing permitted) in the past. Requests follows the same development philosophies as WordPress: developing for the masses with broad PHP support, and maintaining backwards compatibility.

By switching to Requests, a library without any WordPress-specific dependencies, WordPress benefits from input from the wider PHP ecosystem and community

Requests also has a huge number of unit tests, with test coverage at 92% of the codebase and increasing. It’s also used by other projects via the Composer ecosystem, including wp-cli’s HTTP functionality.

What has changed?

From your perspective as a developer, nothing should have changed visibly. You can and should continue to use WP’s HTTP functions the way you always have.

(Note: For the 4.6 development cycle and beta 1, the HTTP functions returned an array-like object. Many plugins and themes in the real world are using direct is_array() checks, so it was decided to pull this functionality back a bit to be safe, see #37097.)

Some new functionality has been introduced. In particular, the array returned from wp_remote_request() now includes a new http_response value, which contains a WP_HTTP_Response object (technically, WP_HTTP_Requests_Response). This shares functionality with WP_REST_Response objects introduced in WordPress 4.4, allowing common functionality to be developed for both APIs. In future releases, WordPress may introduce new WP_HTTP_Request objects as well, allowing common middleware to be used across both APIs.

In addition, all of Requests’ features are now available in WordPress. This includes things like better HTTP standard support, case-insensitive headers, parallel HTTP requests, support for Internationalized Domain Names (like böcean901.ch), and many other internal improvements.

Some new features are only available when using Requests::request() directly (such as parallel requests), however, these will be introduced into new WordPress-specific APIs in future releases (#37459). This release is focussing on switching internal implementation and remaining stable.

For more background on the change, see #33055.

#4-6, #dev-notes, #http-api

Rewrites Next Generation: Next Meeting

There was a bit of confusion with the last Rewrites meeting, so we never really got to kick off the conversation. Let’s give it another shot this week. The revised kick-off meeting for the Rewrites Next Generation project will hence be on May 18th 23:00 UTC.

The agenda for this meeting is to discuss problems you see with the rewrites system, any particular use-cases you think should be considered, as well as agreeing on a broad approach for how we want to tackle the problems.

(In case you missed it, you may want to read the introductory post for the project.)

Hope to see you all there!

#rewrite-rules

Proposal: Next Generation Rewrites

Hi everyone! Today I’d like to propose a new feature project for WordPress: Next Generation Rewrites. After proposing this at the last feature projects meeting, it’s time to flesh out the details of what this project would be.

The aim of the project is to modernise the rewriting and routing system for the modern CMS and platform era of WordPress.

(This project was previously proposed in a ticket on Trac, however the project is larger than a single Trac ticket and needs a larger discussion.)

Overview

If you’ve worked with custom development on WordPress, you’ve probably registered at least one rewrite rule. Rewrites are the key to what WordPress calls “pretty permalinks”, which are URLs designed for humans rather than the server. They look like /2016/04/19/, or /about/requirements/, rather than index.php?p=42.

As a developer, you can register your own rewrite rules as well. For example, bbPress registers URLs like /forums/topic/jjj-is-awesome/ and WooCommerce has URLs like /product/gs3/. WordPress then “re-writes” these to the internal query variables (“query vars”), which are eventually passed into the main WP Query.

The rewrite system was initially designed to implement pretty permalinks, but has been used and abused for so much more since then. With modern plugins and web apps built on top of WordPress, it’s not uncommon to have pages that don’t need a main query, or need a specialised system of querying. As an example of this, the REST API infrastructure added in WordPress 4.4 doesn’t use the main query, as many of the endpoints don’t require querying posts at all.

While the usage of rewrites has developed, the internals of how URLs are handled internally hasn’t changed. The system is fundamentally still designed for the blog era of WordPress. It also predates a lot of the pieces of WordPress we take for granted, such as transients and object caching.

Project Proposal

It’s time to change the rewrite system. Rewrite rules should be changed from a layer on top of WP Query to a fully-fledged system all of their own. To do this, I’m proposing three initial steps:

  • Decouple rewrites from the query system
  • Refactor and rework the internals to make them testable
  • Rethink rewrite storage and remove flushing

These steps would take place under the umbrella of a new feature project, Next Generation Rewrites. This feature project would coordinate the project and people working on it across the various parts of core it touches (primarily the Rewrite Rules component, but also potentially involving UI and UX discussion and changes; fixing the “visit the Permalinks page and save to fix your site” issue, for example). This would also coordinate the team across multiple release cycles as we slowly but surely make progress. It’s important to make progress while keeping rewrites stable, as they’re a critical part of WordPress that we cannot break.

Decoupling Rewrites from Querying

The first step I’m proposing is to decouple rewrites from querying. Right now, rewrites for anything except querying posts involves jumping through a few hoops. This includes registering temporary query vars, or using global state to track route matching. Separating these two components will make it easier to add non-query-based rewrites, as well as allowing more powerful query rewrites.

Currently, rewrites are registered using code like the following:

add_rewrite_rule( '/regex/', 'index.php?var=value' );

These rewrite rules map a regular expression to a query string, which is later parsed into an array internally. You can achieve more complex routing via regular expressions by using a special syntax in the rewrite string:

add_rewrite_rule( '/topic/(.+)', 'index.php?topic=$matches[1]' );

Note that while this looks like a PHP variable, it’s actually a static string that gets replaced after the regular expression. This can lead to confusion with developers who are new to the syntax, and it also can make doing more complex rewrites hard. These typically involve temporary query vars, as well as quite a bit of processing.

Instead, I want to introduce a new WP_Rewrite_Rule object to replace the current rewrite string. This object would contain a method called get_query_vars that receives the $matches variable and returns the query vars to set. This would look something like this:

class MyRule extends WP_Rewrite_Rule {
    public function get_query_vars( $matches ) {
        return array(
            'post_type' => 'topic',
            'meta_query' => array(
                array(
                    'key' => '_topic_name',
                    'value' => $matches[1],
                ),
            ),
        );
    }
}
add_rewrite_rule( '/topic/(.+)', new MyRule() );

(The exact format of the object is yet to be decided; we’ve also started discussing the possibility of passing a request object into this callback as well.)

Using an object for this allows us to have multiple callbacks for different stages of the routing process, and starts to simplify some of the internal code in WP_Rewrite. For example, the routing code around pages that allows URLs like /parent/child/sub-child/ for child pages can be simplified and moved out of the main routing code. This also helps make the code more testable, which dovetails nicely with the third goal.

Refactor rewrite internals

Step 2 of changing rewrites is to make the rewrite system fully testable. Currently, a bunch of global state is mixed into the internals of rewrite matching, and the rewrite methods tend to be monolithic. @ericlewis has previously begun work on this in #18877, and this can be continued and rolled into the Next Generation Rewrites project.

Ideally, this should happen at the same time or before the first step to allow easy checking of regressions. This is relatively boring work that won’t affect many developers, but it’s important we do it. The rewrite system is a critical part of WordPress, and it’s crucially important that it’s testable and verifiable.

Rethink rewrite storage

Once the first two steps are in place, we should begin reconsidering how rewrites are stored. Currently, rewrites are stored in the database in the rewrite_rules option. The option is less of an option (it’s not really configuration), and more of a caching technique. This is somewhat of a relic, as rewrites predate object caching and transients in WordPress, both of which are better techniques to handle caching in modern WordPress.

Removing this option and changing it to use a proper caching subsystem in WordPress should fix multiple problems, including the need to flush rewrites. This should improve the UX for end users, as we should be able to remove the “links on your site don’t work, so go to the Permalinks page and save” trick (which only really requires visiting the page, not saving).

The need to cache rewrites at all can also be reconsidered; many of the rewrite rules are simply entries in an array, and are not expensive to generate on-the-fly, while removing the caching so can make for an easier to use and more dynamic system. More expensive rules can be cached by the code generating the rule, rather than via the monolithic rewrite cache.

This has the potential to improve the user experience and fix a class of issues, but it also has the potential to ruin performance, depending on how other code is using it. It’s important to tread carefully as we attempt to improve this, and ensure we remain compatible and performant. Introducing a two-tiered system is one approach we can consider, with the ability for plugins to opt-in to a newer, dynamic system to avoid problems with flushing.

Why a Feature Project?

I’m proposing Rewrites Next Generation as a feature project for several reasons. The concept and implementation are both large and complex, moreso than simply operating in an informal matter on Trac tickets. The impact of this project is also large, affecting many plugin and theme developers, as well as potential improvements to UX. Gaining feedback from all interested stakeholders is important, as this is a crucial part of WordPress.

Getting Started

The steps I’ve listed here are only a selection of the issues with rewrites. The rewrite system hasn’t been massively changed since its inception, so there are plenty of parts that could be changed to better suit the modern era of WordPress development. The issues here are simply the three most important that I’ve found, but I want to hear your feedback too.

Let’s talk rewrites. I’m proposing a weekly meeting for Rewrites Next Generation, at Wednesday, 23:00 UTC with the first meeting at May 4th 23:00 UTC. If you’re interested in rewrites, or have had problems with them in the past, let’s talk and work out what we need to do to improve rewrites. (This is a non-permanent meeting to set the scope of the project; we’ll refine meeting frequency and timing at a later date.)

After this initial discussion, we can settle on concrete goals and a timeline for the initial stages of the project. A proof-of-concept patch and ticket are available on Trac, however alternative approaches should be considered after this discussion. The short-term goal is to begin landing these improvements in trunk, with the goal of having our first changes in WordPress 4.6, which is a quick but achievable timeline.

This project has the potential to make a large impact on developers and users, and it’s important that everyone has their say. I hope you’ll join me for the first meeting, and join in the fun of contributing to a key part of WordPress!

Thanks for reading. <3

#rewrite-rules

REST API: Slashed Data in WordPress 4.4 and 4.5

Hi everyone. The REST API team recently discovered a bug with parameter parsing in the API infrastructure, part of WordPress 4.4. For those of you using the API infrastructure, you need to be aware of a bug fix we’re making with the API.

The Problem

The REST API has several types of parameters that it mixes together. These come from several sources including the request body as either JSON or URL-encoded form data ($_POST), query parameters ($_GET), the API route, and internally-set defaults. Unfortunately, due to an oversight on our behalf, these parameters can be inconsistently formatted.

In WordPress, the superglobal request variables ($_POST and $_GET) are “slashed”; effectively, turning magic quotes on for everyone. This was originally built into PHP as a feature to help guard against SQL injection, but was later removed. Due to compatibility concerns, WP cannot change this behaviour for the superglobals. This only applies to the PHP superglobals, not to other sources of input like a JSON body or parameters in the URL. It additionally does not apply to form data on PUT or DELETE requests.

Internally, some low-level WordPress functions expect slashed data. These functions internally call wp_unslash() on the data you pass in. This means input data from the superglobals can be passed in directly, but other data needs to be wrapped with a call to wp_slash().

When the REST API gathers the data sources, it accidentally mixes slashed and unslashed sources. This results in inconsistent behaviour of parameters based on their source. For example, data passed as a JSON body is unslashed, whereas data passed via form data in the body is slashed (for POST requests).

For example, the following two pieces of data are equivalent in the REST API:


// JSON body:
{"title": "Foo"}

// Form-data ($_POST)
title=Foo

// Both result in:
$request->get_param('title') === 'Foo';

However, if the data contains slashes itself, this will be inconsistently passed to the callback:


// JSON body:
{"title": "Foo\Bar"}

// Results in:
$request->get_param('title') === 'Foo\Bar';

// Form-data ($_POST) (%3D = "\")
title=Foo%3DBar

// Results in:
$request->get_param('title') === 'Foo\\Bar';

This means that callbacks need to understand where parameters come from in order to consistently handle them internally. Specifically:

  • Data passed in the query string ($_GET, $request->get_query_params()) is slashed
  • Data passed in the body as form-encoded ($_POST, $request->get_body_params()) is slashed for POST requests, and unslashed for PUT and DELETE requests.
  • Data passed in the body as JSON-encoded ($request->get_json_params()) is unslashed.
  • Data passed in the URL ($request->get_url_params()) is unslashed.
  • Data passed as a default ($request->get_default_params()) is unslashed.

In addition, parameters set internally via $request->set_param() are unslashed. Unit and integration tests for API endpoints typically use these directly, so the majority of tested code (such as the WP REST API plugin) assumes parameters are unslashed.

See the related Trac Ticket #36419 for more information.

The Solution for WordPress 4.4 and 4.5

We are regarding inconsistently-slashed data as a major bug, and are changing the API infrastructure to ensure unslashed data. This will ensure that data is consistent regardless of the source. Callbacks will now receive unslashed data only, and can rely on this regardless of the original data source or request method.

If you are using functions that expect slashed data in your callback, you will need to slash your data before passing into these functions. Commonly used functions that expect slashed data are wp_insert_post, wp_update_post, update_post_meta, wp_insert_term, wp_insert_user, along with others. Before passing data into these functions, you must call wp_slash() on your data.

The fix for this issue, will be included in the WordPress 4.5 release candidates and final release. Due to the severity of the bug, we are also backporting the fix to the next minor WordPress 4.4 update. This also ensures you can update your plugins can act consistently across all versions of the REST API.

We understand that this may inadvertently break some plugins that are expecting slashed data. Right now, it’s not possible to consistently ensure that callbacks receive slashed data, so it is likely that these plugins will already break in some conditions.

tl;dr: if you’re using wp_insert_* or *_post_meta in your REST API callback, you need to ensure you are calling wp_slash() on data you are passing in, regardless of source.

We apologize for this bug existing in the first place. Slashed data is a problem that has plagued WordPress for a long time, and we’re not immune to getting caught by the issue ourselves.

#4-4, #4-5, #rest-api

WP REST API: 2.0 Beta 13 & Roadmap

Hi folks! I’m here with another exciting update from the API team.

Beta 13

First off, we’re excited to announce 2.0 Beta 13 “yoink.adios\losers” is now available. Grab it from the plugins repo or GitHub while it’s hot. Here’s some of the key updates:

  • BREAKING CHANGE: Fix Content-Disposition header parsing. This technically breaks backwards compatibility to correctly match the header specification. (#2239)

  • BREAKING CHANGE: Use compact links for embedded responses if they are available. We now use CURIEs for sites on 4.5+, which look like wp:term (but canonicalise to the full URI relation). (#2412)

  • Updated JS client to the latest version. (#2403)

There’s lots more changes in this release; check out the release notes or the commits for this release.

Roadmap

We’ve been thinking about how to tackle the API in the coming future. We want to do the most we can to ensure you can build sites with confidence.

Along these lines, we’re going to release a 2.0 final version in the coming months. This will be a completely stable release with guaranteed backwards compatibility for the foreseeable future. This backwards compatibility ensures that your sites can remain up-to-date with minimal maintenance or issues with upgrading.

We originally held the software in beta for a long period to ensure that breaking changes could be rolled in if deemed necessary to move the project forward. However, the majority of these breaks occurred at the start of the 2.0 lifecycle, and the API is mostly stable at this point. Keeping the ability to break compatibility benefits only us, whereas moving to a stable release benefits everyone.

Moving forward, version 2.0 of the WP REST API will follow a normal project release cycle. We will have minor releases in the 2.x series as new features are added, and bugfix releases in the 2.0.x series.

As for the core merge itself, we are not submitting a merge proposal of the core endpoints for WordPress 4.6. We believe endpoints for the main WordPress objects (posts, users, comments, terms, and taxonomies) are not enough to garner the support needed for the proposal to be accepted. Our hope is that with a stable version 2.0 release, we will attract our community members that have been waiting for the endpoints to be available in core, and submit a merge proposal for the WordPress 4.7 release cycle.

In addition to attracting more developers within our community, we are also looking to get more contributors involved with the project. As noted in previous discussions, the four of us on the API team can’t keep pace with WordPress itself without help. We’re looking to get WordPress core component maintainers involved in their relevant components, as well as new developers from outside the project. Moving forward, the API team sees our role as advisory over the API itself, with the API treated as an integral part of the component rather than maintained by a separate team. We’re also going to continue to work on our feature plugins (metadata, site/multisite, menus/widgets, and authentication) in parallel, and are looking for help on these as well. (There’s also more news regarding authentication coming very soon.)

If you’d like to get involved with the API, please let us know. You can comment here, ping us on Slack in the #core-restapi room, or via GitHub issues. We’re looking at spending significant time onboarding new users, so if you’d like to get involved, now’s the time! Our weekly meeting is at Monday 23:00 UTC

Thanks for catching up with us, and have a wonderful day.

With love,

Ryan, Rachel, Daniel, and Joe

#json-api, #rest-api

WP REST API: OAuth Plugin Security Update

Hi everyone. This is a quick update on the OAuth 1.0a Server plugin, available on GitHub.

Versions of the OAuth plugin prior to this commit contain a security issue during the authorization flow, regarding signature and nonce checks. Due to the OAuth architecture, it is highly unlikely this can be used to compromise a site or client application; however due to an abundance of caution, we recommend all users update to 0.2.1 immediately. (Pull the latest changes from master.)

Thanks to @bradyvercher for responsible disclosure of this issue via HackerOne.

WP REST API: New Tools & OAuth Updates

Hi everyone! I’m here today with some special news for everyone, rather than a standard release announcement. I have three things to announce instead. 🙂

Discovery Library for PHP

A super cool thing that you might not know about with the API is that it’s entirely discoverable. We use a relatively simple process modelled after Atom/RSS feed discovery. All you need to do is check a site’s headers for a Link header:

Link: <http://example.com/wp-json/>; rel="https://api.w.org/"

This allows a tonne of possibilities, including renaming the API base, or even delegating API access to someone else. (For example, WordPress.com could use https://api.wordpress.com/{site_id}/ instead of per-site APIs.)

However, this isn’t always the easiest process to use (even if you have an advanced degree in hypothetical topology). To simplify this, we now have a discovery library for PHP 5.3+.

To use it, add wp-api/discovery to your Composer requirements manually or run composer require wp-api/discovery in your project directory. You can then use the WordPress\Discovery\discover() function to discover the API for a given URL. (Oh hey, namespaces!)

The library also includes a demo that you can run using PHP’s built-in server, and we’re working on getting a public version of this up on wp-api.org so you don’t even need to install it.

This should simplify the discovery process for everyone, and I’m hoping some wonderful folks in the community will help port this to other languages as well. (Hint hint.)

New OAuth Server

One of the weakest points of developing with the API right now is getting authentication working. For a long time, our OAuth server plugin has languished and fallen behind as we push forward with the API. No longer is this the case!

Simply update to the latest master. This will also be available on WordPress.org very soon.

This new version of the OAuth server has a bunch of changes, including:

  • Full admin UI, including application management and the ability to revoke tokens
  • Ability to delete applications or regenerate their secrets
  • Callback validation process overhaul, now supporting custom protocols
  • Overhauled internals

In addition to this, I wanted to address one of the biggest problems with the OAuth process: documentation. The documentation for the OAuth server and process has been terrible in the past. Previously, I’d indicated to people that they should just go read the generic OAuth 1.0a documentation on the web and try with that, but as it turns out, there’s no good documentation on this. (Apologies to those of you who’ve struggled in the past.)

Thankfully, this is now fixed, with a guide included and available on Gitbook. This is an initial version of the guide, and I imagine it’ll grow and improve further in the future.

If there’s anything missing you’d like added or improved, file an issue on the plugin repo. (The guide’s source is also included with the plugin.)

Demo API Client

(pause for breath)

Combining all these pieces, there’s now a demo API client in PHP that you can download and run to try all of this out. The demo client uses the discovery library to find your site, then connects with OAuth to display your user details. Again, you can run this locally using PHP’s built-in server, and we’re working on getting a version set up on wp-api.org too.

Internally, this uses the wonderful OAuth 1 client library by The League of Extraordinary Packages. This repo also acts as a provider for that library, allowing you to use the library in your own code to handle OAuth.

(Both the discovery library and the demo client are open source and MIT licensed, allowing you to use them in commercial projects should you so desire.)

Hopefully you find these pieces useful. As always, your feedback on all of this is much appreciated; we’d also love to see discovery libraries and demo clients in other languages, if anyone wants to port them across. Thanks for being great.

#feature-plugins, #json-api, #rest-api