Typové príklady základného dopytovania Web API (Query String)
Ďalej sú uvedené príklady pre základné dopytovanie - query string (parametre URL).
Klauzula select slúži na výber polí BO, ktoré budú vrátené vo výsledku dopytu.
Výber kolekcie faktúr, každý objekt faktúry bude obsahovať field ID a field DisplayName, ktorý bude premenovaný na DocNumber.
Týmto spôsobom je možné do výsledku zahrnúť aj používateľské alebo neperzistentné fieldy business objektu. Avšak neperzistentné fieldy BO odporúčame používať len v krajných prípadoch, pri ich výbere dochádza k degradácii výkonu.
GET http://localhost/data/issuedinvoices?select=ID,DisplayName+as+DocNumber
Všimnite si, že namiesto medzier je napísané +. Alternatívne by bolo možné medzeru zakódovať ako %20. (Ide o URL kódovanie, viď Základné dopytovanie - query string (parametre URL) Jednotlivé fieldy sú oddelené čiarkou.
Výber kolekcie faktúr, každý objekt faktúry bude obsahovať všetky perzistentné fieldy a používateľské položky business objektu.
GET http://localhost/data/issuedinvoices?select=*
Výber kolekcie faktúr, každý objekt faktúry bude obsahovať čiastku (Amount) a názov firmy, na ktorú je faktúra vystavená (Firm_ID.Name). Prvý variant vráti názov firmy v JSON vlastnosti s názvom "Firm_ID.Name", rovnakým názvom, aký bol použitý pre jeho výber. V druhom variante je vidieť, ako možno field premenovať pomocou konštrukcie as (výsledná JSON vlastnosť sa bude volať "FirmName").
GET http://localhost/data/issuedinvoices?select=Amount,Firm_ID.NameGET http://localhost/data/issuedinvoices?select=Amount,Firm_ID.Name+as+FirmName
Výber kolekcie faktúr, každý objekt faktúry bude obsahovať fieldy ID a DisplayName, ktorý je tentoraz zložený pomocou polí načítaných z previazaných objektov. Ide o rýchlejší variant než je uvedený v prvom príklade, v ktorom je použitá neperzistentná položka (DisplayName); ako už bolo spomenuté vyššie, neperzistentné položky znamenajú degradáciu výkonu (pri ich použití dochádza k načítaniu BO). Všimnite si operátor || slúžiaci na spájanie reťazcov.
GET http://localhost/data/issuedinvoices?select=ID,DocQueue_ID.Code||'-'||OrdNumber||'/'||Period_ID.Code+as+DocNumber
Klauzula where slúži na obmedzenie vyberaných dát. Jej hodnotou je výraz, ktorý vracia booleovskú hodnotu. Vo výrazoch je možné využívať nasledujúce operátory na porovnávanie:
Výrazy je možné kombinovať pomocou logických operátorov (log. operátory viď tabuľka nižšie). Poradie vykonávania operácií možno určovať pomocou zátvoriek.
Výber kolekcie faktúr, vybrané sú iba faktúry s čiastkou väčšou ako 10000.
GET http://localhost/data/issuedinvoices?select=Amount,Firm_ID.Name+as+FirmName&where=Amount+gt+10000
Výber kolekcie faktúr, vybrané sú iba faktúry, ktoré majú čiastku väčšiu ako 10000 a zároveň sa Firm_ID nerovná '1100000101'.
GET http://localhost/data/issuedinvoices?select=Amount,Firm_ID.Name+as+FirmName&where=Amount+gt+10000+and+Firm_ID+ne+'1100000101'
Ukážka práce s dátumovými hodnotami. Ak potrebujeme získať príjemky vystavené 2. 8. 2018 o 6:00 alebo neskôr, môžeme na vyjadrenie dátumu a času použiť alternatívne zápis vo formáte ISO 8601
GET http://localhost/data/receiptcards?select=DisplayName&where=CreatedAt$DATE+ge+timestamp'2018-08-02T06:00:00'
alebo číselný formát OLE (Excel)
GET http://localhost/data/receiptcards?select=DisplayName&where=CreatedAt$DATE+ge+43314.25
s rovnakým výsledkom.
Uvádzanie hodinových a minútových údajov je v oboch prípadoch nepovinné. 2. 8. 2018 je tak možné vyjadriť ako '2018-08-08' (ISO) alebo 43314 (OLE).
Ak v zápise explicitne neuvediete časové pásmo, predpokladá sa, že máte na mysli lokálny čas. Rovnakú požiadavku by bolo možné zaslať aj s uvedením časového pásma, napr.
GET http://localhost/data/receiptcards?select=DisplayName&where=CreatedAt$DATE+ge+'2018-08-02T06:00:00+01:00'
Vyššie uvedené príklady sa týkajú zápisu dátumu a času v odosielaných požiadavkách. Pri práci s Web API sú avšak časové údaje obsiahnuté aj v odpovediach na požiadavky, v ktorých sú časové údaje vracané ako UTC (koordinovaný svetový čas) vo formáte ISO 8601 vrátane špecifikácie časového pásma, tj. napríklad 2018-08-02T05:00:00.000Z.
Výnimkou je používanie agregačných funkcií, keď sa agregované časové údaje vracajú v číselnom formáte OLE (Excel). Viď príklad platnosti cenníkov v kapitole Knihovna praktických příkladů Web API.
S touto skutočnosťou je potrebné počítať a na spracovanie dátumových a časových údajov ideálne využívať nejakú štandardnú knižnicu, ktorá korektne interpretuje časové pásma.
Ak používate triedu java.time.format.DateTimeFormatter (Java 8 alebo novší), môžete využiť preddefinovaný formát ISO_INSTANT.
Úplne nevhodné je spracovávať vrátené hodnoty iba reťazcovými funkciami, ako si ukážeme na príklade:
Hodnota 2019-02-10T23:00:00.000Z (vrátená v odpovedi na zaslanú požiadavku) zodpovedá miestnemu času 2019-02-11T00:00:00.000. Ak sa pokúsite oddeliť dátum prostým odrezaním prvých 10 znakov z vráteného reťazca, získate mylnú informáciu (dátum o 1 deň starší, než je v skutočnosti).
Od verzie 22.1.9 už nie je nutné pred uvedením času používať kľúčové slovo timestamp.
Od verzie 23.1. sú dátumové položky s hodnotou 0 v API namiesto ISOStringu vrátené s hodnotou null. Hodnota null je zároveň použiteľná v klauzule where a vyhodnocuje sa ako 0.
V starších verziách ABRA Gen nebol údaj o časovom pásme v odpovediach uvádzaný, čo mohlo v určitých situáciách viesť k nejednoznačnostiam (pri práci s rôznymi časovými pásmami alebo prechodmi zo štandardného času na letný a späť):
Požiadavka (ľubovoľná verzia ABRA Gen):
GET http://localhost/data/issuedinvoices?where=id+eq+'3400000101'&select=docdate$date
Odpoveď vo verzii ABRA Gen 19.x alebo novšej:
[
{
"docdate$date": "2006-01-24T23:00:00.000Z"
}
]
Odpoveď vo verzii ABRA Gen 18.x alebo staršej (rovnaké dáta):
[
{
"docdate$date": "2006-01-25T00:00:00.000"
}
]
Ukážka obmedzenia za skladové menu Hardware - vypíše menu Hardware a všetkých jeho potomkov:
GET http://localhost:80/demo/storemenuitems?select=text&where=id in (tree 'parent_id' where text eq 'hardware')
Ukážka obmedzenia za skladové menu Hardware (prvé ID) a služby (druhé ID) a všetkých ich potomkov (ilustruje použitie logickej podmienky or, ale rovnakú službu urobí podmienka in s oboma ID):
GET http://localhost:80/demo/storemenuitems?select=text&where=id in (tree 'parent_id' where id eq '2000000101' or id eq '4000000101')
Ukážka obmedzenia skladových kariet> za menu Hardware všetky jeho potomky:
GET GET http://localhost:80/demo/storecards?select=storemenuitem_id.text,code,name&where=storemenuitem_id in (tree 'parent_id' where text eq 'hardware')
Za hardware a služby by to bolo obdobne ako vyššie - podmienky v segmente tree sa vždy týkajú stromového číselníka, resp. stanovenia základnej úrovne, ku ktorej sa dopočítajú podriadené úrovne podľa väzbovej položky. Ak chceme filtrovať za všetko, tak do where tree časti stačí dať podmienku parent_id eq null (prípadne inú, ktorá vráti najnadradenejšie uzly, tzn. tie, ktoré nemajú parent_id).
Ak nie je potrebné obmedzovať, tak je lepšie podmienku vôbec nepoužiť.
Ukážka filtrovania za firmu a jej predchodcov. Toto je potrebné vykonať cez rozšírený dopyt, pretože štandardný endpoint firms navyše vkladá podmienku za Firm_ID rovné null.
POST http://localhost:80/demo/query
{
"class": "firms",
"select": ["name", "id", "firm_id"],
"where": "id in (tree 'firm_id' where firm_id eq null and name like 'Oracle*')",
}
Odpoveď:
POST http://localhost:80/demo/query
[
{
"name": "Oracle Czech s.r.o.",
"id": "4600000101",
"firm_id": null
},
{
"name": "Aktis a.s.",
"id": "M000000101",
"firm_id": "4600000101"
}
]
Aktuálne je podmienka riešená využitím common table expression výrazov. Pri konštrukcii sa interne skladá aj Path cesta a kontroluje sa zacyklenie. Tzn. že aj v prípade chybného vstupu (cyklickej tree štruktúry) dopyt nespôsobí zamrznutie.
Klauzula expand slúži na rozvíjanie odkazovaných BO a kolekcií BO. Používa sa vtedy, ak chceme jedným dopytom získať business objekt vrátane BO, ktoré sú s ním prepojené (typicky fieldy, ktorých názov končí na "_ID"). Môže ísť o jednotlivé objekty alebo ich kolekcie (typicky Rows - riadky dokladu). Využiť možno aj vnorený expand, keď možno kolekcie a referencie rozvíjať vnorene. V klauzule expand možno aj kombinovať klauzulu selectschema
Ak chceme pri použití expand použiť aj iné než rozvíjané objekty, je nutné ich uviesť v klauzule select.
Výber kolekcie vydaných faktúr, každá faktúra obsahuje sumu (Amount) a celý objekt firmy (Firm_ID), na ktorú bola vystavená.
GET http://localhost/data/issuedinvoices?select=Amount&expand=Firm_ID
Výber kolekcie vydaných faktúr, každá faktúra obsahuje sumu (Amount) a objekt firmy (Firm_ID), na ktorú bola vystavená - objekt firmy obsahuje iba fieldy špecifikované v zátvorkách za názvom fieldu v klauzule expand. Vyberané fieldy možno premenovávať pomocou operátora as, rovnako ako v klauzule select.
GET http://localhost/data/issuedinvoices?select=Amount&expand=Firm_ID(ID, Code, Name)
Ide o skrátenú formu zápisu, rovnaký výsledok možno dosiahnuť nasledovne:
GET http://localhost/data/issuedinvoices?select=Amount&expand=Firm_ID(select ID, Code, Name)
Výber kolekcie vydaných faktúr, každá faktúra obsahuje sumu (Amount), celý objekt firmy (Firm_ID), na ktorú bola vystavená, a kolekciu riadkov faktúry (Rows).
GET http://localhost/data/issuedinvoices?select=Amount&expand=Firm_ID, Rows
Výber kolekcie faktúr vydaných, pričom každá faktúra obsahuje ID a podmnožinu kolekcie riadkov faktúry (Rows) obmedzenú na riadky typu 3 (skladové). Navyše sú vrátené iba špecifikované fieldy - ID, typ riadka a suma).
GET http://localhost/data/issuedinvoices?select=id&expand=Rows(select ID, RowType, TotalPrice where RowType eq 3)
Výber kolekcie faktúr vydaných, pričom každá faktúra obsahuje ID a podmnožinu kolekcie riadkov faktúry (Rows) obmedzenú na riadky typu 3 (skladové). Sú vrátené iba špecifikované fieldy - ID, typ riadka a suma). Riadky sú navyše zoradené v rovnakom poradí ako na doklade.
GET http://localhost/data/issuedinvoices?select=id&expand=Rows(select ID, RowType, TotalPrice where RowType eq 3 orderby PosIndex)
Radenie môže byť aj zostupné:
http://localhost/data/issuedinvoices?select=id&expand=Rows(select ID, RowType, TotalPrice where RowType eq 3 orderby PosIndex desc)
Výber kolekcie faktúr vydaných, pričom každá faktúra obsahuje ID a podmnožinu kolekcie riadkov faktúry (Rows) obmedzenú na riadky typu 3 (skladové). Sú vrátené iba špecifikované fieldy - ID, typ riadka a suma. Riadky sú zoradené v rovnakom poradí ako na doklade. Pri skladových kartách na riadkoch chceme navyše získať ich ID, kód a názov.
GET http://localhost/data/issuedinvoices?select=id&expand=Rows(select ID, RowType, TotalPrice where RowType eq 3 orderby PosIndex), Rows.StoreCard_ID(select ID, Code, Name)
V príklade je opakovane využitý vnorený expand na niekoľkých úrovniach.
GET http://localhost/data/storecards?expand=storeunits(expand storeeans(expand parent_id))
V príklade je okrem expand využitá aj klauzula selectschema
GET http://localhost/data/storecards?expand=storeunits(selectschema persistent)
Klauzula selectschema je query parameter pomocou ktorého možno ovplyvniť rovnako ako v rozšírenom dopytovaní množinu vracaných položiek. Využiť možno parametre id, persistent, full a expanded
Príklad použitia selectschema na získanie ID nad skladovými kartami:
GET http://localhost/data/storecards?selectschema=id
Klauzula groupby slúži na agregáciu dát rovnakým spôsobom ako v SQL.
Výber kolekcie vydaných faktúr, každý objekt faktúry obsahuje sumu ("Sum(Amount)") agregovanú podľa firiem, na ktoré boli faktúry vystavené ("Firm_ID").
GET http://localhost/data/issuedinvoices?select=Sum(Amount),Firm_ID&groupby=Firm_ID
Výber kolekcie faktúr vydaných, každý objekt faktúry obsahuje sumu ("Sum(Amount)") agregovanú podľa firiem, na ktoré boli faktúry vystavené - Firm_ID obsahuje kompletný objekt firmy.
GET http://localhost/data/issuedinvoices?select=Sum(Amount)&groupby=Firm_ID&expand=Firm_ID
Ukážka použitia funkcie Floor, vracia pre kladné čísla celú časť, pre záporné tiež celú, ale smerom od nuly.
GET http://localhost/data/issuedinvoices?select=Sum(Amount),Firm_ID&groupby=Firm_IDGET http://localhost/data/issuedinvoices?select=Sum(Amount),Firm_ID&groupby=Firm_ID
Klauzula orderby slúži na zoradenie výstupu rovnakým spôsobom ako v SQL.
Výber kolekcie faktúr vydaných, každý objekt faktúry obsahuje sumu (Amount) a objekt firmy, na ktorú je faktúra vystavená (Firm_ID). Dáta sú zoradené podľa sumy (predvolené je vzostupné zoradenie).
GET http://localhost/data/issuedinvoices?select=Amount&expand=Firm_ID(ID,Code,Name)&orderby=Amount
Výber kolekcie faktúr vydaných, každý objekt faktúry obsahuje sumu (Amount) a objekt firmy, na ktorú je faktúra vystavená (Firm_ID). Faktúry sú zoradené podľa kódu firmy, na ktorú sú vystavené, a následne podľa sumy. Radiť je možné aj podľa polí odkazovaných objektov, a tiež viacerých polí všeobecne.
GET http://localhost/data/issuedinvoices?select=Amount&expand=Firm_ID(ID,Code,Name)&orderby=Firm_ID.Code,Amount
Výber kolekcie vydaných faktúr, každý objekt faktúry obsahuje sumu (Amount) a objekt firmy, na ktorú je faktúra vystavená (Firm_ID). Faktúry sú radené podľa kódu firmy, na ktorú sú vystavené vzostupne, a následne podľa sumy zostupne.
GET http://localhost/data/issuedinvoices?select=Amount&expand=Firm_ID(ID,Code,Name)&orderby=Firm_ID.Code,Amount+desc
Klauzuly skip a take slúžia na obmedzovanie počtu vybraných záznamov. Typickým využitím je stránkovanie výpisu výsledkov. Klauzula skip udáva, koľko záznamov sa má preskočiť, klauzula take počet záznamov, ktoré sa majú vrátiť.
Klauzuly skip a take je vhodné kombinovať s klauzulou orderby, ktorá zaistí jednoznačné poradie vypisovaných záznamov.
Výber kolekcie stredísk s obmedzením na účely stránkovania výpisu. Prvá požiadavka vráti prvých desať stredísk (zoradených podľa kódu), druhá požiadavka ďalších desať stredísk atď.
GET http://localhost/data/divisions?select=code,name&orderby=code&skip=0&take=10
GET http://localhost/data/divisions?select=code,name&orderby=code&skip=10&take=10
...
Podobný príklad nájdete v zbierke príkladov pod názvom Výber skladových kariet s obmedzením počtu vrátených záznamov.
Na získanie kompletnej cesty pri číselníkoch podporujúcich stromovú štruktúru slúži funkcia treepath(<tree field>, <tree expression>). Okrem cesty je možné využiť aj triedenie pomocou aliasu položky.
Funkciu možno použiť v časti select ako url, tak rozšíreného dopytovania pomocou post query. V rámci tabuľky, nad ktorou sa cesta vytvára(teda v ktorej je definovaná tree položka), možno za výraz aj radiť. Ak sa použije v klauzule expand alebo obdobne v rozšírenej verzii, tak radiť nemožno (v tomto prípade sa totiž expand dopyty spúšťajú ako samostatné subdopyty).
Aby bolo možné pomocou výrazu radiť správne, boli doplnené funkcie lpad a rpad. Tie sú tiež všeobecné a dajú sa použiť aj na iné položky. Prvý parameter je výraz, ktorý sa má doplniť na požadovanú dĺžku, druhý parameter je požadovaná dĺžka a tretí vlastný pad reťazec.
Vypíše všetky dostupné cesty k skladovému menu.
GET http://localhost:80/demo/storemenuitems?select=treepath(Parent_ID, '/' || text) as path&orderby=path&take=5&skip=10"
Odpoveď:
[
{
"path": "/Hlavná činnosť/Služby"
},
{
"path": "/Hlavná činnosť/Služby/Servis"
},
{
"path": "/Hlavná činnosť/Služby/Účtovné služby"
},
{
"path": "/Hlavná činnosť/Služby/Školenie"
},
{
"path": "/Hlavná činnosť/Softvér"
}
]
Získanie skladového menu triedeného podľa posindex - pre správnosť triedenia je posindex doplnený pomocou lpad na rovnakú dĺžku.
GET http://localhost:80/demo/storemenuitems?select=text,treepath(Parent_ID, '/' || lpad(posindex, 5, ' ')) as path&orderby=path&take=5&skip=10
Odpoveď:
[
{
"text": "Softvér",
"path": "/ 1/ 2"
},
{
"text": "ERP",
"path": "/ 1/ 2/ 1"
},
{
"text": "OS",
"path": "/ 1/ 2/ 2"
},
{
"text": "Ostatné",
"path": "/ 1/ 2/ 3"
},
{
"text": "Služby",
"path": "/ 1/ 3"
}
]
Získanie cesty v skladovom menu k skladovej karte pomocou klauzuly expand.
GET http://localhost:80/demo/storecards?select=code,name&expand=storemenuitem_id(select text, treepath(Parent_ID, '/' || text) as path)&where=code eq '48'
Odpoveď:
[
{
"code": "48",
"name": "HDD Seagate 1 TB",
"storemenuitem_id": {
"text": "Počítač.komponenty",
"path": "/Hlavná činnosť/Hardware/Počítač.komponenty"
}
}
]
Získanie skladového menu triedeného podľa posindex pomocou rozšíreného dopytovania na endpoint /query.
Telo
body = {
"class": "storemenuitems",
"select": [
{
"name": "path",
"value": "treepath(parent_id, '/' || lpad(posindex, 3, '0'))",
},
],
"orderby": ["path"],
"take": 5,
"skip": 10,
}
Odpoveď:
[
{
"path": "/001/002"
},
{
"path": "/001/002/001"
},
{
"path": "/001/002/002"
},
{
"path": "/001/002/003"
},
{
"path": "/001/003"
}
]
Získanie cesty v skladovom menu k skladovej karte pomocou rozšíreného dopytovania na endpoint /query.
Telo:
body = {
"class": "storecards",
"select": [
{
"name": "storemenuitem_id",
"value": [{"name": "path", "value": "treepath(Parent_ID, ' / ' || text)"}],
},
],
"where": "code='48'",
}
Odpoveď:
[
{
"storemenuitem_id": {
"path": " / Hlavná činnosť / Hardvér / Počítač.komponenty"
}
}
]