API: Some changes to tag API endpoints

- Updated tag values endpoint to use query param instead of path
  argument, so a better range of values can be provided (including those
  with slashes).
- Updated image gallery example request to align with docs use changes.
This commit is contained in:
Dan Brown
2026-04-14 12:03:29 +01:00
parent 346dc27979
commit 208629ee1f
5 changed files with 22 additions and 8 deletions

View File

@@ -7,6 +7,7 @@ namespace BookStack\Activity\Controllers;
use BookStack\Activity\TagRepo;
use BookStack\Http\ApiController;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
/**
* Endpoints to query data about tags in the system.
@@ -21,6 +22,15 @@ class TagApiController extends ApiController
) {
}
protected function rules(): array
{
return [
'listValues' => [
'name' => ['required', 'string'],
],
];
}
/**
* Get a list of tag names used in the system.
* Only the name field can be used in filters.
@@ -38,18 +48,21 @@ class TagApiController extends ApiController
}
/**
* Get a list of tag values, which have been set for the given tag name.
* Get a list of tag values, which have been set for the given tag name,
* which must be provided as a query parameter on the request.
* Only the value field can be used in filters.
*/
public function listValues(string $name): JsonResponse
public function listValues(Request $request): JsonResponse
{
$tagQuery = $this->tagRepo
->queryWithTotalsForApi($name);
$data = $this->validate($request, $this->rules()['listValues']);
$name = $data['name'];
$tagQuery = $this->tagRepo->queryWithTotalsForApi($name);
return $this->apiListingResponse($tagQuery, [
'name', 'value', 'usages', 'page_count', 'chapter_count', 'book_count', 'shelf_count',
], [], [
'name', 'value',
'value',
]);
}
}

View File

@@ -0,0 +1 @@
GET /api/tags/values-for-name?name=Category

View File

@@ -111,7 +111,7 @@ Route::get('search', [SearchApiController::class, 'all']);
Route::get('system', [SystemApiController::class, 'read']);
Route::get('tags/names', [TagApiController::class, 'listNames']);
Route::get('tags/name/{name}/values', [TagApiController::class, 'listValues']);
Route::get('tags/values-for-name', [TagApiController::class, 'listValues']);
Route::get('users', [UserApiController::class, 'list']);
Route::post('users', [UserApiController::class, 'create']);

View File

@@ -76,7 +76,7 @@ class TagsApiTest extends TestCase
$booksToTag->each(fn (Book $book) => $book->tags()->save(new Tag(['name' => 'MyValueApiTag', 'value' => 'tag-book' . $book->id])));
$chaptersToTag->each(fn (Chapter $chapter) => $chapter->tags()->save(new Tag(['name' => 'MyValueApiTag', 'value' => 'tag-chapter' . $chapter->id])));
$resp = $this->actingAsApiEditor()->getJson('api/tags/name/MyValueApiTag/values');
$resp = $this->actingAsApiEditor()->getJson('api/tags/values-for-name?name=MyValueApiTag');
$resp->assertStatus(200);
$resp->assertJson(['total' => 18]);
@@ -101,7 +101,7 @@ class TagsApiTest extends TestCase
$this->permissions->disableEntityInheritedPermissions($pagesToTag[3]);
$this->permissions->disableEntityInheritedPermissions($pagesToTag[6]);
$resp = $this->actingAsApiEditor()->getJson('api/tags/name/MyGreatApiTag/values');
$resp = $this->actingAsApiEditor()->getJson('api/tags/values-for-name?name=MyGreatApiTag');
$resp->assertStatus(200);
$resp->assertJson(['total' => 8]);
$resp->assertJsonMissing(['value' => 'cat' . $pagesToTag[3]->id]);