Nije REST svaki API

4 min

Napravio si HTTP API intefejs (endpoints) i nazivaš ga “REST API”. Najverovatnije je da nisi u pravu. No ne brini, svima nam se to događa. REST je nešto više.

Najkraća definicija REST-a je sadržana u sledećoj formuli:

WWW := URI + HTTP + MIME + Hypermedia.

REST je način da se ostvari inter-operabilinost između kompjuterskih sistema na Internetu. Korišćenjem protokola, tipova sadržaja i URI-ja se definišu resursi i način kako se njima manipuliše. No bez hypermedia nema potpunog REST APIja.

REST nije specifikacija, već preporuka. To čini stvari podložnim različitim tumačenjima i implementacijama. Kako bilo, neka pravila se mogu izvući. Ipak, to su i dalje samo predlozi (ovde i subjektivni), a ne definicije koje treba slepo slediti.

I još nešto: napravi REST API nije nimalo jednostavno.

Odlike REST APIja

Koristi množinu za listu resursa, a jedninu za konkretan resurs

GET /users
GET /user/123

Međutim, češći je slučaj da se koristi množina u oba slučaja:

GET /users/173

ID resursa je deo URI; atributi se navode u parametrima

Kada se resurs dobavlja svojim ID, on se navodi u URI. Primer:

GET /users/173

Resurs koji se dobavlja pretragom po nekom od atributa:

GET /users?email=joe@oblac.com

Svaki resurs ima link na sebe

GET /user/173
{
  "id" : 173,
    "name" : "Joe",
    "_links": {
      "self":{"href": "http://oblac.com/user/173"},
      "html":{"href": "http://oblac.com/user.html?id=173"}
  }
}

Lista resursa sadrži navigacione linkove

GET /users?start=15
{
  "result": [
    {"id": 1},
    {"id": 2},
    ...
  ],
  "_links": {
    "prev" : {"href" : "http://oblac.com/users?start=10"},
    "next" : {"href" : "http://oblac.com/users?start=20"},
    "first": ...
    "last" : ...
  }
}

Vrati kompozitni resurs kada to ima smisla

Kada resurs ima smisla jedino u kontekstu roditelja, vrati ga ugnježdenog:

GET /persons/1
{
  "name" : "Freedy",
  "address" : {
    "type" : "home",
    "street" : "Elm street"
  }
}

Ali isto tako:

GET /persons/1/address
{
  "type" : "home",
  "street" : "Elm street"
}

Zavisno od načina korišćenja treba identifikovati nove resurese koji su agregacija postojećih da bi smanjili učestanost komunikacije sa serverom.

Tretiraj atribute resursa kao posebne resurse

Ako je element resursa dovoljno važan i često se koristi, može da predstavlja resurs za sebe. Primer:

GET /users/173/name
GET /users/ids

POST vs PUT

PUT je idempotentna operacija: ako se ponovi više puta, rezultat je uvek isti. PUT služi da napravi resurs ako ne postoji ili da izmeni postojeći resurs.

POST uvek pravi novi resurs.

Dakle:

POST /report
PUT /report/1029

Parcijalne izmene

Često treba izmeniti nekoliko atributa resursa. Obično se to postiže slanjem PUT requesta sa delimično definisanim resursom:

PUT /users/123
{"status":false}

Alternativno se može koristi PATCH metod, noviji, pa stoga i manje podržan.

HATEOAS

Princip hipermedije je da svaki HTTP response sadrži linkove koji korespondiraju na sve akcije koje klijent može da izvrši. Dakle, zavisno od trenutnog stanja aplikacije, svaki response opisuje sve akcije koje su dostupne. Server dinamički menja koje su akcije dostupne, a klijent bi trebalo da se sam adaptira na izmene.

Trenutno stanje resursa je kombinacija:

HATEOAS (Hypermedia as the Engine of Application State) je krajnji nivo u poznatoj lestvici zrelosti REST APIja koju je sastavio Martin Fowler. Ova osobenost REST APIja pruža informacije kako navigirati i koristiti REST API dinamički, uključujući hipermedia linkove u response.

Jednostavan test za vaš API može biti sledeće: dovuci resurs i probaj da navigiraš kroz sve ponuđene linkove. Na sličan način kako prolaziš Web sajtom prateći linkove, tako i ovde, u domenu REST APIja, bi trebalo da možeš da dođeš do svih drugih resursa i akcija koje se mogu izvesti nad njima. Simple as that.

🧧
Nisam definisan svojim stavovima. Stavove usvajamo, menjamo, nadograđujemo, ali oni ne čine nas same. Manje je važno da li se slažemo, koliko da se razumemo.