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}()