Book Contents

Book Index

Úvod

K2 API v2 je webová aplikace, která zpřístupňuje data a funkce informačního systému K2 dalším aplikacím. Komunikuje s aplikačním serverem K2 (AS) a přes něj umožňuje číst, vytvářet a měnit data, získávat popis jejich struktury, spouštět skripty a sestavy a využívat další specializovaná rozhraní – například pro napojení e-shopu.

Díky K2 API lze propojit K2 s okolním světem, aniž by externí aplikace musela znát vnitřní strukturu databáze nebo běžet jako klient K2. Všechny požadavky přitom procházejí stejnou aplikační logikou jako práce v K2 – uplatňují se uživatelská práva, kontroly při ukládání i business pravidla.

Webové služby jsou založeny na architektuře REST. Komunikace probíhá protokolem HTTP (HTTPS) pomocí standardních metod (GET pro čtení, POST pro vytváření a spouštění operací, PUT pro změnu dat). Pro výměnu dat se používá výhradně formát JSON.

K2 API v2 je nástupcem původního K2 API. Funkčně mu odpovídá a v řadě oblastí jej rozšiřuje, je ale postaveno na nové technologii, která přináší možnost provozu i mimo Windows, moderní způsob autentizace a lepší práci s chybami.

K čemu K2 API slouží

Typické scénáře využití:

Dokumentace konkrétní instance

Po zadání kořenové adresy K2 API do prohlížeče se zobrazí úvodní stránka s informací o verzi a odkazem na interaktivní dokumentaci. Dokumentace je generována ze specifikace OpenAPI (Swagger) a odpovídá nainstalované verzi K2 API. Lze v ní procházet dostupné služby a operace, struktury požadavků a odpovědí i ukázkové příklady a přímo z prohlížeče zkoušet jednotlivá volání.

pic_8304

Obrázek:

Příklad pro demo instanci:

Specifikaci OpenAPI lze použít pro automatické vygenerování klienta v libovolném programovacím jazyce, případně ji importovat do nástrojů pro testování API (Postman, Insomnia apod.).

Tip: Zobrazení úvodní stránky znamená, že běží K2 API. Zda je dostupný i aplikační server K2, ověříte voláním GET /system/ping – vrací stav 200, pokud je k dispozici alespoň jeden aplikační server.

Book Contents

Book Index

Co je nového oproti původnímu K2 API

Možnosti nového API zůstávají obdobné jako u původního K2 API. Hlavní rozdíly shrnuje tabulka:

Oblast

Původní K2 API

 

K2 API v2

Provozní prostředí

Pouze Windows, IIS (ASP.NET, WCF)

Windows v IIS nebo Linux v Docker kontejneru

Formát dat

XML nebo JSON

Pouze JSON

Autentizace

HMAC podpis požadavku

HMAC podpis požadavku nebo JWT token (access + refresh token)

Odpovědi a chyby

Data bez jednotné obálky; chyby jako text [ErrorKind]ErrorText, chyby deserializace jako HTML stránka

Každá odpověď v jednotné obálce JSON se stavovým kódem, chybovou zprávou a seznamem chyb; standardní HTTP stavové kódy

Kontextové informace

Pouze jazyk, RID e-shopu

HTTP hlavičky pro jazyk, vlastní firmu, informační sklad, období, měnu a další

Čtení seznamů

Sekvenční stránkování pomocí URL další/předchozí stránky

Sekvenční stránkování a nově i přímý přístup na libovolnou stránku včetně celkového počtu záznamů

Filtrování

Podmínky v parametru conditions, uložený filtr v K2

Podmínky v parametru conditions, uložený filtr v K2, strukturované podmínky (AND/OR, podmínky na položky)

Dokumentace

Dynamická nápověda WCF

OpenAPI (Swagger) s příklady a možností vyzkoušet volání

Komunikační protokol API - AS

Pojmenované trubky

TCP spojení

Z dalších novinek:

Upozornění pro přechod z původního API: Změnila se struktura požadavků a odpovědí (jednotná obálka, pojmenování vlastností JSON, adresy služeb) a odpadla podpora XML. Stávající integrace proto nelze na K2 API v2 jen přesměrovat – je potřeba je upravit podle OpenAPI specifikace.

