4.2 KiB
4.2 KiB
GET /article/search
Protected. Requires a valid session cookie (credentials: 'include').
Fuzzy article search. Use this to build a search box / result list with category facets.
Query parameters
| Param | Required | Description |
|---|---|---|
target |
yes | Search string. Split on spaces; each word must match (AND). Each word is matched with LIKE %word% against EAN, supplier article number, name, article number, or barcode. |
filter |
no | Comma-separated category IDs. Omit or leave empty to search all categories. See Category filter. |
offset |
no | Pagination offset (default 0). |
maxCount |
no | Page size (default 10). |
Search behaviour
- Multiple spaces are collapsed to one.
- Example:
target=bizz allmix→ bothbizzandallmixmust match somewhere on the article. - By default only active articles (
cAktiv = 'Y') are returned. - Without a category filter, at most 2000 rows are returned (before pagination).
- Results are ordered by product name ascending.
lengthis the total match count (beforeoffset/maxCount);recordsetis the current page.
Category filter
filter value |
Effect |
|---|---|
| (omitted or empty) | All categories; TOP 2000 |
751 |
Include inactive articles (no cAktiv = 'Y' restriction). Still uses category branch logic if other IDs are present. |
16 or 16,39 |
Restrict to articles in those categories (OR). No row limit. |
Pass category IDs as a comma-separated list: filter=16,39.
Whenever filter is present, categories always includes every id from filter, even when length is 0 or a filtered id has no hits. Those entries use master-data name / parent and may have count: 0. Other facet categories with hits are still returned as usual.
Response 200
{
"length": 42,
"recordset": [
{
"categories": "16,39",
"available": 0,
"id": 49,
"stock": null,
"sku": "42000044",
"name": "BioBizz AllMix Peat Free 20L",
"price": 13.5,
"tax": 19
}
],
"categories": {
"16": { "name": "Dünger", "count": 42, "parent": 0 },
"39": { "name": "Erde", "count": 18, "parent": 16 }
}
}
Empty result with an active filter still returns the applied category:
{
"length": 0,
"recordset": [],
"categories": {
"16": { "name": "Dünger", "count": 0, "parent": 0 }
}
}
Top-level fields
| Field | Type | Notes |
|---|---|---|
length |
number | Total matching articles (unpaginated). |
recordset |
array | Current page of shaped article rows. |
categories |
object | Map keyed by category id (string). Facet counts for the current search (+ filters). |
recordset[] fields
| Field | Type | Notes |
|---|---|---|
id |
number | Internal article ID (kArtikel) |
sku |
string | Article number — pass to GET /article/get |
name |
string | Display name |
stock |
number | null | Stock in warehouse 1 |
available |
number | null | Available stock |
price |
number | null | Brutto VK, rounded to 1 decimal |
tax |
number | null | Tax rate percent for the article’s Steuerklasse |
categories |
string | null | Comma-separated category IDs on the article |
categories map entries
| Field | Type | Notes |
|---|---|---|
name |
string | null | Display label from category master data |
count |
number | Hit count under the current search (+ other filters); may be 0 |
parent |
number | null | Parent category id, or 0 if root |
Counts include parent categories rolled up from each article’s category path. Use for category sidebar / facet UI. Resolve labels via categories[id].name (skip ids without a name).
Errors
| Status | Body |
|---|---|
| 400 | { "error": "Query parameter \"target\" is required" } |
| 401 | { "error": "Unauthorized" } |
| 500 | { "error": "..." } |
Example
const res = await fetch(
'http://localhost:4208/api/article/search?target=bizz%20allmix&filter=16&maxCount=10',
{ credentials: 'include' }
);
const { categories, length, recordset } = await res.json();