Several projects (including dewiki) use the FlaggedRevs extension to show a reviewed version of an article to anonymous users. REST API users like the mobile apps expect similar functionality, so we should support this.
API behavior
Use cases:
- Mobile apps, reading focused web apps: Load stable revision of an article.
- Editing: Load the *latest* revision of an article.
- Recentchanges followers: Retrieve specific revisions, independent of whether they are flagged or not.
Strawman proposal:
- /page/html/{title}: Return flagged (stable) revision.
- /page/html/{title}/{revision}: Return specific revision, independent of whether it is stable or not.
For editing, we also need a way to explicitly retrieve the latest revision, stable or not. Options:
- Let the editor ask for the latest revision explicitly, using /page/html/{title}/{revision}. This is current VE behavior on mis-match between metadata & REST API response.
- Advantage: Simplicity. No code changes needed. Will need similar editor smarts when reusing view HTML as well.
- Disadvantage: Doubled request latency on mis-match. This is likely to affect a relatively small percentage of edits.
- Extra parameter for "latest" entry point: /page/html/{title}?latest=true.
- Disadvantages: Somewhat ugly; problematic for caching. Would make CDN caching ineffective for edit requests.
- Advantages: Reduces probability of version mis-match on edit.
- Special revision value: /page/html/latest
- Disadvantages: Similar to the ?latest=true parameter above. Complicates parameter validation and documentation.
- Advantages: Reduces probability of version mis-match on edit.
I am currently leaning towards 1), mostly because it does not complicate the API, and because it should still result in decent performance for editing. It also seems to be the option we'd want once we use Parsoid HTML for views, and don't need to load any HTML for editing in the common case of flagged revision being the same as the latest revision.
Implementation options in RESTBase
Efficient access to flagged revisions will require some changes in RESTBase's database structure. Here are a few options.
(Temporary): Retrieve latest flagged revision from the MW API
Idea: For requests to /page/html/{title} (latest revision), request the latest flagged revision number from the MediaWiki API in parallel with retrieving the latest stored revision from Cassandra. Then compare the two. If the latest stored revision does not match, repeat the Cassandra storage request with the latest flagged revision.
Performance impact, on projects with flagged revisions enabled:
- Requests for specific revisions: No impact on requests for specific revisions.
- Requests for latest revision: Slow down to the max of (MW API request, storage request) in most cases. In practice, this would likely be a median slow-down from about 6ms (storage) to about 50ms (MW API). In the relatively rare case of recently edited pages with outstanding unpatrolled edits, we would repeat the storage request, adding another ~6ms median.
Open questions
- CDN purging on flagged revision review. Need to purge "latest" cached content in that case. @Pchelolo mentioned that we do not have a flaggedrev review event in eventbus yet, but we could consider to use the flaggedrevs_CacheUpdate job mentioned in https://phabricator.wikimedia.org/T175210 as a pseudo-event.
Extra "flagged" table
Idea: Add an extra table keyed on title that contains those revisions that are flagged, but not the latest for the title. Read from both the flagged table & latest table, and return the flagged revision if found.
Updates
- On edit:
- Make sure the flagged revision is stored in the flagged table.
- Store the new revision.
- On flag status update:
- If flagged revision is the latest, delete the flagged entry from the "flagged" table.
- Otherwise, store the new flagged revision to the "flagged" table.