API-juhis

v0.3 26.06.2017

Juhis esitab terminoloogia, nõuded ja soovitused REST API-de projekteerimiseks, testimiseks ja dokumenteerimiseks. Arvamused ja ettepanekud palume saata: priit.parmakson@ria.ee.

Sisukord

1 API elutsükkel

API (application programming interface) e masinliides on eraldi käitatavate ja/või arendatavate süsteemide või komponentide sidumise viis. API-del põhineb süsteemide lõimimine (systems integration), hajusarhitektuursed lahendused, sh mikroteenused ja üldse suur osa tänapäevasest infotöötlusest.

API-põhine arhitektuur, nn API first strateegia API First Government, Kütt 2016, toob kaasa API-de arvu ja keerukuse kasvu. Süsteemid, ka taristud, arenevad selles suunas, et kõik andmed ja kogu funktsionaalsus on kasutatavad API-de kaudu. Masinloetav API ja inimkasutaja liides toetavad ja täiendavad teineteist. Vt ka Kütt, A (2016) Reference Architecture for Cloud-Ready Government Systems, nn “Rebaseregister”.

Süsteem peaks kogu oma andmestikku pakkuma masinloetaval kujul s.t API kaudu.

API elutsükli moodustavad hulk tegevusi:

API arendamisel tuleb kõiki neid aspekte adekvaatselt käsitleda.

2 API-juhised

API kavandamisel saab eeskuju võtta muuhulgas järgmistest juhistest jm materjalidest:

3 API kavandamise lähteparameetrid

Kavandamist mõjutavad liidese kavandatavad kasutusparameetrid: 1) kas liides on avalik, kõigile vabalt kasutamiseks või on vaja ligipääsu piirata? 2) kas liides on mõeldud kasutamiseks turvatud sisevõrgus või avalikus internetis? 3) kas kasutatakse REST, SOAP või mõnda muud stiili? Käesolev juhis keskendub REST API-dele.

4 API tööriistad

API-de arendamise, dokumenteerimise, testimise ja turvamise keerukus on tinginud mitmesuguste API tööriistade (redaktorite, avaldamisvahendite, validaatorite) teket. Näiteks:

API-de arendamise ja haldamise platvormid üritavad pakkuda tööriistade kogumeid ja API elutsükli täistoetust. Tähtsamad API-platvormid on Apiary ja Agigee. API-platvormide arengut näitab Apiary ostmine Oracle poolt (Jan 2017) ja Apigee ostmine Google poolt (Nov 2016). API-platvormi kasutamine väikese API-de arvu korral tõenäoliselt ei ole õigustatud. Kuid tuleb tajuda, et API arendamine pole ühekordne ettevõtmine, vaid pikemaajaline protsess.

5 API teenusenimi

API teenuse nimi peab olema RFC1035 kohane domeeninimi, mis lahendub üheks või mitmeks võrguaadressiks. Nt riha.eesti.ee. Kui API kujundatakse mitmest teenusest koosnevana, siis peab teenusenimede valik toetama teenuste ülesleitavust. Mitut teenust saab ka pakkuda sama teenusenime all, esitades need pöördumistees teenuse versiooninumbri järel. Nt riha.eesti.ee/v1/Producer ja riha.eesti.ee/v1/Publisher (Google käsitlus). Vt Google disainijuhis, jaotis Naming Conventions.

6 Ressursid

Ressursid jagunevad lihtressurssideks (simple resource) ja kogumressurssideks (collection resource). Ressursil on olek (state) ja võivad olla alamressursid (sub-resources).

Ressursi nimi moodustub ressursi ID-st, vanemressursside ID-dest ja API teenuse nimest (Google käsitlus).

Igal ressursil peab olema unikaalne nimi.

Nt: systems (RIHA-s kirjeldatud infosüsteemide kogum) ja systems/ETIS (RIHAs kirjeldatud infosüsteem ETIS).