Book Contents

Book Index

Architektura a nasazení

K2 API v2 je samostatná webová aplikace, která stojí mezi klientskými aplikacemi a aplikačním serverem K2. Klient posílá požadavky na K2 API, to je předá aplikačnímu serveru ke zpracování a výsledek vrátí klientovi ve formátu JSON. Klient tak nikdy nekomunikuje přímo s aplikačním serverem ani s databází.

Varianty provozu

Postup instalace a konfigurace jednotlivých variant je popsán v kapitole K2 API v2

Doporučené nasazení pro přístup z internetu

Aplikační server K2 by měl být vždy instalován na serveru dostupném pouze z vnitřní sítě. K2 API (stejně jako další webové aplikace) je doporučeno provozovat na samostatném serveru nebo v kontejneru, který je dostupný z internetu a do vnitřní sítě má povolenou pouze komunikaci s aplikačním serverem K2. K2 API tedy typicky bývá umístěno v DMZ. Pro přístup z internetu používejte vždy zabezpečený protokol HTTPS.

Licence a uživatelé

Požadavky K2 API zpracovává aplikační server K2. Pro provoz je proto potřeba mít v licenci K2 odpovídající počet vláken K2 API a správně nakonfigurovaný aplikační server.

AS3USER='AN'
AS3PASSWORD='ANPassword'
AS3USERS=5
AS3IO=2000034152

Požadavky na síťovou komunikaci

K2 API v2 komunikuje s aplikačním serverem pomocí TCP protokolu. Aplikační server tedy musí být konfigurován pro provoz na TCP protokolu a zvolený TCP port musí být povolen na všech firewallech mezi serverem s K2 API a serverem s K2 AS.

Příklad obsahu konfiguračního souboru K2.INI u AS:

AS3SERVERPROTOCOLS=3 ; AS naslouchá jak na pojmenovaných trubkách, tak na TCP

AS3SERVERPORT=10010 ; číslo TCP portu, na kterém AS naslouchá

Parametry konfiguračního souboru

K2 API v2 má veškeré konfigurační parametry uvedeny v konfiguračním souboru appsettings.json.

{

  "AutomaticHttpsRedirect": true,

  "Authentication": "UrlHash", // Type of authentication: UrlHash, JWT, RequestChoice, Disabled

  "AuthenticationSessionLifetime": 10, // Lifetime of logged user session

  "AuthenticationJwt": { // JWT configuration

    "SecretKey": "{112AXXXX-XXXX-XXXX-XXXX-F98BC9BXXXX}",

    "ValidateIssuerSigningKey": true,

    "ValidateTokenLifetime": true,

    "ValidateIssuer": true,

    "ValidateAudience": true,

    "ValidIssuer": "K2API",

    "ValidAudience": "public"

  },

  "ASClient": { // AS server configuration

   
"ForwardASGeneralExceptions": false, // Forward general AS exceptions to API client

    "BalancerConfig": {

      "PeriodicCheckTimer": 1,

      "Multipliers": {

        "SystemCPUAvg": 1,

        "SystemFreeMemory": -1,

        "AppPoolSpandAvg": 1,

        "AppNCLSessions": 1,

        "AppAnonymousSessions": 1,

        "AppSchedulerSessions": 1

      }

    },

    "Servers": [

      {

        "ServerName": "127.0.0.1",

        "Port": 55000

      }

    ]

  }

}

Vybrané důležité parametry:

Parametr

Výchozí hodnota

Význam

AutomaticHttpsRedirect

true

true – přesměrovávat provoz z HTTP na zabezpečené HTTPS

Authentication

RequestChoice

Povolený režim autentizace API požadavků. Možné hodnoty:

UrlHash – pouze původní HMAC hash

JWT – pouze pomocí JWT tokenu

RequestChoice – povolen jak HMAC hash, tak JWT. Rozlišení podle podoby HTTP hlavičky Authorization (prefix Bearer – JWT token, bez prefixu HMAC hash)

Disabled – autentizace není vyžadována, pouze pro ladící účely!

AuthenticationSessionLifetime

10

Délka platnosti uživatelské session po autorizaci prvního požadavku v minutách

AuthenticationJwt

 

