Find out:
- list of actions which apply to our REST API
- which of these actions require us to enforce REST API rate limiting in our code
Time box: 16 hrs
Find out:
Time box: 16 hrs
Status | Subtype | Assigned | Task | ||
---|---|---|---|---|---|
Open | None | T335067 Epic: Wikidata Query Service stabilization | |||
Resolved | Lydia_Pintscher | T314503 rollout of the new Wikibase REST API to Wikidata | |||
Resolved | WMDE-leszek | T320470 "Non-functional" blockers of delivering Wikibase REST API to production Wikidata | |||
Resolved | WMDE-leszek | T301970 Rate limit request to Wikibase REST API | |||
Resolved | Jakob_WMDE | T322746 [INVESTIGATE] Find out if/how current rate limiting applies to REST API |
Ok, so the approach here was to a) look at all the standard rate limited actions and ponder which might apply to the REST API, and b) take the action API as a baseline and compare its calls to RateLimiter::limit() to those resulting from equivalent REST API requests.
TL;DR As far as I can tell the REST API already does everything the action API does by using the same MediawikiEditEntity::attemptSave() low-level service.
a) I looked at https://www.mediawiki.org/wiki/Manual:$wgRateLimits and https://gerrit.wikimedia.org/r/plugins/gitiles/operations/mediawiki-config/+/c44980b3fcfeb4d2139dac7311e33f599ea0788e/wmf-config/InitialiseSettings.php#7997 and only found "edit" and "create" of interest for our REST API so far. In part (b) of the investigation I also discovered "wikibase-idgenerator" here https://gerrit.wikimedia.org/g/mediawiki/extensions/Wikibase/+/cc66ac0089ce1eca84eaddf655791003d48259a2/extension-repo.json#964.
b) In this part I made requests to similar action API and REST API endpoints and simply put a breakpoint in RateLimiter::limit(). I didn't check all the endpoints because it is quite obvious that they behave similarly because of their implementation. Here are the results:
GET /rest.php/wikibase/v0/entities/items/{id}: no rate limiting
wbgetentities: no rate limiting
wbgetclaims: no rate limiting
GET /rest.php/wikibase/v0/entities/items/{id}/statements/{statement_id}: no rate limiting
wbcreateclaim:
$action = "edit" $incrBy = {int} 1 RateLimiter.php:141, MediaWiki\Permissions\RateLimiter->limit() User.php:1472, User->pingLimiter() MediawikiEditEntity.php:539, Wikibase\Repo\EditEntity\MediawikiEditEntity->checkRateLimits() MediawikiEditEntity.php:694, Wikibase\Repo\EditEntity\MediawikiEditEntity->attemptSave() StatsdSaveTimeRecordingEditEntity.php:77, Wikibase\Repo\EditEntity\StatsdSaveTimeRecordingEditEntity->attemptSave() EntitySavingHelper.php:387, Wikibase\Repo\Api\EntitySavingHelper->attemptSaveEntity() CreateClaim.php:152, Wikibase\Repo\Api\CreateClaim->execute() ApiMain.php:1902, ApiMain->executeAction() ApiMain.php:877, ApiMain->executeActionWithErrorHandling() ApiMain.php:848, ApiMain->execute() api.php:90, wfApiMain() api.php:45, {main}()
POST /rest.php/wikibase/v0/entities/items/{id}/statements
$action = "edit" $incrBy = {int} 1 RateLimiter.php:141, MediaWiki\Permissions\RateLimiter->limit() User.php:1472, User->pingLimiter() MediawikiEditEntity.php:539, Wikibase\Repo\EditEntity\MediawikiEditEntity->checkRateLimits() MediawikiEditEntity.php:694, Wikibase\Repo\EditEntity\MediawikiEditEntity->attemptSave() StatsdSaveTimeRecordingEditEntity.php:77, Wikibase\Repo\EditEntity\StatsdSaveTimeRecordingEditEntity->attemptSave() MediaWikiEditEntityFactoryItemUpdater.php:54, Wikibase\Repo\RestApi\DataAccess\MediaWikiEditEntityFactoryItemUpdater->update() AddItemStatement.php:88, Wikibase\Repo\RestApi\UseCases\AddItemStatement\AddItemStatement->execute() AddItemStatementRouteHandler.php:105, Wikibase\Repo\RestApi\RouteHandlers\AddItemStatementRouteHandler->runUseCase() [...] MiddlewareHandler.php:33, Wikibase\Repo\RestApi\RouteHandlers\Middleware\MiddlewareHandler->run() AddItemStatementRouteHandler.php:90, Wikibase\Repo\RestApi\RouteHandlers\AddItemStatementRouteHandler->run() SimpleHandler.php:38, Wikibase\Repo\RestApi\RouteHandlers\AddItemStatementRouteHandler->execute() Router.php:487, MediaWiki\Rest\Router->executeHandler() Router.php:406, MediaWiki\Rest\Router->execute() EntryPoint.php:191, MediaWiki\Rest\EntryPoint->execute() EntryPoint.php:131, MediaWiki\Rest\EntryPoint::main() rest.php:31, {main}()
wbsetclaim:
$action = "edit" $incrBy = {int} 1 RateLimiter.php:141, MediaWiki\Permissions\RateLimiter->limit() User.php:1472, User->pingLimiter() MediawikiEditEntity.php:539, Wikibase\Repo\EditEntity\MediawikiEditEntity->checkRateLimits() MediawikiEditEntity.php:694, Wikibase\Repo\EditEntity\MediawikiEditEntity->attemptSave() StatsdSaveTimeRecordingEditEntity.php:77, Wikibase\Repo\EditEntity\StatsdSaveTimeRecordingEditEntity->attemptSave() EntitySavingHelper.php:387, Wikibase\Repo\Api\EntitySavingHelper->attemptSaveEntity() SetClaim.php:210, Wikibase\Repo\Api\SetClaim->executeInternal() SetClaim.php:163, Wikibase\Repo\Api\SetClaim->execute() ApiMain.php:1902, ApiMain->executeAction() ApiMain.php:877, ApiMain->executeActionWithErrorHandling() ApiMain.php:848, ApiMain->execute() api.php:90, wfApiMain() api.php:45, {main}()
PUT /rest.php/wikibase/v0/entities/items/{id}/statements/{statement_id}:
$action = "edit" $incrBy = {int} 1 RateLimiter.php:141, MediaWiki\Permissions\RateLimiter->limit() User.php:1472, User->pingLimiter() MediawikiEditEntity.php:539, Wikibase\Repo\EditEntity\MediawikiEditEntity->checkRateLimits() MediawikiEditEntity.php:694, Wikibase\Repo\EditEntity\MediawikiEditEntity->attemptSave() StatsdSaveTimeRecordingEditEntity.php:77, Wikibase\Repo\EditEntity\StatsdSaveTimeRecordingEditEntity->attemptSave() MediaWikiEditEntityFactoryItemUpdater.php:54, Wikibase\Repo\RestApi\DataAccess\MediaWikiEditEntityFactoryItemUpdater->update() ReplaceItemStatement.php:106, Wikibase\Repo\RestApi\UseCases\ReplaceItemStatement\ReplaceItemStatement->execute() ReplaceItemStatementRouteHandler.php:97, Wikibase\Repo\RestApi\RouteHandlers\ReplaceItemStatementRouteHandler->runUseCase() [...] MiddlewareHandler.php:33, Wikibase\Repo\RestApi\RouteHandlers\Middleware\MiddlewareHandler->run() ReplaceItemStatementRouteHandler.php:91, Wikibase\Repo\RestApi\RouteHandlers\ReplaceItemStatementRouteHandler->run() SimpleHandler.php:38, Wikibase\Repo\RestApi\RouteHandlers\ReplaceItemStatementRouteHandler->execute() Router.php:487, MediaWiki\Rest\Router->executeHandler() Router.php:406, MediaWiki\Rest\Router->execute() EntryPoint.php:191, MediaWiki\Rest\EntryPoint->execute() EntryPoint.php:131, MediaWiki\Rest\EntryPoint::main() rest.php:31, {main}()
Just out of curiosity, I also checked two action API endpoints which aren't implemented by the REST API yet, but are coming soon.
wbsetlabel:
$action = "edit" $incrBy = {int} 1 RateLimiter.php:141, MediaWiki\Permissions\RateLimiter->limit() User.php:1472, User->pingLimiter() MediawikiEditEntity.php:539, Wikibase\Repo\EditEntity\MediawikiEditEntity->checkRateLimits() MediawikiEditEntity.php:694, Wikibase\Repo\EditEntity\MediawikiEditEntity->attemptSave() StatsdSaveTimeRecordingEditEntity.php:77, Wikibase\Repo\EditEntity\StatsdSaveTimeRecordingEditEntity->attemptSave() EntitySavingHelper.php:387, Wikibase\Repo\Api\EntitySavingHelper->attemptSaveEntity() ModifyEntity.php:340, Wikibase\Repo\Api\SetLabel->execute() ApiMain.php:1902, ApiMain->executeAction() ApiMain.php:877, ApiMain->executeActionWithErrorHandling() ApiMain.php:848, ApiMain->execute() api.php:90, wfApiMain() api.php:45, {main}()
wbeditentity when creating a new item: 3 calls
$action = "wikibase-idgenerator" $incrBy = {int} 1 RateLimiter.php:141, MediaWiki\Permissions\RateLimiter->limit() User.php:1472, User->pingLimiter() RateLimitingIdGenerator.php:33, Wikibase\Repo\Store\RateLimitingIdGenerator->getNewId() WikiPageEntityStore.php:178, Wikibase\Repo\Store\Sql\WikiPageEntityStore->assignFreshId() TypeDispatchingEntityStore.php:59, Wikibase\Lib\Store\TypeDispatchingEntityStore->assignFreshId() EntitySavingHelper.php:298, Wikibase\Repo\Api\EntitySavingHelper->createEntity() EntitySavingHelper.php:228, Wikibase\Repo\Api\EntitySavingHelper->loadEntity() ModifyEntity.php:382, Wikibase\Repo\Api\EditEntity->loadEntityFromSavingHelper() ModifyEntity.php:306, Wikibase\Repo\Api\EditEntity->execute() ApiMain.php:1902, ApiMain->executeAction() ApiMain.php:877, ApiMain->executeActionWithErrorHandling() ApiMain.php:848, ApiMain->execute() api.php:90, wfApiMain() api.php:45, {main}() $action = "edit" $incrBy = {int} 1 RateLimiter.php:141, MediaWiki\Permissions\RateLimiter->limit() User.php:1472, User->pingLimiter() MediawikiEditEntity.php:539, Wikibase\Repo\EditEntity\MediawikiEditEntity->checkRateLimits() MediawikiEditEntity.php:694, Wikibase\Repo\EditEntity\MediawikiEditEntity->attemptSave() StatsdSaveTimeRecordingEditEntity.php:77, Wikibase\Repo\EditEntity\StatsdSaveTimeRecordingEditEntity->attemptSave() EntitySavingHelper.php:387, Wikibase\Repo\Api\EntitySavingHelper->attemptSaveEntity() ModifyEntity.php:340, Wikibase\Repo\Api\EditEntity->execute() ApiMain.php:1902, ApiMain->executeAction() ApiMain.php:877, ApiMain->executeActionWithErrorHandling() ApiMain.php:848, ApiMain->execute() api.php:90, wfApiMain() api.php:45, {main}() $action = "create" $incrBy = {int} 1 RateLimiter.php:141, MediaWiki\Permissions\RateLimiter->limit() User.php:1472, User->pingLimiter() MediawikiEditEntity.php:540, Wikibase\Repo\EditEntity\MediawikiEditEntity->checkRateLimits() MediawikiEditEntity.php:694, Wikibase\Repo\EditEntity\MediawikiEditEntity->attemptSave() StatsdSaveTimeRecordingEditEntity.php:77, Wikibase\Repo\EditEntity\StatsdSaveTimeRecordingEditEntity->attemptSave() EntitySavingHelper.php:387, Wikibase\Repo\Api\EntitySavingHelper->attemptSaveEntity() ModifyEntity.php:340, Wikibase\Repo\Api\EditEntity->execute() ApiMain.php:1902, ApiMain->executeAction() ApiMain.php:877, ApiMain->executeActionWithErrorHandling() ApiMain.php:848, ApiMain->execute() api.php:90, wfApiMain() api.php:45, {main}()