Ressursi täisnimi sarnaneb URL-le, kuid ei ole viimasega samaväärne, sest sama ressurss võib olla eksponeeritud mitme erineva protokolli ja API versiooni kaudu (Google käsitlus). Ressursi täisnimi moodustatakse järgmiselt: 1) lisada teenuse nime ette HTTPS skeem; 2) lisada ressursitee ette API major versioon; 3) kasutada URL-escape-i (%-encoding).

Ressursi suhteline nimi identifitseerib ressurssi API teenuse kontekstis.

Ressursi ID on ressurssi oma vanemressursi kontekstis identifitseeriv URI segment. Nt: ETIS (RIHAs kirjeldatud infosüsteem ETIS).

Peab selgelt dokumenteerima, kas ressursi ID moodustatakse kliendi (kasutaja) või serveri poolt (Google disainijuhend).

Nimemustri kujundamisel arvestada ka seda, et kasutajad mustrist aru saaksid ja nime oleks kerge kasutada.

Kogumressursi ID (collection ID) peab olema mitmuses. Nt: systems (RIHA-s kirjeldatud infosüsteemide kogum). Vt Google disainijuhis, jaotis Resource Names.

7 Meetodid

Meetodid rakenduvad ressurssidele ja jagunevad standardmeetoditeks ja erimeetoditeks. Standardmeetodid Google käsitluses on List, Get, Create, Update ja Delete. Need esitatakse HTTP meetodite abil järgmiselt:

Meetod Vastav HTTP meetodimuster HTTP päringu keha HTTP vastuse keha
List GET <kogumi URL> tühi ressursikogum
Get GET <ressursi URL> tühi ressurss
Create POST <ressursi URL> ressurss ressurss
Update PUT või PATCH <ressursi URL> ressurss ressurss
Delete DELETE <ressursi URL> tühi tühi

Nendest reeglitest on erisusi, vt Google disainijuhis, jaotis Standard Methods.

Erimeetod on selline, mis kaldub kõrvale standardsest REST semantikast. Nt infosüsteemi omaniku vahetus.

Kus vähegi võimalik, tuleks kasutada REST standardmeetodeid.

Google disainijuhis, jaotis Custom Methods pakub skeemi erimeetodite vormindamiseks (custom verb).

8 Protokollid

Arvestada turvatud HTTP protokolli kasutamisega (HTTPS, aga mitte näiteks WebSocket. Viimane on uuem, TCP-põhine, veebisirvija ja -serveri vahel üheaegselt kahes suunas andmeedastust (full-duplex) võimaldav andmevahetusprotokoll).

9 Päringu moodustamine

Andmete saatmiseks päringus on järgmised võimalused:

1) URL-i osana (URL-encoded);

2) JSON-vormingus päringu kehas (HTTP request body). MIME meediatüüp sellisel juhul on application/json;

3) POST päringutes kasutatakse ka nn form-urlencoded esitust, kus HTML-vormilt loetud andmed saadetakse query string-kujul, kuid päringu kehas (MIME meediatüüp application/x-www-form-urlencoded).

10 Filtreerimine ja sortimine

Kui API pakub tulemuste nimekirja filtreerimist või sortimist, siis võiks järgida SQL süntaksit. Vt ka Google disainijuhend, jaotis Sorting Order.

11 Kauakestvad operatsioonid

Kui API meetodi täitmine võtab tüüpiliselt kauem aega, siis võib meetodi projekteerida nii, et tagastatakse tagasikutse (callback, Google terminoloogias - Long Running Operation), mille abil klient saab jälgida edenemist ja saada lõpptulemuse. Vrdl Google disainijuhend, jaotis Common Design Patterns.

12 Andmete väljastamine leheküljeti

Andmete väljastamine leheküljeti tuleks teostada ka väikesemahuliste, kuid kasvada võivate ressursikogumite puhul. Google soovitus on “listable collections should support pagination, even if results are typically small.” Vt Google disainijuhend, jaotis Common Design Patterns.

13 Päringu samajõulisus

Väga soovitav on teha päringud samajõuliseks (idempotentseteks). See tähendab, et sama päringut saab võrgutõrke korral ilma kahjulike kõrvalmõjudeta uuesti saata. Kui päringut ei saa teha idempotentseks, siis peaks iga päringsõnum sisaldama unikaalset idempotentsus-ID-d. Vt: Leach (2017) Designing robust and predictable APIs with idempotency; Google disainijuhis, jaotis Request Duplication.