Podrobná konfigurace JWT autentizace

ASClient.
ForwardASGeneralExceptions

false

true – veškeré výjimky při zpracování požadavku na straně K2 AS budou předány klientovi API. False – klientovi se vrací pouze obecná chyba bez podrobností. Podrobnosti jsou uloženy v logu

ASClient.BalancerConfig.
PeriodicCheckTimer

1

Počet minut pro interval získávání stavu a čítačů vytížení pro load balancer

ASClient.BalancerConfig. Multipliers

 

Váhy (koeficient) jednotlivých čítačů výkonu pro rozhodování load balanceru.

ASClient.Servers

 

Pole se seznamem všech instancí aplikačních serverů (server + port), proti kterým může API běžet v režimu load balancer. Bez load balanceru je zadán pouze jeden záznam.

Logování API

K2 API umožňuje více režimů a rozsahu logování od základního logování pouze výjimek až po log kompletních dat příchozího požadavku a kompletní odpovědi, což najde využití především při ladění komunikace a hledání problémů s integrací dalších systémů.

Souborové logy vznikají v podadresáři logs v instalačním/pracovním adresáři API.

Požadovaná úroveň logování se nastavuje v konfiguračním souboru appsettings.json v sekci NLog.

Globální úroveň logování – parametr NLog.globalThreshold umožňuje nastavit maximální podrobnost výstupů do všech logů. Možné hodnoty jsou:

Trace – podrobné trasovací výstupy pro detail o kompletním postupu zpracování požadavku

Debug – podrobné ladící výstupy o zpracování požadavku

Info – základní informace o začátku a konci zpracování každého požadavku

Warn – pouze varování při zpracování požadavku

Error – veškeré chyby při zpracování požadavku

Fatal – pouze kritické chyby při zpracování požadavku

Off – logování je kompletně vypnuto

Sekce NLog.rules obsahuje pravidla pro jednotlivé logovací kolekce. Standardně pracuje API se 3 logovacími kolekcemi.

CommonLogger – pro obecné logovací výstupy

RequestLogger – pro zaznamenávání kompletních požadavků a odpovědí

stdOutMessages – pro zápis výstupů na standardní výstup aplikace

U každé kolekce lze určit, zda je povolená/zakázaná, jakou podrobnost výstupů má zapisovat (stejné možné hodnoty jako globální úroveň) a na jaký cíl (úložiště) se má zapisovat.

Sekce NLog.targets pak definuje jednotlivá úložiště logů a jejich pravidla. Typicky u souborového výstupu určuje název a cestu k souboru, formát jednotlivého řádku v logu a například pravidla pro archivaci/rotaci logů

Book Contents

Book Index

Základní principy komunikace

Formát dat

Těla požadavků i odpovědí jsou ve formátu JSON v kódování UTF-8. Požadavky s tělem (POST, PUT) musí obsahovat hlavičku Content-Type: application/json. Výjimkou jsou operace, které vracejí soubor (např. výstup sestavy v PDF nebo dokument připojený k záznamu) – ty vracejí přímo obsah souboru.

Struktura URL adresy

URL adresa určuje službu a prostředek, se kterým chceme pracovat, případně operaci, kterou chceme spustit:

<adresa serveru>/<služba>/<prostředek nebo operace>{?volitelné parametry}

Na rozdíl od původního API se v URL již neuvádí přepínač xml/ – výstup je vždy JSON. Datové objekty se identifikují názvem třídy datového modulu, např. TArticleDM pro zboží.

Struktura odpovědi

Všechny odpovědi ve formátu JSON mají jednotnou obálku. Kromě vlastních dat obsahuje stav zpracování požadavku, takže klient vždy ví, zda byl požadavek úspěšný a proč případně selhal:

Vlastnost

Význam

statusCode

Stav zpracování požadavku, např. OK nebo ResourceNotFound.

errorMessage

Textový popis chyby; při úspěchu prázdný.

errors

Seznam jednotlivých chyb; každá má text (message) a odkaz na místo, kterého se týká (reference).

dbgMessages

Ladicí zprávy ve stejné struktuře jako errors.

data

Vlastní data odpovědi – datový objekt, seznam objektů, výsledek skriptu apod.

Datový objekt v JSON

