Booster panel je malá webová aplikace vytvořená v AYETO Booster Studiu. Panel může mít vlastní databázi a endpointy na této stránce umožňují vašemu serveru tuto databázi číst a měnit pomocí API klíče: importovat do panelu data, synchronizovat je s jiným systémem nebo zpracovávat, co zadali uživatelé panelu.
Všechny endpointy jsou pod /api/v3/booster/database/private/. Samotné panely se ke
své databázi dostávají samostatnou přístupovou cestou, kterou tato stránka nepopisuje.
Základní pojmy
Panely a jejich databáze
Každý panel má nejvýše jednu databázi. Existuje, když je nastavení panelu Přístup
k databázi (detaily panelu v aplikaci) Veřejná databáze nebo Soukromá
databáze; s volbou Bez databáze odpovídá každý endpoint na této stránce 403.
Přes toto API lze používat veřejný i soukromý režim. Databáze se vytvoří při prvním
použití a smaže se spolu s panelem.
Každý požadavek uvádí panel v hlavičce panel-id. ID panelu je zobrazeno, s tlačítkem
pro zkopírování, v horní části detailů panelu v aplikaci.
Kolekce a záznamy
Databáze obsahuje kolekce a kolekce obsahuje záznamy. Kolekce není třeba
vytvářet: kolekce existuje, jakmile má nějaký záznam. Názvy kolekcí smějí obsahovat
jen písmena, číslice a podtržítka (orders, contact_requests).
Záznam má právě dvě pole:
| Pole | Typ | Popis |
|---|---|---|
key |
UUID | Identifikátor záznamu, jedinečný napříč databázemi všech panelů (nejen v rámci jeho kolekce). |
value |
libovolný | Data, která jste uložili. Přijímá se jakákoli hodnota JSON; pokud chcete filtrovat nebo řadit podle jejích polí, použijte objekt. |
Záznamy nenesou žádná další metadata: odpovědi neobsahují název kolekce, časová
razítka ani autora. Pokud cokoli z toho potřebujete, uložte to do value.
Endpointy, které pracují s jedním záznamem (get, update, delete a jejich dávkové
varianty), ho adresují jen pomocí key; kolekce se vezme z uloženého záznamu.
Endpointy, které pracují s celou kolekcí (create, find, count, zámky), přijímají
název kolekce v těle.
{
"key": "8f14e45f-ceea-467a-9b1c-4e1f2a6b3c70",
"value": {
"customer": {"name": "Jana Nováková", "email": "jana@example.com"},
"status": "open",
"priority": 3,
"created_at": "2026-10-01T09:15:00Z"
}
}
Kdo má přístup k datům panelu
Požadavky se provádějí jménem uživatele, kterému API klíč patří. Tento uživatel musí:
- panel vlastnit (být jeho tvůrcem nebo členem skupiny, která ho vlastní, například administrátorů organizace, která panel dostala od partnera), nebo
- mít panel sdílený, přímo nebo prostřednictvím skupiny, do které patří.
Vlastníci a uživatelé, se kterými je panel sdílený (pro čtení nebo pro zápis), mohou databázi číst i do ní zapisovat, v obou režimech databáze: zápis do databáze se počítá jako používání panelu, ne jeho úprava (změna samotného panelu dál vyžaduje sdílení pro zápis). Členství v organizaci panelu samo o sobě přístup nedává, stejně jako administrátorské účty AYETO. API klíč musí také nést odpovídající rozsah:
| Rozsah | Endpointy |
|---|---|
ayeto.booster.database |
get, find, count |
ayeto.booster.database.write |
create, create-many, update, update-many, delete, delete-many, lock/acquire, lock/release |
Rozsah pro zápis nezahrnuje rozsah pro čtení; klíč, který čte i zapisuje, potřebuje oba.
Zápisy provedené přes toto API jsou zápisy do databáze panelu jako jakékoli jiné: spouštějí workflow se spouštěčem booster záznamu na daném panelu a spouštějí moduly panelu pro webhooky a e-mailová oznámení.
Pravidla kolekcí
Panel může definovat pravidla kolekcí, která určují, co smějí dělat anonymní návštěvníci panelu. Pravidla platí jen v režimu veřejné databáze; panel v soukromém režimu je ignoruje a každý endpoint na této stránce funguje na všech jeho kolekcích.
U panelu ve veřejném režimu je pro požadavky na této stránce důležitá jen jedna část pravidel:
- Operace nastavená pro kolekci (nebo pro pravidlo
*, které ji pokrývá) na none je zakázaná pro všechny, včetně tohoto API. Požadavek selže s403. - Každá jiná úroveň (public, secret, private) požadavky API povoluje.
- Kolekce bez odpovídajícího pravidla je pro API plně přístupná.
Omezení zápisu z pravidla (validační schéma, maximální velikost hodnoty, maximální počet záznamů) se na zápisy provedené přes toto API nepoužijí. Data validujte na své straně, než je zapíšete.
Limity
| Limit | Hodnota |
|---|---|
Záznamy vrácené jedním find |
při stránkování až 1000 (limit_to je nejvýše 1000, limit_from menší než 1000); bez poslaných limitů všechny odpovídající záznamy |
| Podmínky filtru v jednom dotazu | 1000, včetně podmínek uvnitř AND / OR |
Vnoření AND / OR |
100 úrovní |
Hodnoty v jedné podmínce in |
100 |
| Řetězcová hodnota filtru | 1000 znaků |
| Doba platnosti zámku | více než 0,1 s, výchozí 3600 s |
Dávkové endpointy nemají pevný maximální počet položek, ale každá položka se zapisuje zvlášť (viz Vytvoření více záznamů); udržujte dávky v rozsahu několika set položek, aby požadavek skončil s rezervou v rámci vašeho časového limitu HTTP.
Dotazy na záznamy
find a count přijímají volitelný objekt params. Jeho pole se řídí obecnými
konvencemi pro dotazy s rozdíly uvedenými zde.
| Pole | Typ | Povinné | Popis |
|---|---|---|---|
filters |
pole | ne | Podmínky, které musí platit všechny. Viz Filtry a níže. |
sort_key |
řetězec | ne | Pole, podle kterého se řadí: key nebo value.<field>. |
sort_order |
celé číslo | ne | 0 vzestupně (výchozí, když je nastaveno sort_key), 1 sestupně. |
limit_from |
celé číslo | ne | Index prvního vraceného záznamu, od 0, menší než 1000. |
limit_to |
celé číslo | ne | Index za posledním vraceným záznamem (ne počet), nejvýše 1000. Když se pošle jen limit_from, je to limit_from + 100 (nejvýše 1000). |
Pole, podle kterých lze filtrovat a řadit
Přijímají se jen dva druhy názvů polí:
key, klíč záznamu (porovnávejte ho s řetězcem UUID).value.<path>, pole uvnitř hodnoty záznamu, s tečkami pro vnořené objekty:value.status,value.customer.email.
Jakýkoli jiný název selže s 422. Záznamy, jejichž hodnota pole nemá (nebo není
objektem), prostě neodpovídají.
Podmínka je [field, operator, value] s operátory ==, !=, <, >, <=, >=,
regex (nikdy nerozlišuje velikost písmen) a in (hodnota je seznam, z něhož může
odpovídat kterákoli položka). Podmínky lze kombinovat pomocí {"AND": [...]}
a {"OR": [...]}; každá z těchto skupin potřebuje aspoň dvě podmínky a lze je
vnořovat.
{
"collection": "tickets",
"params": {
"filters": [
["value.status", "in", ["open", "waiting"]],
{"OR": [
["value.priority", ">=", 3],
["value.customer.email", "regex", "@example\\.com$"]
]}
],
"sort_key": "value.created_at",
"sort_order": 1,
"limit_from": 0,
"limit_to": 50
}
}
Na co myslet při filtrování podle hodnot:
- Typy se musí shodovat.
["value.priority", ">=", 3]neodpovídá uloženému"priority": "3". Čísla ukládejte jako čísla a data jako řetězce ISO 8601 nebo jako čísla, aby je<a>porovnávaly správně. - Řetězce, které vypadají jako UUID, zůstávají řetězci v podmínkách
value.*, takže UUID, které jste uložili jako text, se najde jako text. - Znaky
<,>,"a'v řetězcové hodnotě filtru se před porovnáním escapují, takže podmínka na text, který je obsahuje, neodpovídá. Řetězcová hodnota filtru také nesmí začínat na$.
Řazení a stránkování
Bez sort_key přicházejí záznamy od nejnovějších. S sort_key se řadí podle tohoto
pole.
limit_from a limit_to jsou pozice ve výsledku, takže druhá stránka po 50 je
"limit_from": 50, "limit_to": 100. Protože limit_to nemůže přesáhnout 1000,
stránkování pomocí limitů dosáhne jen na prvních 1000 odpovídajících záznamů. Chcete-li
pokračovat dál, stránkujte podle hodnoty: řaďte podle pole a filtrujte podle poslední
hodnoty, kterou jste dostali, například ["value.created_at", "<", "2026-09-30T12:00:00Z"]
s "sort_key": "value.created_at", "sort_order": 1.
Pokud nepošlete ani limit_from, ani limit_to, find vrátí všechny odpovídající
záznamy. Používejte to jen u kolekcí, o kterých víte, že jsou malé.
count použije filtry a ignoruje řazení a stránkování: vrací celkový počet
odpovídajících záznamů.
Společné hlavičky požadavků a chyby
Každý endpoint na této stránce potřebuje tyto hlavičky:
| Hlavička | Popis |
|---|---|
uni-api-key |
Váš API klíč. Viz Autentizace. |
panel-id |
ID panelu, k jehož databázi přistupujete. |
Content-Type |
application/json |
Chyby jsou JSON ve tvaru {"detail": "..."} (viz Chyby).
Tyto mohou přijít z každého endpointu:
| Stav | detail |
Příčina |
|---|---|---|
401 |
API key not provided / API key is invalid |
Klíč je prázdný, neznámý, vypnutý nebo mu chybí rozsah endpointu. |
403 |
permission denied |
Panel nevlastníte a ani s vámi není sdílený. |
403 |
database access is not allowed for this panel |
Přístup k databázi panelu je nastaven na Bez databáze. |
403 |
operation '<operation>' is disabled for collection '<collection>' |
Pravidlo kolekce panelu ve veřejném režimu nastavuje tuto operaci na none. Operace je create, read, update, delete, count nebo lock. |
404 |
panel not found |
Panel s tímto ID neexistuje, nebo je panel vypnutý. |
422 |
chyba validace | Hlavička panel-id chybí nebo není UUID, nebo tělo neodpovídá modelu požadavku. |
422 |
Collection name can only contain alphanumeric characters and underscores |
Neplatný název kolekce (Collection cannot be empty u prázdného). |
429 |
zpráva limitu požadavků | Příliš mnoho požadavků; počkejte dobu uvedenou v hlavičce Retry-After. Viz Limity požadavků. |
500 |
chyba serveru | Neočekávané selhání; zkuste to později. |
Vyhledání záznamů
Vrací záznamy kolekce, které odpovídají dotazu.
| Endpoint | POST /api/v3/booster/database/private/find |
| Rozsah | ayeto.booster.database |
| Limit požadavků | default |
Požadavek
| Pole | Typ | Povinné | Popis |
|---|---|---|---|
collection |
řetězec | ano | Název kolekce. |
params |
objekt | ne | Filtry, řazení a stránkování; viz Dotazy na záznamy. Bez něj se vrátí všechny záznamy kolekce, od nejnovějších. |
Odpověď
Pole záznamů (key, value). Neznámá nebo prázdná kolekce
vrací [].
Chyby
| Stav | detail |
Příčina |
|---|---|---|
422 |
Field '<field>' is not allowed for filtering or sorting |
Filtr nebo sort_key uvádí něco jiného než key nebo value.<path>. |
422 |
Each filter condition must be a list of [field, operator, value] |
Chybně utvořená podmínka. |
422 |
Operator '<operator>' is not allowed |
Neznámý operátor. |
422 |
'<AND/OR>' operator requires a list of at least 2 conditions |
Hodnota AND / OR není seznam aspoň dvou podmínek. |
422 |
Logical filter must have exactly one key ('AND' or 'OR') |
Chybně utvořená logická podmínka, např. {} nebo objekt s několika klíči. |
422 |
limit_from must be lower than 1000 |
limit_from 1000 nebo více (stránkování dosáhne jen na prvních 1000 záznamů). |
422 |
Maximum number of filter conditions is 1000 (including conditions inside AND/OR) |
Příliš mnoho podmínek. |
422 |
sort_order must be 0 (ASC) or 1 (DESC) |
Neplatné sort_order. |
422 |
limit_to cannot exceed 1000 |
limit_to nad 1000. |
422 |
limit_from cannot be greater than limit_to |
Obrácený rozsah. |
Příklady
curl -X POST "https://ayeto.ai/api/v3/booster/database/private/find" \
-H "uni-api-key: $AYETO_API_KEY" \
-H "panel-id: 3d2c5a8e-7b41-4f0e-9a6d-2c8b1e4f7a90" \
-H "Content-Type: application/json" \
-d '{
"collection": "tickets",
"params": {
"filters": [["value.status", "==", "open"]],
"sort_key": "value.priority",
"sort_order": 1,
"limit_from": 0,
"limit_to": 20
}
}'
[
{
"key": "8f14e45f-ceea-467a-9b1c-4e1f2a6b3c70",
"value": {
"customer": {"name": "Jana Nováková", "email": "jana@example.com"},
"status": "open",
"priority": 3,
"created_at": "2026-10-01T09:15:00Z"
}
},
{
"key": "c9f0f895-fb98-4b91-8f2a-6d3e5c1b0a47",
"value": {
"customer": {"name": "Petr Svoboda", "email": "petr@example.org"},
"status": "open",
"priority": 1,
"created_at": "2026-10-01T11:40:00Z"
}
}
]
Počet záznamů
Vrací počet záznamů kolekce, které odpovídají filtrům.
| Endpoint | POST /api/v3/booster/database/private/count |
| Rozsah | ayeto.booster.database |
| Limit požadavků | default |
Požadavek
| Pole | Typ | Povinné | Popis |
|---|---|---|---|
collection |
řetězec | ano | Název kolekce. |
params |
objekt | ne | Stejný objekt jako u Vyhledání záznamů. Výsledek ovlivňují jen filters; řazení a stránkování se validují, ale ignorují. |
Odpověď
Celé číslo.
Chyby
Chyby dotazu z Vyhledání záznamů.
Příklady
curl -X POST "https://ayeto.ai/api/v3/booster/database/private/count" \
-H "uni-api-key: $AYETO_API_KEY" \
-H "panel-id: 3d2c5a8e-7b41-4f0e-9a6d-2c8b1e4f7a90" \
-H "Content-Type: application/json" \
-d '{"collection": "tickets", "params": {"filters": [["value.status", "==", "open"]]}}'
42
Čtení záznamu
Vrací jeden záznam podle jeho klíče.
| Endpoint | POST /api/v3/booster/database/private/get |
| Rozsah | ayeto.booster.database |
| Limit požadavků | default |
Požadavek
| Pole | Typ | Povinné | Popis |
|---|---|---|---|
key |
UUID | ano | Klíč záznamu. |
Odpověď
Chyby
| Stav | detail |
Příčina |
|---|---|---|
404 |
Database record not found |
Databáze tohoto panelu nemá záznam s tímto klíčem. |
Příklady
curl -X POST "https://ayeto.ai/api/v3/booster/database/private/get" \
-H "uni-api-key: $AYETO_API_KEY" \
-H "panel-id: 3d2c5a8e-7b41-4f0e-9a6d-2c8b1e4f7a90" \
-H "Content-Type: application/json" \
-d '{"key": "8f14e45f-ceea-467a-9b1c-4e1f2a6b3c70"}'
{
"key": "8f14e45f-ceea-467a-9b1c-4e1f2a6b3c70",
"value": {
"customer": {"name": "Jana Nováková", "email": "jana@example.com"},
"status": "open",
"priority": 3,
"created_at": "2026-10-01T09:15:00Z"
}
}
Vytvoření záznamu
Přidá záznam do kolekce.
| Endpoint | POST /api/v3/booster/database/private/create |
| Rozsah | ayeto.booster.database.write |
| Limit požadavků | default |
Požadavek
| Pole | Typ | Povinné | Popis |
|---|---|---|---|
collection |
řetězec | ano | Název kolekce (písmena, číslice, podtržítka). Kolekce vznikne s prvním záznamem. |
value |
libovolný | ne | Data k uložení. Vynechání znamená null. |
key |
UUID | ne | Klíč nového záznamu. Když se vynechá, vygeneruje se; nesmí ho používat žádný existující záznam žádného panelu (jinak 422). |
Odpověď
Vytvořený záznam, včetně jeho key.
Chyby
| Stav | detail |
Příčina |
|---|---|---|
422 |
a record with key '<key>' already exists |
Klíč, který jste poslali, používá existující záznam (tohoto nebo jiného panelu). |
500 |
error creating database record |
Záznam se nepodařilo uložit (výjimečně, když dva požadavky vytvořily stejný klíč ve stejném okamžiku). |
Příklady
curl -X POST "https://ayeto.ai/api/v3/booster/database/private/create" \
-H "uni-api-key: $AYETO_API_KEY" \
-H "panel-id: 3d2c5a8e-7b41-4f0e-9a6d-2c8b1e4f7a90" \
-H "Content-Type: application/json" \
-d '{
"collection": "tickets",
"value": {
"customer": {"name": "Jana Nováková", "email": "jana@example.com"},
"status": "open",
"priority": 3,
"created_at": "2026-10-01T09:15:00Z"
}
}'
{
"key": "8f14e45f-ceea-467a-9b1c-4e1f2a6b3c70",
"value": {
"customer": {"name": "Jana Nováková", "email": "jana@example.com"},
"status": "open",
"priority": 3,
"created_at": "2026-10-01T09:15:00Z"
}
}
Vytvoření více záznamů
Přidá několik záznamů, případně do různých kolekcí.
| Endpoint | POST /api/v3/booster/database/private/create-many |
| Rozsah | ayeto.booster.database.write |
| Limit požadavků | default |
Požadavek
Tělo je pole JSON objektů stejného tvaru jako u
Vytvoření záznamu (collection, value, volitelný key).
Položky se zapisují jedna po druhé, v pořadí. Dávka není atomická: pokud položka
selže, požadavek vrátí chybu, záznamy před ní zůstanou vytvořené a položky za ní se
nezapíšou. Položka, jejíž key už existuje, zastaví dávku s 422. Před opakováním
neúspěšné dávky zkontrolujte, co se zapsalo, nebo posílejte vlastní klíče, abyste
poznali, které položky existují.
Odpověď
Pole vytvořených záznamů v pořadí požadavku.
Chyby
Chyby Vytvoření záznamu pro první položku, která selhala.
Příklady
curl -X POST "https://ayeto.ai/api/v3/booster/database/private/create-many" \
-H "uni-api-key: $AYETO_API_KEY" \
-H "panel-id: 3d2c5a8e-7b41-4f0e-9a6d-2c8b1e4f7a90" \
-H "Content-Type: application/json" \
-d '[
{"collection": "products", "key": "0b6e8c1a-5d2f-4e3b-9a7c-1f4d6e8a2b30", "value": {"sku": "MUG-01", "name": "Mug", "quantity": 12}},
{"collection": "products", "key": "5a9d3f2e-8c1b-4a6e-b7d0-3e2f1c9a8b54", "value": {"sku": "TEE-M", "name": "T-shirt M", "quantity": 40}}
]'
[
{"key": "0b6e8c1a-5d2f-4e3b-9a7c-1f4d6e8a2b30", "value": {"sku": "MUG-01", "name": "Mug", "quantity": 12}},
{"key": "5a9d3f2e-8c1b-4a6e-b7d0-3e2f1c9a8b54", "value": {"sku": "TEE-M", "name": "T-shirt M", "quantity": 40}}
]
Úprava záznamu
Nahradí hodnotu záznamu.
| Endpoint | POST /api/v3/booster/database/private/update |
| Rozsah | ayeto.booster.database.write |
| Limit požadavků | default |
Požadavek
| Pole | Typ | Povinné | Popis |
|---|---|---|---|
key |
UUID | ano | Klíč záznamu. |
value |
libovolný | ne | Nová hodnota. Uloženou hodnotu nahradí úplně; pole, která vynecháte, se odstraní. Vynechání znamená null. |
Chcete-li změnit jediné pole, přečtěte záznam, pole změňte a pošlete zpět celou hodnotu. Pokud mohou stejný záznam ve stejnou chvíli zapisovat i jiní klienti, dělejte to pod zámkem.
Odpověď
Upravený záznam.
Chyby
| Stav | detail |
Příčina |
|---|---|---|
404 |
Database record not found |
Databáze tohoto panelu nemá záznam s tímto klíčem. |
Příklady
curl -X POST "https://ayeto.ai/api/v3/booster/database/private/update" \
-H "uni-api-key: $AYETO_API_KEY" \
-H "panel-id: 3d2c5a8e-7b41-4f0e-9a6d-2c8b1e4f7a90" \
-H "Content-Type: application/json" \
-d '{
"key": "8f14e45f-ceea-467a-9b1c-4e1f2a6b3c70",
"value": {
"customer": {"name": "Jana Nováková", "email": "jana@example.com"},
"status": "closed",
"priority": 3,
"created_at": "2026-10-01T09:15:00Z"
}
}'
{
"key": "8f14e45f-ceea-467a-9b1c-4e1f2a6b3c70",
"value": {
"customer": {"name": "Jana Nováková", "email": "jana@example.com"},
"status": "closed",
"priority": 3,
"created_at": "2026-10-01T09:15:00Z"
}
}
Úprava více záznamů
Nahradí hodnoty několika záznamů.
| Endpoint | POST /api/v3/booster/database/private/update-many |
| Rozsah | ayeto.booster.database.write |
| Limit požadavků | default |
Požadavek
Tělo je pole JSON objektů stejného tvaru jako u
Úpravy záznamu (key, value). Položky se zapisují jedna po druhé,
v pořadí, a dávka není atomická: položka, která selže, požadavek zastaví a položky
před ní zůstanou upravené.
Odpověď
Pole upravených záznamů v pořadí požadavku.
Chyby
Chyby Úpravy záznamu pro první položku, která selhala.
Příklady
curl -X POST "https://ayeto.ai/api/v3/booster/database/private/update-many" \
-H "uni-api-key: $AYETO_API_KEY" \
-H "panel-id: 3d2c5a8e-7b41-4f0e-9a6d-2c8b1e4f7a90" \
-H "Content-Type: application/json" \
-d '[
{"key": "0b6e8c1a-5d2f-4e3b-9a7c-1f4d6e8a2b30", "value": {"sku": "MUG-01", "name": "Mug", "quantity": 10}},
{"key": "5a9d3f2e-8c1b-4a6e-b7d0-3e2f1c9a8b54", "value": {"sku": "TEE-M", "name": "T-shirt M", "quantity": 37}}
]'
[
{"key": "0b6e8c1a-5d2f-4e3b-9a7c-1f4d6e8a2b30", "value": {"sku": "MUG-01", "name": "Mug", "quantity": 10}},
{"key": "5a9d3f2e-8c1b-4a6e-b7d0-3e2f1c9a8b54", "value": {"sku": "TEE-M", "name": "T-shirt M", "quantity": 37}}
]
Smazání záznamu
Smaže jeden záznam.
| Endpoint | POST /api/v3/booster/database/private/delete |
| Rozsah | ayeto.booster.database.write |
| Limit požadavků | default |
Požadavek
| Pole | Typ | Povinné | Popis |
|---|---|---|---|
key |
UUID | ano | Klíč záznamu. |
Odpověď
null.
Chyby
| Stav | detail |
Příčina |
|---|---|---|
404 |
Database record not found |
Databáze tohoto panelu nemá záznam s tímto klíčem (i když už byl smazán). |
Příklady
curl -X POST "https://ayeto.ai/api/v3/booster/database/private/delete" \
-H "uni-api-key: $AYETO_API_KEY" \
-H "panel-id: 3d2c5a8e-7b41-4f0e-9a6d-2c8b1e4f7a90" \
-H "Content-Type: application/json" \
-d '{"key": "8f14e45f-ceea-467a-9b1c-4e1f2a6b3c70"}'
Smazání více záznamů
Smaže několik záznamů.
| Endpoint | POST /api/v3/booster/database/private/delete-many |
| Rozsah | ayeto.booster.database.write |
| Limit požadavků | default |
Požadavek
Tělo je pole JSON objektů s polem key, jako u
Smazání záznamu. Záznamy se mažou jeden po druhém, v pořadí;
položka, která selže (například klíč, který neexistuje), požadavek zastaví a záznamy
před ní zůstanou smazané.
Odpověď
null.
Chyby
Chyby Smazání záznamu pro první položku, která selhala.
Příklady
curl -X POST "https://ayeto.ai/api/v3/booster/database/private/delete-many" \
-H "uni-api-key: $AYETO_API_KEY" \
-H "panel-id: 3d2c5a8e-7b41-4f0e-9a6d-2c8b1e4f7a90" \
-H "Content-Type: application/json" \
-d '[
{"key": "0b6e8c1a-5d2f-4e3b-9a7c-1f4d6e8a2b30"},
{"key": "5a9d3f2e-8c1b-4a6e-b7d0-3e2f1c9a8b54"}
]'
Zámky
Zámky umožňují několika klientům (vašim serverům, samotnému panelu) střídat se nad stejnými daty. Zámek má dobu platnosti (TTL) a je jednoho ze dvou druhů:
- Zámek záznamu:
collectionakey. Použijte skutečnou kolekci záznamu; zámek vzatý pod jiným názvem kolekce záznam nechrání. - Zámek kolekce:
collectionbezkey.
Zámky jsou doporučující (advisory): server je nekontroluje. get, find, count,
create, update, delete a jejich dávkové varianty projdou bez ohledu na to, zda je
záznam nebo kolekce zamčená. Zámek jen přiměje ostatní volání lock/acquire na stejný
zámek čekat, takže data chrání jen tehdy, když si ho každý klient, který je zapisuje,
nejdřív vezme; koordinace je na panelu a vašem kódu.
- Zámky záznamů a kolekcí jsou nezávislé. Držení zámku kolekce nikomu nebrání vzít si zámek záznamu v ní, a naopak.
- Zámek může uvolnit kdokoli.
releaseuvolní zámek bez ohledu na to, kdo ho vzal, a druhéacquirezámku, který už držíte, čeká stejně jako u kohokoli jiného. Zámek uvolňujte jen z kódu, který ho získal. - Zámky vypršejí. Každý zámek se automaticky uvolní po uplynutí svého
ttl, i když nebyl nikdy uvolněn. Zvolte TTL delší, než trvá vaše práce, ale dost krátké na to, aby spadlý klient neblokoval ostatní dlouho.
Zamykání je operace lock v pravidlech kolekcí; oba endpointy
potřebují rozsah pro zápis a stejný přístup k panelu jako zápis.
Získání zámku
Vezme zámek záznamu nebo kolekce a počká, dokud nebude volný.
| Endpoint | POST /api/v3/booster/database/private/lock/acquire |
| Rozsah | ayeto.booster.database.write |
| Limit požadavků | default |
Požadavek
| Pole | Typ | Povinné | Popis |
|---|---|---|---|
collection |
řetězec | ano | Název kolekce. |
key |
UUID | ne | Klíč záznamu. Vynechte ho, chcete-li vzít zámek kolekce. |
acquire_timeout |
číslo | ne | Kolik sekund na zámek čekat. 0 selže okamžitě, když je zámek obsazený. Když se vynechá, požadavek čeká tak dlouho, jak je potřeba, nejvýše po zbývající TTL současného držitele; vždy pošlete hodnotu kratší, než je váš časový limit HTTP. |
ttl |
číslo | ne | Počet sekund, po kterých se zámek automaticky uvolní. Musí být větší než 0.1. Výchozí 3600. |
Odpověď
null, jakmile je zámek váš.
Chyby
| Stav | detail |
Příčina |
|---|---|---|
423 |
Failed to acquire lock for collection '<collection>' and key '<key>' |
Zámek zůstal obsazený po dobu acquire_timeout sekund (<key> je u zámku kolekce None). Zkuste to později. |
422 |
chyba validace | ttl je 0.1 nebo méně. |
Příklady
curl -X POST "https://ayeto.ai/api/v3/booster/database/private/lock/acquire" \
-H "uni-api-key: $AYETO_API_KEY" \
-H "panel-id: 3d2c5a8e-7b41-4f0e-9a6d-2c8b1e4f7a90" \
-H "Content-Type: application/json" \
-d '{"collection": "products", "key": "0b6e8c1a-5d2f-4e3b-9a7c-1f4d6e8a2b30", "acquire_timeout": 10, "ttl": 30}'
Uvolnění zámku
Uvolní zámek záznamu nebo kolekce bez ohledu na to, kdo ho drží.
| Endpoint | POST /api/v3/booster/database/private/lock/release |
| Rozsah | ayeto.booster.database.write |
| Limit požadavků | default |
Požadavek
| Pole | Typ | Povinné | Popis |
|---|---|---|---|
collection |
řetězec | ano | Název kolekce, jak byl poslán do lock/acquire. |
key |
UUID | ne | Klíč záznamu, jak byl poslán do lock/acquire. U zámku kolekce ho vynechte. |
Odpověď
null. Uvolnění zámku, který není obsazený (nebo už vypršel), také uspěje.
Příklady
curl -X POST "https://ayeto.ai/api/v3/booster/database/private/lock/release" \
-H "uni-api-key: $AYETO_API_KEY" \
-H "panel-id: 3d2c5a8e-7b41-4f0e-9a6d-2c8b1e4f7a90" \
-H "Content-Type: application/json" \
-d '{"collection": "products", "key": "0b6e8c1a-5d2f-4e3b-9a7c-1f4d6e8a2b30"}'
Čtení, úprava a zápis pod zámkem
update nahrazuje celou hodnotu, takže dva klienti, kteří každý přečtou záznam,
změní ho a zapíšou zpět, se mohou navzájem přepsat. Vezměte zámek záznamu kolem celé
této sekvence a uvolněte ho v bloku finally; totéž musí dělat každý klient, který
záznam zapisuje:
import os
import time
import requests
BASE_URL = "https://ayeto.ai/api/v3/booster/database/private"
HEADERS = {
"uni-api-key": os.environ["AYETO_API_KEY"],
"panel-id": "3d2c5a8e-7b41-4f0e-9a6d-2c8b1e4f7a90",
}
def call(path: str, body):
response = requests.post(f"{BASE_URL}/{path}", json=body, headers=HEADERS, timeout=30)
response.raise_for_status()
return response.json()
def change_stock(key: str, delta: int, attempts: int = 3) -> dict:
"""Add `delta` to the quantity of a product record without losing concurrent changes."""
lock = {"collection": "products", "key": key}
for attempt in range(attempts):
try:
# wait at most 10 s; the lock frees itself after 30 s if this process dies
call("lock/acquire", {**lock, "acquire_timeout": 10, "ttl": 30})
break
except requests.HTTPError as e:
if e.response.status_code != 423 or attempt == attempts - 1:
raise
time.sleep(2)
try:
record = call("get", {"key": key})
value = record["value"]
value["quantity"] = value.get("quantity", 0) + delta
return call("update", {"key": key, "value": value})
finally:
call("lock/release", lock)
print(change_stock("0b6e8c1a-5d2f-4e3b-9a7c-1f4d6e8a2b30", -2))