Stopárov sprievodca REST API
Už ste niekedy potrebovali pristupovať k dátam aplikácie z viacerých prostredia alebo svoje dáta poskytovať aj ďalším užívateľom? Ak áno, najskôr ste tiež museli definovať nejaké verejné rozhranie (API), ktorému by rozumeli všetky vaše aplikácie a prípadne ďalšie konzumenti vašich dát. REST toto API definuje za vás. Je to rozhranie pre distribuované prostredia orientované na dáta, nie na volanie procedúr ako napr. RPC (XML-RPC) či SOAP.
REST má samozrejme svoje špecifiká a (dosť často nepísané) štandardy, ktoré je ale vhodné dodržiavať. Aby sme ich lepšie pochopili, rozdelíme si REST do 4 úrovní tak, ako ich rozdelil Leonard Richardson.
Nultá úroveň
Jedná sa o samotný prenos dát. REST sa totiž neviaže na HTTP, takže je teoreticky možné použiť inú metódu prenosu. HTTP je ale dnes tak rozšírený protokol, že snáď ani nemá cenu hovoriť o iných možnostiach. Navyše za nás vyrieši veľa vecí, a tak môžeme rovno skočiť na ďalší bod.
Prvá úroveň - zdroje (Resources)
Namiesto toho, aby sa všetky požiadavky posielali na jeden centrálny bod,
použije sa ich viac. Každý zdroj (resource) má potom práve
jeden koncový bod, kde ho možno dosiahnuť. Napr.
GET /articles
- vráti zoznam článkov,
GET /articles/1/comments
vráti zoznam komentárov k jednému
danému článku pod. Je dôležité zvoliť si nejaký štandard pomenovávaní
zdrojov (potrebné používať buď len množné číslo -
GET /articles
, GET /comments
, alebo len jednotné
GET /article
, /comment
)
Druhá úroveň - HTTP Verbs
V protokole HTTP je asi najznámejšia metóda GET. Bola by však chyba obmedzovať sa pri návrhu API len na ňu. Protokol HTTP ich totiž ponúka oveľa viac. Sú to: PUT, PATCH, DELETE, OPTIONS a ďalšie. Samotné názvy zdrojov neobsahujú slovesá, len podstatné mená. Akciu, ktorú chceme vykonať, vyjadríme práve pomocou HTTP Verbs.
Významy jednotlivých HTTP Verbs sú nasledujúce:
- GET - získanie dát
- POST - vytvorenie
- PUT - úpravy (upraví celý zdroj - správa sa ako SET)
- DELETE - zmazanie
- PATCH - čiastočné úpravy
Metódu PATCH pritom v originálnej špecifikácii HTTP nenájdeme. Ale keďže je HTTP rozšíriteľný protokol, časom začali vznikať nová užitočná rozšírenie. Používaním metódy PATCH znížime tok informácií po sietí, pretože prenášame len dáta, ktorá sa zmenila, kdežto u PUT prenášame vždy celý zdroj.
Stavové kódy
V http tiež nájdeme stavové kódy a je ich zďaleka viac ako len 200 OK. Pomerne známy je ešte kód 404 Not Found (nenájdené). Pre nás vývojárov pravdepodobne ešte 500 Server Error. V REST API sú najčastejšie používané:
- 200 OK - požiadavka prebehol v poriadku
- 201 Created - pri POST, ak bol vytvorený nový obsah
- 204 No Content - keď požiadavka na server prebehne v poriadku, ale server nič nevráti
- 304 No Modified - pokiaľ nebol od posledného požiadavke nebol zmenený obsah - používa sa pre natívny http cache
- 400 Bad Request - požiadavka na server je nejakým spôsobený nečitateľný (napríklad zlý JSON a pod.)
- 401 Unauthorized - klient nie je dôveryhodný
- 403 Forbidden - klient nemá prístup k danému obsahu
- 404 Nod Found - zdroj nie je nájdený
- 405 Method Not Allowed - zdroj nie je dostupný pre túto metódu. Napríklad je možné použiť GET / articles a POST / articles, ale už treba nemôžeme článok zmazať. Nemožno teda zavolať DELETE / articles - je vhodné používateľom nášho API v tomto momente poskytnúť zoznam podporovaných metód pre danú URL
- 410 Gone - zdroj nie je už na tejto adrese dostupný - to sa používa pri verzovania
- 415 Unsupported Media Type - klient v požiadavke na server uviedol hlavičku Content-Type, ktorú server nepodporuje
- 422 Unprocessable Entity - chyba validácia dát - napríklad formuláre a pod.
- 429 Too-Many Requests - ak klient prekročil maximálny počet požiadaviek, napríklad za deň
Nezabudnite, že je HTTP rozšíriteľný protokol. V špecifických prípadoch tak môžeme použiť vlastný kód stavu, ak bude zachovaná hlavná trieda (tj. Odpoveď: 1xx - informačné, 2xx - úspešná, 3xx - presmerovanie, 4xx - chyba klienta, 5xx - chyba servera)
Veľmi dôležité je udržať REST API bezstavový. To znamená, že by napr. Overenie užívateľa nemalo závisieť na session alebo cookies. Každá požiadavka by mal obsahovať overovací údaje, podľa ktorých REST API pozná, kto sa pripojil. Možností, ako takéto overenie vykonať, je viac. Najrozšírenejším štandardom je OAuth. Počíta aj s prípadmi, keď nemožno u klienta ako je Android alebo JavaScript uchrániť citlivé údaje.
Tretia úroveň - hypermediálnych Controls
Posledná tretia úroveň je známa pod akronymom HATEOAS (Hypertext as the Engine of Application State). Zjednodušene ide o to, že poznáme iba základné koncový bod, ktorý vracia spolu s dátami aj odkazy na ďalšie zdroje, tie zase na ďalšie a tak ďalej. Každý zdroj tak klientovi dáva možnosti, akú akciu môže vykonať alebo čo ďalej urobiť. Predstaviť si to môžeme ako HTML dokument s odkazmi na ďalšie stránky. Výhody sú zrejmé - klient nie je závislý na URL adresách (musí poznať len tú prvú, ďalej len "kliká" na odkazy), tie sa môžu pokojne za behu meniť. Ďalej možno pridávať alebo meniť ďalšie funkčnosť, bez potreby čokoľvek zmeniť u klienta.
Hoci sami autori REST tvrdí, že REST API musí byť riadené odkazy, zatiaľ sa HATEOAS veľmi nepoužíva. V súčasnej dobe totiž nie je moc dostupných nástrojov a materiálov pre HATEOAS.
Implementácia REST API
GZIP kompresia
Kompresiou zdrojov môžeme ušetriť až 80% veľkosti zdroja, čím sa zníži prenos dát po sieti.
JSON ako hlavný formát
JSON je dnes veľa rozšírený formát, s ktorým vie dobre pracovať veľa
jazykov. Pokiaľ by ale bolo nutné podporovať aj iný formát, použijeme
hlavičku Content-Type
pre detekciu. Pr .: keď klient pošle
požiadavku s Content-Type: application/json
vrátime mu JSON, keď
Content-Type: application/xml
, vrátime XML - keď niečo iné,
vrátime klientovi error 415 Unsupported Media Type. Detekciu typu môžeme dať
aj do URL (GET /articles.xml
, GET /articles.json
), ale
v tom prípade je vhodné hlavičku Content-Type úplne ignorovať. Použitie
HTTP hlavičky je "čistejšie" riešenie.
Cache
HTTP má vstavanú podporu pre nezdieľanú cache pomocou hlaviček ETag alebo Last-Modified.
Relácie
Osvedčilo sa mi používať URL typu
/<zdroj>/<id>/<relace>/<id relace>/<další relace>
atď. Pre úplnosť uvediem pár príkladov:
- GET / articles / 1 / comments - vráti komentáre k článku s ID 1
- GET / articles / 1 / comments / 5 - vráti komentár s ID 5 k článku s ID 1
- DELETE / articles / 1 / comments / 5 - zmaže komentár s ID 5 u článku s ID 1
Stránkovanie
Nie je nič jednoduchšie ako klientovi poskytnúť URL na ďalšiu,
predchádzajúcu, príp. poslednú stránku. Používa sa na to hlavička
Link
. Je taky vhodné klientovi vrátiť presný počet všetkých
položiek v hlavičke X-Total-Count
Snake_case, CamelCase, PascalCase
Je vhodné používať jednotnú konvenciu pre všetky zdroje alebo ešte
lepšie ponúknuť klientom možnosť, použiť konvenciu inú.
snake_case
je oveľa lepšie čitateľný ako
camelCase
, ale s camelCase
sa zase prirodzenejšie
pracuje v JS.
Vývoj REST API
Pre návrh API a jeho mockování existuje veľmi užitočný nástroj Apiary.io Vďaka nemu možno pomerne ľahko navrhnúť prototyp REST API, ktorý potom následne môžeme použiť ako zástupca servera. To umožňuje zamerať sa viac na vývoj samotnej aplikácie a skvele oddelí vývoj jej klientskej a serverovej časti.
Testovanie
Skvelým nástrojom pre testovanie môže byť potrebné cURL. Jednoduchý konzolový nástroj, ktorý umožňuje volať HTTP požiadavky. Ak máte radšej GUI, pozrite sa na rozšírenie do vášho prehliadača. Do Chrome napríklad existuje skvelé rozšírenie Postman a do Firefoxu nájdete veľa addon.
Hotová riešenie
Za zmienku stojí tiež databázy CouchDB, v ktorej sa na dáta pýtame práve pomocou REST API. Svoje REST API má aj napríklad ElasticSearch a množstvo ďalších.
Záver
REST je architektúra API, ktorá nám umožňuje pristupovať k dátam a vykonávať nad nimi CRUD operácie. REST je bezstavový, čím jednak značne zjednodušuje komunikáciu s API a umožňuje paralelné spracovanie obsahu. Zároveň ho možno dosť ľahko použiť s HTTP, čo je veľmi rozšírený protokol (v podstate dnes nemá zmysel používať iný). V neposlednom rade nám poskytuje určitý štandard, takže nie je problém použiť cudzí API alebo naopak ponúkať vlastné veľkému množstvo ďalších užívateľov.