Skip to main content
Version: main (5.3)

The Fetch batcher

Since 5.2

The core/fetch module makes requests to the Moodle REST API (routes). In addition to immediate requests, it can queue several requests and send them as a single HTTP $batch request, reducing the number of round trips.

Immediate requests​

Static methods perform a single request immediately:

import Fetch from 'core/fetch';

const response = await Fetch.performGet('mod_example', 'animals', {params: {type: 'mammal'}});

performGet, performHead, performPost, performPut, performPatch and performDelete are available.

Batching requests​

The same methods are available on an instance. Instance calls are queued and sent together.

The automatic batcher​

Fetch.getBatcher() returns a shared singleton which automatically executes the queue 50ms after the last request was added.

import Fetch from 'core/fetch';

const batcher = Fetch.getBatcher();
const [mammals, reptiles] = await Promise.all([
batcher.performGet('mod_example', 'animals', {params: {type: 'mammal'}}),
batcher.performGet('mod_example', 'animals', {params: {type: 'reptile'}}),
batcher.performDelete('mod_example', `animals/${pig.id}`),
]);

Each call returns a Promise resolving to a standard Response for that sub-request, and failures reject only the individual promise.

A manual batcher​

Create an instance yourself and call execute() when ready. An optional constructor argument sets an auto-execute delay in milliseconds.

const batcher = new Fetch();
const results = Promise.all([
batcher.performGet('mod_example', 'animals', {params: {type: 'mammal'}}),
batcher.performGet('mod_example', 'animals', {params: {type: 'reptile'}}),
]);

batcher.execute();
await results;

Behaviour notes​

  • If a batch contains a single request, the batch endpoint is not used; it is sent as a normal request.
  • The queue is flushed automatically once it holds more than 20 requests.
  • If the $CFG->batch_fetch_requests setting (JS: M.cfg.batchFetchRequests, default true) is disabled, each request is executed immediately instead of being queued.

Cacheable requests bypass the batcher​

Requests made with a cachekey (see route caching) are sent individually, even via a batcher. Hiding them inside a generic $batch request would prevent browsers and reverse proxies caching each URL.

const response = await Fetch.getBatcher().performGet('core', 'strings/en/core', {cachekey: M.cfg.jsrev});

To batch these requests anyway, set $CFG->batch_api_asset_requests = true (JS: M.cfg.batchApiAssetRequests).

See also​