Web API - Zpracování požadavků v mezipaměti
Každý business object má endpoint /serverstate, přes který je možné posílat požadavky. Endpoint má jedinou povolenou metodu POST. Každý požadavek na tento endpoint se směřuje na stejné vlákno, které má každý uživatel jedno. Na tomto vlákně je jeho cache (dále mezipaměť). Případné požadavky pod stejným přihlášením se serializují.
Tato vlákna se alokují z jiného poolu než standardní požadavky. Pro konfiguraci tohoto poolu existují v konfiguračním souboru APIServer.yaml parametry sessionPoolSize a sessionTimeoutMs.
Pokud klient zašle v rámci stejných přihlašovacích údajů více požadavků současně, endpoint /serverstate je automaticky serializuje a zpracuje postupně.
POST {server}/{spojení}/{BO}/serverstate
Případně:
POST {server}/{spojení}/serverstate
Tento způsob je primárně určen pro práci s importními managery.
Tělo požadavku:
{
"cacheid": "<cacheid>",
"type": "<type>"
"breakiflocked": <breakiflocked>
"data": {
"object_id" = "<objid>",
"object_data" = <objdata>,
"query" = <query>,
"meta" : {
"validation": {
"errors": "<boolean>",
"warnings": "<boolean>",
"objectdataerrors": "<boolean>",
"queryerrors": "<boolean>"
},
"bodiff": {
"includeSource": "<boolean>",
"query": "<query_object>"
}
}
}
}
Vlastnost | Význam |
---|---|
|
Pomocí tohoto identifikátoru si uživatel může rozdělit mezipaměť do více prostorů. S každým z nich se pracuje nezávisle (pokud se ale naplní sessionTimeoutMs, odstraní se všechny mezipaměti na uživateli). Lze použít i prázdnou hodnotu. Povinná položka. |
|
Povinná položka. Aktuálně může obsahovat tyto hodnoty:
Po úspěšném provedení create, load nebo clone je objekt vložen do mezipaměti. Po úspěšném provedení save nebo discard je objekt uvolněn z keše. |
|
Nepovinná položka. Výchozí hodnota je false. Má smysl jen u operace typu load. Pokud je použito true, je aktivní pesimistické zamykání a business objekt je již zamknutý, provede se pokus o převzetí zámku. To se podaří, jen pokud má uživatel privilegium Opravovat záznamy, které již opravuje jiný uživatel. |
|
Object ID business objektu. Má smysl jen u typu operací load, clone, update a discard (buď identifikuje BO v databázi nebo v mezipaměti). |
|
Pomocí tohoto objektu se posílají změny na BO. Je možné jej použít u typu operací create, load, clone, update, save. Pokud se použije v souvislosti s operací, která vkládá BO do mezipaměti (create, clone, load) a během aplikace změn dojde k chybě, BO se z mezipaměti opět odstraní. Položka není povinná. Může se jednat o jeden objekt reprezentující změny BO ve stejném formátu, jako se posílá na běžné endpointy business objektů anebo pole těchto objektů. Pokud se jedná o pole, pak jsou změny aplikovány postupně (pokud dojde k chybě, aplikování se přeruší). |
|
Pomocí tohoto elementu lze specifikovat položky, které se mají vrátit. Protože se jedná o dotaz proti BO v mezipaměti, je v objektu podporovaná jen hodnota select. Položka je nepovinná a pokud se neuvede, vrací se všechny položky rozvinuté do první úrovně stejně, jako by se poslal dotaz na BO specifikovaný pomocí cesty /<BO>/<id>. |
|
Tato položka umožňuje definovat metainformace, které mají být vráceny.
Položku @temporaryid server generuje automaticky (pokud není zadaná uživatelem) a při operaci clone ve stavu na serveru se vygeneruje automaticky na základě ID zdrojového řádku. Operace stavu na serveru týkající se nových řádků tak lze zopakovat se stejným výsledkem. |
|
Položka Validation obsahuje tyto parametry:
Položka validation může být typu boolean nebo objekt. Pokud je typu boolen, nastaví se tato boolean hodnota na všechny podřízené parametry. Pokud je typu objekt, potom je možné specifikovat, které parametry chce uživatel vrátit. Příklad vstupu:
|
|
Tento objekt slouží k specifikaci požadavků pro sestavení rozdílů v business objektech (BO) před a po aplikaci změn. Obsahuje dva nepovinné parametry: includeSource a query. Parametr includeSource určuje, zda se mají ve výsledcích zahrnout i původní data použitá pro sestavení rozdílů. Pokud je nastaven na true, v odpovědi se objeví elementy before a after s výsledky dotazů před a po změně. Parametr query, který se zadává ve stejném formátu jako sekce data, umožňuje definovat specifický dotaz pro sestavení těchto rozdílů. Pokud není zadán, použije se pro sestavení rozdílů dotaz zadaný v sekci data. Výsledné rozdíly jsou vráceny ve formátu JSON Patch podle RFC 6902, což umožňuje efektivní zaznamenání a aplikaci změn na BO.
IncludeSource je zadáno jako true, takže se v odpovědi vrátí i výsledky dotazů použité pro sestavení rozdílů (používá se spíše pro ladící účely). Vlastní query je specifikováno tak, aby vrátila rozdíly za všechny položky objektu. |
Nejprve v mezipaměti vytvoříme novou fakturu vydanou.
Požadavek:
POST http://localhost:81/demodata/issuedinvoices/serverstate
Tělo požadavku:
{
"cacheid": "xb1",
"type": "create",
"data": {
"object_data": {
"firm_id": "F011000000",
"docqueue_id": "5600000101",
"storedocqueue_id": "P600000101",
"rows": [
{
"@temporaryid": "ID1",
"rowtype": 0,
"text": "testovaci radek",
"division_id": "2100000101"
},
{
"@temporaryid": "ID2",
"rowtype": 3,
"store_id": "2100000101",
"storecard_id": "2100000101",
"unitquantity": 10,
"unitprice": 20.5,
"division_id": "2100000101"
}
]
}
}
}
Odpověď je zapouzdřena v elementu data. Pro další práci s touto fakturou vydanou je třeba z elementu data získat objid nové FV a z kolekce rows dohledat skutečná objid řádků pomocí @temporaryid (které se klientovi vrací na výstup beze změny). V dalších příkladech jsou tato objid uvedena s prefixem NEW_.
V dalším kroku aktualizujeme popis na faktuře, upravíme existující řádek, další řádek smažeme a doplníme nový řádek.
Hodnoty objid, které začínají na NEW_, je, jak bylo řečeno výše, třeba získat z dat po předchozím kroku a doplnit tyto konkrétní hodnoty.
Požadavek:
POST http://localhost:81/demodata/issuedinvoices/serverstate
Tělo požadavku:
{
"cacheid": "xb1",
"type": "update",
"data": {
"object_id": "NEW_FV_OID",
"object_data": {
"description": "testovaci faktura",
"rows": [
{
"id": "NEW_ROW_OID_1",
"text": "zmena textu"
},
{
"@temporaryid": "ID4",
"rowtype": 0,
"text": "textovy radek c 2",
"division_id": "2100000101"
}
]
"rows@delete": {
"IncludeIDs": [NEW_ROW_OID_3]
}
}
}
}
V posledním kroku aktualizujeme položku unitquantity na řádku identifikovaném NEW_ROW_OID_2 a fakturu uložíme do databáze.
Požadavek:
POST http://localhost:81/demodata/issuedinvoices/serverstate
Tělo požadavku:
{
"cacheid": "xb1",
"type": "save",
"data": {
"object_id": "NEW_FV_OID",
"object_data": {
"rows": [
{
"id": "NEW_ROW_OID_2",
"unitquantity": 12
}
]
}
"query" = {
"select": [
"id"
]
}
}
}
V tomto příkladu provedeme import objednávky přijaté do dokladu Dodací list.
Mějme čerpatelnou objednávku přijatou s ID 15C0000101.
Požadavek:
POST http://localhost:81/demodata/billsofdelivery/serverstate
Tělo požadavku:
{
"cacheid": "xb1",
"type": "import",
"data": {
"import_data": {
"input_document_clsid": "01CPMINJW3DL342X01C0CX3FCC",
"output_document_clsid": "050I5SAOS3DL3ACU03KIU0CLP4",
"input_documents": "15C0000101",
"params": {
"docqueue_id": "P600000101"
}
},
"object_data": {},
"query": {
"select": [
"ID"
]
}
}
}
Status: 200 OK
Výsledek zpracování dotazu:
{
"data": {
"ID": "49F0000101",
"@meta": {
"version": 1
}
}
}
Typ import má povinnou položku import_data, kde jsou zadána data importu ve standardním formátu jako v obyčejném importu. V položce object_data je stejně jako u jiných typů (create, load atd.) možné zadat seznam změn výsledného objektu. Nad objektem je možné provádět query a validaci. Pokud je import zavolán na endpointu serverstate nad BO, potom clsid výstupního dokumentu musí odpovídat clsid tohoto BO.
Pokud je aktivní pesimistické zamykání, pak se business objekt před vložením do mezipaměti zamkne a při uvolnění z mezipaměti odemkne. Odemknutí proběhne i pokud je mezipaměť vyprázdněna v důsledku timeoutu neaktivity klienta.
Zámek lze převzít použitím breakiflocked s hodnotou true (viz výše). Toto zamykání a odemykání probíhá stejně jako u běžného uživatele.
Pokud se objekt nepodaří uzamknout, je vrácen status code 409. Pokud už objekt se stejným ID v mezipaměti je, operace load selže a vrátí status code 422.
Pokud u operací očekávající použití elementu object_id (update, save, discard) business objekt v keši není, vrátí se status 404.
V ostatních případech se vrací status 400 anebo případně další statusy, které se vracejí obecně (neexistující spojení, uživatel neautorizován apod).
Typicky pokud během používání série operací update dojde k vrácení status 404, znamená to, že rozeditovaný objekt byl z mezipaměti odstraněn (pravděpodobně v důsledku timeout a vyčištění mezipaměti, resp. odhlášení uživatele). V takovém případě je nutné objekt do mezipaměti znovu založit (create, load, clone), a pokud si klient udržuje průběžně posílané změny, tak tyto změnu znovu poslat. Pro tento případ je možné s výhodou využít toho, že operace create, load, clone a update dokáží kromě jednoho požadavku zpracovat i pole požadavků, takže je možné je poslat najednou.
Pokud při zpracování požadavku nedojde k chybě, je vždy vrácen status 200.