Záznam K2 (datový objekt) se přenáší jako objekt s názvem třídy (className) a seznamem hodnot polí (fieldValues), kde každé pole má název (name) a hodnotu (value). Hodnotou vazebního pole je vnořený datový objekt, hodnotou položkového pole (např. měrné jednotky zboží) je pole datových objektů.

{

"className": "TArticleDM",

"fieldValues": [

{ "name": "Id", "value": 35 },

{ "name": "Abbr", "value": "TESTARTICLE" },

{ "name": "Name", "value": "Test Article" },

{ "name": "ArticleTypeId", "value": {

"className": "TTextDM",

"fieldValues": [

{ "name": "Id", "value": 1 },

{ "name": "Description", "value": "Article" }

] } }

]

}

Při změně existujícího záznamu je potřeba poslat zpět i hodnotu pole Timestamp načtenou spolu se záznamem. Stejně jako u původního API tím K2 brání přepsání změn, které mezitím provedl jiný uživatel.

Přehled služeb

Služba

Adresa

Účel

Data

/data/…

Čtení seznamů a detailů záznamů (sekvenčně i po stránkách), filtrování včetně uložených filtrů, vytváření a změna záznamů, spouštění příkazů, nahrání a stažení dokumentů.

Meta

/meta/…

Informace o verzi, seznam datových objektů zveřejněných pro K2 API, popis jejich polí, primárních klíčů, příkazů a uložených filtrů.

Formation

/formation/…

Spouštění skriptů a sestav – s vrácením výstupních parametrů, s vrácením výstupního souboru nebo s přímým zpracováním HTTP požadavku skriptem.

FormationDefinition

/formationmeta/…

Popis skriptu nebo sestavy včetně parametrů a jejich výchozích hodnot.

Authorization

/token/…, /currentUser/…

Získání a obnova JWT tokenu, údaje o přihlášené kontaktní osobě.

System

/system/…

Kontrola dostupnosti aplikačního serveru (ping) a další systémové operace.

Web

/web/…

Operace pro webová řešení a e-shopy K2 – konfigurace webu, textové stránky, lokalizované texty.

Marketplace

/marketplace/…

Napojení na marketplace (Alza) – příjem, potvrzení, prodloužení a zrušení objednávek.

CRM

/crm/…

Podpora pro CRM aplikace (synchronizace emailů, kalendáře, atd…)

Pbx

/pbx/…

Příjem událostí z telefonní ústředny do historie hovorů.

Podrobný popis jednotlivých operací je uveden v dalších kapitolách a v OpenAPI dokumentaci instance.

Příklad požadavku

Ukázka odpovědi (zkráceno):

{

"statusCode": "OK",

"errorMessage": "",

"data": {

"items": [

{ "className": "TArticleDM",

"fieldValues": [

{ "name": "Id", "value": 35 },

{ "name": "Abbr", "value": "TESTARTICLE" },

{ "name": "Name", "value": "Test Article" },

…

] }

],

"itemsPerPage": 10,

"firstPageUrl": "…",

"nextPageUrl": "…",

"previousPageUrl": "…",

"lastPageUrl": "…"

}

}

Další stránku výsledku získáte zavoláním adresy z vlastnosti nextPageUrl. Pokud potřebujete přejít přímo na konkrétní stránku nebo znát celkový počet záznamů, použijte operaci GET /data/paged/{classname} s parametry pageNumber a includeTotalRecordsCount. Filtrovat a řadit lze v tomto případě jen podle fyzických (ne počítaných) polí.

Book Contents

Book Index

Autentizace

Každý požadavek na K2 API musí nést informaci o uživateli K2, pod jehož identitou se má zpracovat. Na tomto uživateli závisí, k jakým datům a funkcím má požadavek přístup – uplatňují se stejná přístupová práva jako při práci v K2.

Údaje o přihlášené kontaktní osobě vrací operace GET /currentUser/ContactPerson.

K2 API v2 podporuje dva způsoby autentizace. Které z nich jsou povoleny, se nastavuje v konfiguraci každé instance K2 API. Jsou-li povoleny oba, K2 API je rozliší podle hodnoty hlavičky Authorization – pokud začíná slovem Bearer, jde o JWT token, jinak o HMAC podpis.

