REST APIs - Best Practices

Interesant Apiary.

As avea doar o observatie (la exemplul dat), intr-un REST API, resursele trebuie sa fie sub forma noun nu verb (iar la autentificare acel /login e verb; login s-ar putea inlocui foarte bine cu sessions)

2 Likes

@bokordani: dacă vorbești de exemplul tesla, este evident cine este responsabil.

Dacă vorbești despre API-ul meu, deja am chelit toate metodele:

Din

user/login
user/create
user/delete
message/get
message/send
message/delete
messagess/get

au rămas:

user
message/{id}
messages

Primele două acceptă GET, POST și DELETE, ultima doar GET.

1 Like

@iamntz Exemplul la care ma refeream era cel tesla, intr-adevar.
In ceea ce priveste exemplul tau, eu as folosi doar doua resurse:

/users
/messages/:id

cu mentiunea ca GET /messages si GET /messages/:id returneaza rezultate diferite (in primul caz se returneaza toate mesajele, si in cel de-al doilea caz doar cel cu id-ul respectiv).

Varianta cu user/login unde ai incadrat-o ?

1 Like

GET user. Dar nu sunt 100% sigur că e varianta corectă.

Sugestii?

Related:

Eu in REST API-ul pe care il intretin (mai degraba RESTful, pentru ca nu respecta conditia HATEOAS), am separat resursele in sessions si users (fiecare cu GET, POST si DELETE, iar users are in plus PUT si PATCH).

Apelul de tip GET il folosesc exclusiv pentru a primi informatiile legate de o resursa existenta (fie ca vorbim despre GET /resource sau GET /resource/:id), iar POST pentru a crea o resursa noua.

sessions este resursa pentru autentificare; se realizeaza acest lucru facand un apel POST /sessions?username=someuser&password=somepass si imi returneaza id, user_id, token, start_date, end_date, etc.

users este resursa care se ocupa exclusiv de user (creare de user nou, editare, stergere). Un apel de tip GET /users/:id mi-ar putea returna id, username, password, email, status, subscription_type, etc, in timp ce GET /users imi returneaza o colectie de astfel de informatii (in functie de permisiunile celui care face request-ul, ar putea returna toti userii dintr-o companie spre exemplu).

2 Likes

Fiind stateless, nu cred că este nevoie de nici un token sau o sesiune. Nu?

Aplicația mea funcționează așa:

  1. Trimit user/pass spre server pentru a stabili dacă userul e valid sau este nevoie de înregistrare
  2. După ce stabilesc că e un user valid, afișez restul aplicației iar fiecare request spre server este însoțit și de user/pass.

Iar asta nu pentru că am decis eu ci pentru că există în cerințele inițiale. Acum că o fi bine, că o fi rău… Știi cum se zice: numai timpul va stabili :blush:

Din cate stiu, ideea de stateless se refera la faptul ca nu se tine cont de starea anterioara (apelul anterior). Fiecare stare curenta (apel curent) se proceseaza in mod independent de starile anterioare (apelurile anterioare). Mie unul mi se pare riscant sa circule perechea de user/pass la fiecare apel catre API.

Eu am mers pe varianta token + nonce + timestamp + api_key + signature (signature e un hash generat in functie de apelul catre API), exceptie fiind POST /sessions, unde in loc de token se trimite perechea de user/pass (impreuna cu nonce + timestamp + api_key + signature). Daca nonce, timestamp, api_key sau signature nu corespunde, se returneaza eroare 401. (astfel se previn atacuri de tip man-in-the-middle, refolosirea aceluiasi apel, folosirea unui apel vechi neutilizat, etc).

Varianta cu token are mai multe avantaje (clientul poate pastra o sesiune pe o perioada indelungata, datele sensibile user/pass sunt transmise o singura data, pot exista instante multiple si fiecare poate fi stearsa individual, etc).

Resursa pentru autentificare dupa care m-am ghidat:
http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/

P.S. Poate ar fi bine sa se faca un topic separat legat de REST API, avand in vedere ca am deviat de la Apiary :smile:

4 Likes
2 Likes

Related: