REST API alapok

Mi az az API?

Az API (Application Programming Interface) olyan kommunikációs réteget biztosít két program között, amely segítségével a programok igénybe tudják venni egymás szolgáltatásait. Az API-król dokumentáció (később) készül, ami leírja, hogy az adott szolgáltatásokat hogyan lehet elérni.

A REST (REpresentational State Transfer) egy olyan szoftverarchitektúra, amely a kifejezetten a webes kommunikációhoz készült, annak a módját határozza meg, illetve bizonyos szabályokat fogalmaz meg arról. Ezeket a szabályokat alkalmazó webes API-kat RESTful API-nak nevezzük.

A REST által definiált szabályok egyszerűségre, skálázhatóságra és állapotmentességre törekednek. 5 fő szabályt fogalmaz meg. (6-ot, de az utolsót nem kötelező implementálni)

A REST szabályai

1. Egységes interfész

A REST API-knak konzisztens és egységes interfészt kell biztosítaniuk a kliens-szerver interakciókhoz. Ez többek között azt jelenti, hogy standard HTTP utasításokat (GET, POST, PUT, DELETE, ...) használnak és az erőforrásokat URI-k (Uniform Resource Identifier) azonosítják.

2. Kliens-szerver szemlélet

A kliens-szerver elválasztódás azt jelenti, hogy függetleníteni kell egymástól a felhasználói felület feladatait és a szerver feladatait. Például a kliens ne foglalkozzon azzal, hogy az adatok milyen adatbázisba kerülnek, és a szerver se azzal, hogy a kliens milyen operációs rendszert használ.

Ez az elválasztás azt eredményezi, hogy a két komponens külön-külön fejleszthetővé válik, illetve több platformra készíthetünk külön-külön felhasználói felületet, amelyek ugyanúgy működőképesek a szerverrel. (Pl. mobil applikáció és webes felület)

Fejlesztés során figyelni kell arra, hogy a két komponens közötti kapcsolat működőképes maradjon. (Működésében továbbra is azt nyújtsa a szerver, amit addig is → API verziókezelés)

3. Állapotmentesség

A szerver nem használhat fel semmi olyan adatot egy kérés feldolgozásához, amit egy előző kérés eredményeként tárolt volna el a memóriájában. Ezért a kliens minden kérésének tartalmaznia kell minden információt, ami a kérés feldolgozásához szükséges.

Ebből kifolyólag a munkafolyamatot a kliensnek kell tárolnia, kezelnie.

Ez a determinisztikusság mellett azért szükséges, mert egy elosztott rendszerben, több szerver esetén nem biztos, hogy egy kliens minden kérése ugyanahhoz a szerverhez kerül.

4. Gyorsítótárazhatóság

A szerver válaszainak (implicit vagy explicit módon) tartalmaznia kell, hogy az adott üzenet gyorsítótárazható-e. Ha igen, akkor a kliens egy adott időtartamon (TTL) belül újra felhasználhatja ezt a választ, így nem kell újra elküldenie ugyanazt a kérést.

5. Rétegelt architektúra

A rétegelt architektúra feladatkörök alapján egyértelműen felosztja a kódbázist külön részekre (rétegekre), amelyek úgy működnek együtt, hogy nem tudnak a szomszédos rétegek implementációjáról.

Erőforrás

A REST-ben az erőforrás az információ egy absztrakciója. Bármilyen információ lehet erőforrás. Lehet például egy dokumentum, egy kép, egy szolgáltatás, más erőforrások gyűjteménye...

Az erőforrások adatból és metaadatból áll.

Erőforrások azonosítása

Az erőforrásokat URI-kkal (Uniform Resource Identifier) egyértelműen azonosíthatjuk.

uri

Lapozás

Olykor egy-egy API kérés mögött rengeteg adat lehet, amit nem szeretnénk, ha egy válaszban kapnánk meg, mert az nagyobb válaszidővel fog járni, és lehet hogy nincs is szükségünk egyszerre az összes adatra.

Ezt a problémát ún. lapozással (API pagination) lehet megoldani, ami általában azzal jár, hogy 2 paramétert fűzünk a kéréshez: az egyik megmondja, hogy hányadik elemtől kérjük az adatokat (skip/offset), a másik, pedig hogy egyszerre hány elemet szeretnénk kapni (limit). Így több, különálló kéréssel kapjuk meg az adatokat.

HTTP Működése

http_process_explained