JWT token

Nový, doporučený způsob. Klient se nejprve přihlásí uživatelským jménem a heslem a získá dvojici tokenů:

Přihlášení:

POST /token/login

Content-Type: application/json

{ "username": "user1", "password": "pass" }

Odpověď:

{

"accessToken": "xxxxx.yyyyy.zzzzz",

"accessTokenValidity": "2000-01-01T00:30:00.000",

"refreshToken": "a50d4492f751c28b2",

"refreshTokenValidity": "2000-02-01T00:30:00.000"

}

Access token se pak posílá v každém požadavku v hlavičce:

Authorization: Bearer <access token>

Po vypršení platnosti access tokenu klient zavolá POST /token/refresh, v jehož těle pošle refresh token (jako řetězec JSON), a získá novou dvojici tokenů. Vlastnosti accessTokenValidity a refreshTokenValidity udávají, do kdy jsou tokeny platné, takže klient může obnovu naplánovat dopředu.

Pro webová řešení lze při přihlášení předat i identifikaci webu (shopRID).

Výhodou JWT je, že klient nemusí podepisovat každý požadavek zvlášť. Tento způsob podporuje většina knihoven a vývojových nástrojů, včetně samotné OpenAPI dokumentace, ve které lze token zadat a volání rovnou vyzkoušet.

HMAC podpis požadavku

Způsob známý z původního K2 API, který umožňuje zachovat stávající mechanismus autentizace u existujících integrací. Klient v každém požadavku uvede hlavičku Authorization ve tvaru {UserName}:{HMACHash}. Hash se vypočte algoritmem HMAC MD5: klíčem je heslo uživatele a hashovanou zprávou celá URL adresa požadavku v nekódované podobě (bez URL kódování speciálních znaků) převedená na velká písmena. Výsledek se převede kódováním Base64 na text. Heslo se tak po síti nepřenáší.

Příklad výpočtu v jazyce C#:

public static string CalcHMAC(string src, string password)

{

byte[] secretBytes = Encoding.UTF8.GetBytes(password);

HMACMD5 hmac = new HMACMD5(secretBytes);

byte[] dataBytes = Encoding.UTF8.GetBytes(Uri.UnescapeDataString(src).ToUpper());

byte[] computedHash = hmac.ComputeHash(dataBytes);

return Convert.ToBase64String(computedHash);

}

Příklad výpočtu v K2 skriptu:

function CalcHMAC(ASrc, APassword: string): string;

begin

if not CreateHMacMD5HashBase64(AnsiUpperCase(HTTPDecode(ASrc)), APassword, Result) then

Result:= ' ';

end;

Příklady v dalších jazycích (Java, PHP) jsou uvedeny v OpenAPI dokumentaci.

Alternativně je možné předat hash i přímo v URL adrese pomocí parametru „x-auth“. V tomto případě se sestaví celá URL požadavku, na konec se připojí &x-auth= a celý text se předá hashovací funkci. Výsledek hashovací funkce se opět připojí na konec tohoto textu.

Příklad funkce v K2 skriptu pro doplnění hashe přímo v URL:

function AppendAuthorizationHeader(aURL: string; aUsername: string; aPassword: string): string;

var

lHash: string;

begin

Result := aUrl;

if (Pos('?', aURL)=0) then

aURL := aURL + '?x-auth='

else

aURL := aURL + '&x-auth=';

if CreateHMacMD5HashBase64(AnsiUpperCase(aURL), aPassword, lHash) then

Result := aURL + HTTPEncode(aUsername + ':' + lHash);

end;

Bezpečnost: Tokeny i HMAC podpis přenášejte vždy pouze přes HTTPS. Tokeny je třeba chránit stejně jako heslo – kdokoli, kdo je získá, může do vypršení jejich platnosti vystupovat jako daný uživatel.

Book Contents

Book Index

Kontextové informace požadavku

V K2 API v2 lze ke každému požadavku připojit kontextové informace, které pro dobu zpracování požadavku upraví nastavení uživatele – obdobně jako když si uživatel v K2 přepne firmu, jazyk nebo sklad. Kontextové informace se předávají jako HTTP hlavičky:

Hlavička

Význam

Příklad

