Page MenuHomePhabricator

Reading List REST Interface: GET lists/changes/since endpoint
Closed, ResolvedPublic

Description

Create a REST handler and any other necessary associated code (extension.json entry, helper classes, etc.) for the GET lists/changes/since endpoint.

  • endpoint implemented
  • tests created
  • tests pass

Endpoint summary:
Get recent changes to the lists

Endpoint description:
Returns metadata describing lists and entries which have changed. Might be truncated and include a continuation token.
Request must be authenticated with a MediaWiki session cookie.
For safe synchronization, the date parameter should be taken from the continue-from field of a previous GET /lists/ or GET /lists/changes/since/{date} request. This will ensure that no changes are skipped, at the cost of sometimes receiving the same change multiple times. Clients should handle changes in an idempotent way.
Stability: unstable

Associated RESTBase code
lists.yaml (spec+forwarding)
lists.js (tests)

Associated Action API code
ApiQueryReadingListEntries
ApiQueryReadingListEntriesTest

Parameters:

namesourcerequiredtypeexampledefaultpossible valuesdescription
datepathyesstring (date-time)N/AN/ACutoff date (in ISO 8601). To ensure reliable synchronization, the API might return changes which are slightly older than the cutoff date.
nextquerynostringN/AN/AContinuation parameter from previous request

Error Response

#/components/schemas/problem per API.md and draft-nottingham-http-problem

Success Response

valuetypedescription
listsarray: list_read
nextstringContinuation token
continue-fromstring (date-time)Timestamp to sync from, to be used with the GET /lists/changes/since/{date} endpoint.

Response Headers

This endpoints has additional response headers specified in the RESTBase code:

headers:
  content-type: application/json; charset=utf-8; profile="https://www.mediawiki.org/wiki/Specs/Lists/0.1"
  cache-control: max-age=0, s-maxage=0

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript
BPirkle renamed this task from Reading List REST Interface: create lists/changes/since GET endpoint to Reading List REST Interface: GET lists/changes/since endpoint.Nov 14 2023, 2:58 AM
BPirkle updated the task description. (Show Details)

Change 983241 had a related patch set uploaded (by BPirkle; author: BPirkle):

[mediawiki/extensions/ReadingLists@master] REST Handlers for managing reading lists

https://gerrit.wikimedia.org/r/983241

Change 983241 merged by jenkins-bot:

[mediawiki/extensions/ReadingLists@master] REST Handlers for managing reading lists

https://gerrit.wikimedia.org/r/983241

Added the following parameters that were previously exposed by the underlying Action API endpoint, but not by RESTBase:

namesourcerequiredtypeexampledefaultpossible valuesdescription
sortquerynostringupdatednamename, updatedsort type
dirquerynostringdescendingascendingascending, descendingsort direction
limitquerynointeger5101..10Maximum number of values to return
BPirkle updated the task description. (Show Details)
Dbrant subscribed.

@BPirkle It looks like one requirement for this task might have fallen through the cracks, and somehow got by our testing:

The lists/changes/since endpoint is intended to give us any changes made to any lists or any of the entries in lists. But it looks like the endpoint currently in production only returns changes made to a list itself, not its entries.

Note that the description of the endpoint says "Returns metadata describing lists and entries which have changed," even though for some reason the old lists.yaml only mentions lists in the response, which likely contributed to the confusion.

Do you think it would be simple enough to add changes to entries in addition to changes to lists in the response of this endpoint?

Seddon triaged this task as High priority.Jun 24 2025, 9:15 PM

Confirmed. Doesn't look that bad to fix, based on a quick initial triage.

Daniel and I had a fast look at this. We may have missed something, but it looks like the underlying data is still available via ReadingListRepository. The two functions of interest are:

ReadingListRepository::getListsByDateUpdated
ReadingListRepository::getListEntriesByDateUpdated

Previously, based on our quick analysis, it looks like under the RESTBase/Action API implementation of the lists/changes/since data from two Action API modules was combined. In the Action API implementation, setting the changedsince parameter set activates MODE_CHANGES in both modules:

ApiQueryReadingListEntries
ApiQueryReadingLists

The relevant bit in RESTBase appears to be in lists.yaml.

From a MW REST perspective, we have ListsChangesSinceHandler::execute, which ultimately calls ReadingListRepository:::getListsByDateUpated. There isn't any corresponding code to call ReadingListRepository::getListEntriesByDateUpdated.

So it looks like the fix is to modify ListsChangesSinceHandler::execute (and maybe a bit of related code) to make that additional call for entry change information, and include it in the response.

Update: I'm working through these change locally. Previously, we had some handlers that were aware of lists, and others that were aware of entries. As it turns out, the ListsChangesSinceHandler will need to be aware of both. I could do a quick-and-dirty version with lots of copy and paste, but I'd rather rearrange things in a clean way. All that is pretty straightforward, just code shuffling.

I do notice that continuation is a little interesting in this case, so I'll want reviewers to pay special attention to that, when the change is ready.

Change #1166509 had a related patch set uploaded (by BPirkle; author: BPirkle):

[mediawiki/extensions/ReadingLists@master] Reading Lists: add missing "entries" values to response

https://gerrit.wikimedia.org/r/1166509

In the process of fixing this, I've come across an oversight in the original port of the endpoints.

For compatibility with the existing RESTBase/Action API implementation, the /changes/since endpoint should never have accepted "name" as a valid sort value.

The relevant Action API code is:

		if ( $mode === self::$MODE_CHANGES && $sort === 'name' ) {
			// We don't have the right DB index for this. Wouldn't make much sense anyway.
			$errorMessage = $this->msg( 'apierror-readinglists-invalidsort-notbyname', static::$prefix );
			$this->dieWithError( $errorMessage, 'invalidparammix' );
		}

I did not mirror this check when creating the MW REST API equivalent, so the MW REST version of /changes/since has been accepting "name" as a valid sort value since that endpoint was released. The fix is to have the endpoint return an error if "name" is passed for the sort value (and the code for that is trivial).

I'm very tempted to just fix this as a bug as part of the larger fix, without modifying endpoint version. But it is technically a breaking change to the behavior of that endpoint.

Any objections to treating this as a fix and not a change?

Any objections to treating this as a fix and not a change?

No objections here -- neither of the apps uses a sort parameter when making that call.

Any objections to treating this as a fix and not a change?

No objections here -- neither of the apps uses a sort parameter when making that call.

Thanks. The change I posted for review bumps the patch version (0.1.0 => 0.1.1) in the module definition file, but doesn't change the url in any way. So callers will be unaffected, but we'll have a way to tell, by looking at the OpenAPI spec, if a particular wiki has this change.

Change #1166509 merged by jenkins-bot:

[mediawiki/extensions/ReadingLists@master] Reading Lists: add missing "entries" values to /changes/since response

https://gerrit.wikimedia.org/r/1166509

I think this is done. If anyone sees additional related issues, please either reopen or file a new bug report.