14 API turvamine

Reeglina tuleb API-d kaitsta TLS-ga, ka sisevõrgus. (See tähendab, et pöördumine toimub HTTPS-ga).

Juurdepääs väliseks kasutuseks mõeldud API-le võib olla kas piiramata või piiratud autentimistokeni abil, mis tuleb päringule kaasa panna kas ühe parameetri või HTTP päises oleva väärtusena. Eelistatud on JWT (JSON Web Token) autentimine. Vt Stankovic (2016), JWT Authentication Tutorial: An example using Spring Boot. Siiski tuleb igal konkreetselt juhul selgitada, kas JWT kasutamine on arendajale jõukohane ja äriliselt ning tehniliselt põhjendatud.

15 API versioneerimine

API struktuuris tuleb taodelda stabiilsust.

Kui on ette näha API muutumisvõimalust, siis tuleb API versioneerida.

Versioneerimisel on otstarbekas kasutada semantilist versioneerimist. Vt Google disainijuhis, jaotised Compatibility ja Versioning.

16 API disainimine

Google API Design Guide soovitab järgmist tööde järjekorda (design flow): 1) määrata API-s pakutavad ressursitüübid (resource types); 2) määrata ressurssidevahelised seosed; 3) määrata nimemustrid e -skeemid (resource name schemes); 4) määrata ressursiskeemid; 5) siduda minimaalne hulk meetodeid ressurssidega.

17 API spetsifitseerimine

Kirjelduse täielikkus. Masinliides tuleb täielikult dokumenteerida. “Discovery-based documentation” (API käitumise väljaselgitamine katse-eksituse teel) ei ole aktsepteeritav.

Formalismi kasutamine. Vajalik on formaalne kirjeldus, mis ühtlasi peab olema ka inimloetav.

“Vabas vormis” dokumenteerimine on vastuvõetav ainult triviaalsete liideste puhul.

Formaalne kirjeldamine ei ole eesmärk omaette, vaid vahend kirjelduse täielikkuse ja üheseltmõistetavuse saavutamiseks. REST API-de dokumenteerimise kohta on kaks laialtlevinud standardit: 1) OpenAPI Specification, endise nimega Swagger, kasutab aluskeelena YAML-i või JSON-it; 2) API Blueprint kasutab aluskeelena Markdown-i (“a powerful high-level API description language”). Eelistatud on OpenAPI kirjelduskeele kasutamine. Extended Backus-Naur Form (EBNF) on samuti hea formalism.

Näited. Näite või näidete lisamine on tingimata vajalik. Seejuures kirjeldamine ainuüksi näite abil ei ole piisav.

Navigeeritavus. API kirjeldus peaks olema navigeeritav.

Avalikkus. API kirjeldus tuleb selgelt, tavaliselt avalikult, publitseerida.

Ajakohasus. API kirjeldust tuleb hoida ajakohasena. See tähendab, et API käitumine peab vastama kirjeldusele.

18 API tarkvaraline teostamine

REST API-de tegemise vahendeid pakutakse paljudel platvormidel ja raamistikes. Mõnda platvormi on API-d vaikimisi sisse ehitatud. Nt: Spring Boot; PostgreSQL Restful API; Google Apps Script. Vt ka jaotis “API tööriistad”.

19 API testimine

Testide katvus. Testid peavad hõlmama kõiki ressursitüüpe ja kõiki meetodeid.

Automatiseerimine. API testid tuleb automatiseerida vähemalt testikogumit käitava skripti tasemel.

20 API kasutuse mõõtmine

Ei ole mõtet teha liidest, mida keegi ei kasuta. API kasutuse mõõtmine (statistika kogumine) peaks olema API elutsükli standardne osa. Vajalik võib olla ka API kasutuse monitooring (turvakaalutlustel). Vastavad võimalused tuleks ette näha juba API kavandamisel.

CC BY-NC-SA 4.0 Priit Parmakson 2017