X-LangId

ID jazyka. Ovlivňuje hodnoty přeložených polí apod.

5

X-CompanyId

ID vlastní firmy, v rámci které se požadavek zpracuje.

3

X-InfoWarehouseId

ID informačního skladu. Ovlivňuje hodnoty počítaných polí, např. dostupné množství zboží.

257

X-BusinessYear

Obchodní rok (období), do kterého se zakládají nové záznamy.

2022

X-CurrencyCode

ISO kód měny, ve které se mají vracet ceny.

EUR

X-PartnerId

ID aktuálního partnera. Vyžadováno některými operacemi pro e-shop.

66

X-ShopRid

RID aktuálního e-shopu / webu. Vyžadováno operacemi služby Web.

4569845202946

Příklad – načtení zboží v angličtině s dostupností na skladu s ID 257:

GET https://demo.k2.cz/k2apiv2/data/TArticleDM?fields=Abbr,Name

Authorization: Bearer <access token>

X-LangId: 1

X-InfoWarehouseId: 257

Pokud kontextová hlavička v požadavku uvedena není, použije se nastavení daného uživatele K2.

Book Contents

Book Index

Ošetření chyb

Při chybě K2 API v2 vrací odpovídající stavový kód HTTP a v těle odpovědi stejnou obálku JSON jako při úspěchu, jen s vyplněnou informací o chybě. Klientská aplikace tak může chyby spolehlivě rozpoznat a zpracovat strojově: podle stavového kódu HTTP rozliší základní typ chyby, podle vlastnosti statusCode konkrétní důvod a text z errorMessage a errors může zobrazit uživateli nebo zapsat do logu.

Příklad – požadovaný záznam neexistuje (HTTP 404):

{

"statusCode": "ResourceNotFound",

"errorMessage": "The object with specified key was not found"

}

Oproti původnímu API se ve formátu JSON vracejí i chyby, které dříve končily obecnou HTML stránkou bez bližších podrobností (např. chybně sestavené tělo požadavku). Seznam errors navíc umožňuje vrátit více chyb najednou – například všechny chybějící nebo nesprávně vyplněné hodnoty při ukládání záznamu.

Nejčastější stavové kódy HTTP:

Kód

Význam

200

Požadavek byl úspěšně zpracován.

201

Záznam byl vytvořen (u některých operací, např. Marketplace).

400

Chybně sestavený požadavek – např. nevalidní JSON, neznámé pole, chybná podmínka.

401

Chybí autentizace nebo je neplatná (např. vypršel access token).

403

Uživatel nemá oprávnění k požadované operaci.

404

Požadovaný prostředek neexistuje – např. neznámý datový objekt, záznam, skript nebo uložený filtr.

500

Chyba při zpracování na straně K2 API nebo aplikačního serveru.

Možné hodnoty statusCode:

Kód

Význam

OK

Požadavek byl úspěšně zpracován.

BadRequest

Chybně sestavený požadavek – např. nevalidní JSON, neznámé pole, chybná podmínka.

NotAuthorized

Chybí autentizace nebo je neplatná (např. vypršel access token).

ResourceNotFound

Požadovaný prostředek neexistuje – např. neznámý datový objekt, záznam, skript nebo uložený filtr.

GeneralError

Chyba při zpracování na straně K2 API nebo aplikačního serveru.

ServiceUnavailable

Dočasná chyba služby – například není dostupný žádný běžící aplikační server

Book Contents

Book Index

První kroky

  1. Otevřete v prohlížeči kořenovou adresu K2 API a ověřte, že se zobrazí úvodní stránka s informací o verzi.
  2. Zavolejte GET /system/ping a ověřte, že je dostupný aplikační server K2.
  3. Přejděte na odkaz s dokumentací (Swagger) a seznamte se s dostupnými službami.
  4. Získejte JWT token voláním POST /token/login a zadejte jej v dokumentaci (tlačítko Authorize).
  5. Vyzkoušejte jednoduché čtení dat, např. seznam datových objektů zveřejněných pro K2 API (GET /meta/objects) a seznam zboží (GET /data/TArticleDM).
  6. Podle OpenAPI specifikace implementujte volání ve své aplikaci, případně si klienta vygenerujte automaticky.