Closed BFS-JWesseler closed 3 months ago
Hi 👋
You can already do this with a custom api endpoint.
Create the following file: config/api/batch-content-items.php
With the following contents:
<?php
$batch = $this->param('batch', null);
if (!$batch) {
return $this->stop(412);
}
try {
$batch = json5_decode($batch, true);
} catch(\Throwable $e) {
$this->stop(['error' => "<batch> is not valid json"], 412);
}
$return = [];
$content = $this->module('content');
$userRole = $this->helper('auth')->getUser('role');
foreach ($batch as $model => $opts) {
if (!$content->model($model) || !$this->helper('acl')->isAllowed("content/{$model}/read", $userRole)) {
continue;
}
$options = [];
$process = ['locale' => $opts['locale'] ?? $this->param('locale', 'default')];
if (isset($opts['filter'])) $options['filter'] = $opts['filter'];
if (isset($opts['sort'])) $options['sort'] = $opts['sort'];
if (isset($opts['fields'])) $options['fields'] = $opts['fields'];
if (isset($opts['limit'])) $options['limit'] = $opts['limit'];
if (isset($opts['skip'])) $options['skip'] = $opts['skip'];
if (isset($opts['populate'])) {
$process['populate'] = $opts['populate'];
$process['user'] = $this->helper('auth')->getUser();
}
if (!isset($options['filter']) || !is_array($options['filter'])) {
$options['filter'] = [];
}
// only published items
$options['filter']['_state'] = 1;
$return[$model] = $content->items($model, $options, $process);
}
return $return;
Now you can request the following endpoint:
/api/batch-content-items?batch={model1:{filter:{...}}, model2:{filter:{...}}, ...}
Thanks, it is working flawlessly.
FYI: This is now part of the core: https://getcockpit.com/documentation/core/api/content#get-content-items
API endpoint to fetch items of multiple models at once
Currently, we are facing the issue that we have around 40-50 models which require as many singular HTTP requests. It would be nice if we could fetch all of the items of multiple models with the same filter settings at once. It also does not need to be optimized on the data structure, basically can be done with a loop and adding the models to a JSON array which then contains the items of the respective models as usual.
Current it looks like:
The idea would be to have something like:
api/content/multiple-items?models=[<model1>,<model2>,...]&filter=<filter>
You could also add an array to the filters for something like (so that you can have filters per model if needed - even if we don't need it):
api/content/multiple-items?models=[<model1>,<model2>,...]&filters=[<filter1>,<filter2>,...]
Or something similar. Anyway, that would be awesome to have and would speed up our initialization time by a lot. The easiest solution will suffice, as long as we don't need to make 40-50 HTTP requests for fetching the items of the different models with the same filter. It would be greatly appreciated.