Folyamat:

  1. A kliens küld egy kérést a megfelelő formátumban
  2. A szerver hitelesíti a klienst
  3. A szerver feldolgozza a kérést
  4. A szerver válaszol a kliensnek

HTTP Kérés

http_request

authorization

HTTP Válaszok

A HTTP kérésekre érkező válaszok minden esetben tartalmaznak egy státuszkódot, fejlécet különféle mezőkkel, illetve opcionálisan törzset, ami adatot hordoz.

Státuszkódok

status-codes

Fun: https://http.cat

Adatleíró nyelvek

XML

xml

  • Leíró nyelv
  • Adatok küldésére és tárolására
  • Ember számára is olvasható
  • Tagekből, attribútumokból és adatokból áll

JSON

JSON

  • Leíró nyelv
  • Adatok küldésére és tárolására
  • Ember számára is olvasható
  • Egymásba ágyazott objektumok és tömbök
  • Objektum: kulcs-érték párok
    • Kulcs: szöveg
    • Érték: szöveg, szám, logikai, tömb, objektum vagy null
  • Whitespace nem számít

API Hitelesítés

A nem publikus API-kat hitelesítéssel védik. Ez sokféleképpen történhet, de a fő lépései:

  1. A kliens egy külön erre a célra létrehozott URL-re küld egy kérést, amiben elküldi valamilyen hitelesítő adatot, pl. felhasználónév és jelszó kombinációja
  2. A szerver cserébe küld egy munkamenet-azonosítót (session ID) vagy egy hozzáférési kulcsot (token)
  3. Az további kéréseknél a kliensnek ezzel a kapott adattal kell magát hitelesítenie

A hitelesítő adatok nem csak típusban, hanem az elküldés módjában is különbözhetnek. Ennek két fő módja:

  • Sütik (Cookie): a kliens bejelentkezésére küldött HTTP válaszban a szerver egy Set-Cookie fejlécben küldi el a hitelesítő adatot, amit a kliens sütiként tárol. A sütiket a böngészők automatikusan minden további kérésnél el fogják küldeni a szervernek.
  • Fejléc: a kliens bejelentkezésére küldött HTTP válaszban a szerver a válasz törzsében (body) küldi el az adatot, amit a kliens eltárol. Böngésző esetén jellemzően localStorage-ban, vagy sessionStorage-ban. Ezt követően a hitelesíteni kívánt kéréseknél a kliens oldalról a fejlécbe kell elhelyezni egy sort, ami tartalmazza ezt az adatot. Ez a fejléc az Authorization: <séma> <tartalom>. Sokféle séma létezik, mi két példát nézünk:
    • Basic: sima felhasználónév/jelszó páros, ez nem is igényli az előző lépéseket. A két "szó" közé egy kettőspont kerül, és az így kapott stringet base64 kódolással illesztjük a fejlécbe.
    • Bearer: vagyis a Bearer token, ide kerülhet például egy hosszú random-nak kinéző szöveg

Most pedig nézzük megy, hogy milyen adatokat küldünk 'hitelesítő adat'-ként:

  • Token: a tokenek egy azonosítót tartalmaznak, ami a szerver számára azonosítja a felhasználót. Az egyik legismertebb token standard a JWT, amely JSON formátumban tartalmaz adatokat a token kiállításáról, a felhasználóról, illetve egy digitális aláírást is magáról a token tartalmáról. Az aláíráshoz szükség van egy titkos kulcsra, amit csak a szerver ismer, és ennek segítségével ellenőrizni is tudja, hogy ugyanazzal a kulccsal írták-e alá a tokent, ebben az esetben megbízik a token tartalmában.
    • Előnye: a kiállított tokeneket nem kell a szerveren tárolni, csak a titkos kulcsot, vagyis állapottalan.
    • Hátránya: pont az előbbi miatt nem lehet érvényteleníteni a tokeneket, meg kell várni, hogy lejárjon. (igazából lehet, de azzal elveszti a rendszer az állapottalanságát)
  • Munkamenet-azonosító: pontosan az, aminek hangzik, és nem is több. Egy generált adat, amit a szerver állít elő, és el is tárolja az adatbázisában, ahol azt is számon tartja, hogy melyik azonosító melyik felhasználóhoz tartozik, meddig érvényes, stb.
    • Előnye: minden egyes alkalommal meg kell keresni az adatbázisban, vagyis egyszerűen és azonnal lehet érvényteleníteni.
    • Hátránya: állapotot, vagyis tárolást igényel a szerver oldalon.