Prezentare generală
Responsabili: Florin-Alexandru STANCU, Ioana-Alina TUDORACHE, Anne-Marie ONCIULESCU-DRAGOMIR, Alexandru-Ioan CĂRUŢAŞU, Mihăiţă-Petruţ DINU, Rareș-Alexandru BALAN, Razvan Popa, Alina-Andreea Pirlog, Alin-Calin Dutu, Gabriel Gutu-Robu, Mihai-Catalin Stan, Raluca-Monica Birladeanu, Alexandra Ana-Maria ION, Corina-Elena Ulariu, Cătălin LEORDEANU
Stai pe canapea, sâmbătă seara. Te plictisești. Te uiți lung la pereți, apoi la pisică, apoi la telecomandă. O ridici… dar vai! Nu știi la ce să te uiți. Netflix? Prea complicat. YouTube? Prea zgomotos. Într-un moment de inspirație demn de un hacker de Hollywood, îți spui: "Ce-ar fi să scriu un client HTTP?". Evident, pentru că așa gândește orice automatist normal într-o seară leneșă de weekend.
Așa începe aventura ta: nu cu popcorn, ci cu sockets. Nu cu seriale, ci cu GET și POST. Ținta? Să creezi un client HTTP în C/C++ care să poată comunica cu un REST API ca un adevărat internaut: politicos, precis și cu headers bine aranjați. Fără biblioteci de lux – doar cod curat, ambiție și un pic de cafea (sau ceai, dacă ești chill).
Hai să vedem ce poate face acest client HTTP – și dacă sâmbăta ta chiar n-a fost irosită.
Motivatie & Obiective
Un procent foarte mare din aplicațiile moderne este reprezentat de aplicații web.
Multe dintre aceste aplicații web, în ciuda complexității pe care o au, se bazează pe modelul clasic “client-server”.
Pentru a înțelege cum funcționează modelul client-server în contextul web modern, este nevoie să înțelegeți cum funcționează protocolul HTTP.
Obiectivele pe care le urmărim sunt:
- Înțelegerea mecanismelor de comunicare prin HTTP
- Interacțiunea cu un REST API
- Înțelegerea conceptelor des folosite în web precum JSON, sesiune, JWT
- Utilizarea unor biblioteci externe pentru manipularea obiectelor JSON REST API
Descriere generală
Serverul (infrastructură existentă) va expune un API (Application Programmable Interface) de tip REST (Representational State Transfer).
Puteți să vă gândiți la el ca la o cutie neagră ce primește o serie de intrări reprezentate de rute HTTP.
În urma cererilor HTTP, serverul efectuează o acțiune.
În contextul temei, serverul simulează un library online (de filme) și este deja complet implementat.
Clientul (pe care îl veți construi) este un program scris în C/C++ care acceptă comenzi de la tastatură (stdin) și trimite, în funcție de comandă, cereri către server.
Scopul lui este de a funcționa ca o interfață în linia de comandă (CLI) cu library-ul virtual.
Fiecare student are un singur utilizator de admin cu care se poate loga pentru a crea, șterge și vizualiza conturile utilizatorilor normali. Un user de admin are DOAR functionalitatile de gestiune a utilizatorilor, nu si de gestiune a filmelor / colectiilor.
JSON & Token JWT
JSON
JSON (JavaScript Object Notation) este un format de reprezentare / schimb de date text foarte popular, mai ales în sfera de programare Web, deoarece este și relativ ușor de construit & parsat de către mașini (în orice limbaj), cât și relativ inteligibil de către oameni (fapt ce ajută deseori la depanare):
{
"employee": {
"name": "sonoo",
"salary": 56000,
"married": true
}
}
Majoritatea API-urilor web (REST-ful) folosesc deseori această reprezentare
pentru a structura atât datele de intrare (e.g. POST body), cât și cele de
ieșire (corp răspuns HTTP), marcate prin antetul Content-Type: application/json.
La fel este folosit și de către serverul temei.
Astfel, pentru a parsa răspunsurile primite de la server, puteţi (şi e recomandat) să folosiţi o bibliotecă. Vă sugerăm parson [1] pentru C sau nlohmann [2] pentru C++, însă puteţi folosi orice (inclusiv o soluţie proprie), justificând alegerea în README.
[1] https://github.com/kgabis/parson
[2] https://github.com/nlohmann/json
Observație
‼️ Va trebui să includeți codul bibliotecilor în sursă, altfel arhiva nu va compila pe checker.
Token JWT
Tokenurile JWT (JSON Web Token) sunt o modalitate de transmitere a informaţiilor de autentificare/autorizare dintre un client şi un server. Acestea sunt codificate binar şi semnate pentru verificarea integrităţii. Astfel se asigură că un potenţial atacator nu poate modifica datele împachetate.
Pentru a trimite tokenul către server, este necesară adăugarea acestuia în headerul Authorization. Valoarea tokenului trebuie să fie prefixată de cuvântul Bearer.
Authorization: Bearer eijjkwuqioueu9182712093801293
Pentru mai multe informaţii puteţi să consultaţi documentaţia oficială:
Descriere Server
Datele de conectare
HOST: 63.32.125.183 PORT: 8081
Mod de funcționare
Serverul va permite efectuarea următoarelor acțiuni:
4.1 Autentificare admin
Ruta de acces:
POST /api/v1/tema/admin/login
Tip payload:
application/json
Payload:
{
"username": String,
"password": String
}
Răspuns:
🍪 Întoarce cookie de sesiune.
Erori tratate:
👎 Credențialele nu se potrivesc.
👎 Reautentificare când deja logat.
4.2 Adăugarea unui utilizator normal
Ruta de acces:
POST /api/v1/tema/admin/users
Tip payload:
application/json
Payload:
{
"username": String,
"password": String
}
Observații:
❗ Trebuie să demonstrați că aveți rol de admin.
❗ Userul aparține adminului curent.
Erori tratate:
👎 Lipsă rol admin.
👎 Informații incomplete/incorecte.
4.3 Vizualizare utilizatori normali
Ruta de acces:
GET /api/v1/tema/admin/users
Observații:
❗ Trebuie să demonstrați că aveți rol de admin.
Răspuns:
{
"users": [
{
"id": Number,
"password": String,
"username": String
}
]
}
Erori tratate:
👎 Lipsă permisiuni admin.
4.4 Ștergerea unui utilizator
Ruta de acces:
DELETE /api/v1/tema/admin/users/:username
e.g: /api/v1/tema/admin/users/user123
Observații:
❗ Necesită rol de admin.
Erori tratate:
👎 Lipsă rol admin.
👎 Username invalid.
4.5 Logout admin
Ruta de acces:
GET /api/v1/tema/admin/logout
Observații:
❗ Necesită autentificare.
Erori tratate:
👎 Neautentificat.
4.6 Autentificare utilizator
Ruta de acces:
POST /api/v1/tema/user/login
Tip payload:
application/json
Payload:
{
"admin_username": String,
"username": String,
"password": String
}
Răspuns:
🍪 Trebuie să demonstraţi că sunteţi autentificaţi!
Erori tratate:
👎 Credențialele nu se potrivesc.
👎 Reautentificare.
4.7 Cerere acces library
Ruta de acces:
GET /api/v1/tema/library/access
Observații:
❗ Necesită autentificare.
Răspuns:
🍪 Trebuie să demonstraţi că sunteţi autentificaţi!
Erori tratate:
👎 Neautentificat.
4.8 Vizualizare toate filmele
Ruta de acces:
GET /api/v1/tema/library/movies
Observații:
🍪 Trebuie să demonstraţi că aveţi acces la library! (JWT token)
Răspuns:
[
{
"id": Number,
"title": String
}
]
Erori tratate:
👎 Fără acces library.
4.9 Vizualizare detalii film
Ruta de acces:
GET /api/v1/tema/library/movies/:movieId
e.g: /api/v1/tema/library/movies/123
Observații:
🍪 Trebuie să demonstraţi că aveţi acces la library! (JWT token)
Răspuns:
{
"id": Number,
"title": String,
"year": Number,
"description": String,
"rating": Number
}
Erori tratate:
👎 Fără acces library.
👎 ID invalid.
4.10 Adăugare film
Ruta de acces:
POST /api/v1/tema/library/movies
Tip payload:
application/json
Payload:
{
"title": String,
"year": Number,
"description": String,
"rating": Number
}
Observații:
🍪 Trebuie să demonstraţi că aveţi acces la library! (JWT token)
Erori tratate:
👎 Fără acces library.
👎 Date invalide/incomplete.
4.11 Actualizare film
Ruta de acces:
PUT /api/v1/tema/library/movies/:movieId
Tip payload:
application/json
Payload:
{
"title": String,
"year": Number,
"description": String,
"rating": Number
}
Observații:
🍪 Trebuie să demonstraţi că aveţi acces la library! (JWT token)
Erori tratate:
👎 Fără acces library.
👎 ID invalid.
👎 Date invalide/incomplete.
4.12 Ștergere film
Ruta de acces:
DELETE /api/v1/tema/library/movies/:movieId
e.g: /api/v1/tema/library/movies/123
Observații:
🍪 Trebuie să demonstraţi că aveţi acces la library! (JWT token)
Erori tratate:
👎 Fără acces library.
👎 ID invalid.
4.13 Vizualizare colecții
Ruta de acces:
GET /api/v1/tema/library/collections
Observații:
🍪 Trebuie să demonstraţi că aveţi acces la library! (JWT token)
Răspuns:
[
{
"id": Number,
"title": String,
"owner": String,
"movies": [
{
"id": Number,
"title": String
}
]
}
]
Erori tratate:
👎 Fără acces library.
4.14 Vizualizare detalii colecție
Ruta de acces:
GET /api/v1/tema/library/collections/:collectionId
Observații:
🍪 Trebuie să demonstraţi că aveţi acces la library! (JWT token)
e.g: /api/v1/tema/library/collections/123
Răspuns:
{
"id": Number,
"title": String,
"owner": String,
"movies": [
{
"id": Number,
"title": String
}
]
}
Erori tratate:
👎 Fără acces library.
👎 ID invalid.
4.15 Adăugare colecție
Ruta de acces:
POST /api/v1/tema/library/collections
Tip payload:
application/json
Payload:
{
"title": String
}
Observații:
🍪 Trebuie să demonstraţi că aveţi acces la library! (JWT token)
❗ Owner este utilizatorul curent.
Erori tratate:
👎 Fără acces library.
👎 Date invalide/incomplete.
4.16 Ștergere colecție
Ruta de acces:
DELETE /api/v1/tema/library/collections/:collectionId
Observații:
🍪 Trebuie să demonstraţi că aveţi acces la library! (JWT token)
❗ Trebuie să fiți owner.
Erori tratate:
👎 Fără acces library.
👎 Nu sunteți owner.
👎 ID invalid.
4.17 Adăugare film în colecție
Ruta de acces:
POST /api/v1/tema/library/collections/:collectionId/movies
Tip payload:
{
"id": Number
}
Observații:
🍪 Trebuie să demonstraţi că aveţi acces la library! (JWT token)
❗ Trebuie să fiți owner.
Erori tratate:
👎 Fără acces library.
👎 Nu sunteți owner.
👎 Date invalide/incomplete.
4.18 Ștergere film din colecție
Ruta de acces:
DELETE /api/v1/tema/library/collections/:collectionId/movies/:movieId
e.g: /api/v1/tema/library/collections/5/movies/123
Observații:
🍪 Trebuie să demonstraţi că aveţi acces la library! (JWT token)
❗Trebuie să fiți owner.
❗ Filmul trebuie să existe în colecție.
Erori tratate:
👎 Fără acces library.
👎 Nu sunteți owner.
👎 ID invalid.
4.19 Logout utilizator
Ruta de acces:
GET /api/v1/tema/user/logout
Observații:
❗ Necesită autentificare.
Erori tratate:
👎 Neautentificat.
Observație
‼️ Toate functionalitatile mentionate pentru server sunt testate de checker-ul oferit, dar nu sunt incluse toate cazurile de testare pentru corner case-uri.
Testare server
Pentru a interacţiona neprogramatic cu serverul, puteţi folosi utilitare ce simulează clienţii HTTP, precum Postman [1], Insomnia [2] sau chiar clienţi scrişi de mână în alte limbaje de programare.
Clientul
Clientul va trebui să interpreteze comenzi de la tastatură pentru a putea interacţiona cu serverul. În urma primirii unei comenzi, clientul va forma obiectul json (dacă e cazul), va executa cererea către server şi va afişa răspunsul acestuia (de succes sau de eroare). Procesul se repetă până la introducerea comenzii exit.
‼️ Atât comenzile cât şi câmpurile împreună cu valorile aferente se scriu pe linii separate!
‼️ Conexiunea la server trebuie realizata DOAR cu API-ului de sockets! (ca in laboratorul de HTTP)
Datele introduse de către utilizator de la tastatura sunt cele marcate cu text astfel!
Listă comenzi
- login_admin - efectuează autentificarea pentru admin (doar admin)
- add_user - adaugă un nou utilizator normal (doar admin)
- get_users - cere toti utilizatorii de pe server (doar admin)
- delete_user - șterge un utilizator normal (doar admin)
- logout_admin - efectuează delogarea pentru admin (doar admin)
- login - efectuează autentificarea pentru utilizator normal
- get_access - cere acces pentru colectia de filme
- get_movies - cere toate filmele de pe server
- get_movie - cere informaţie despre un film
- add_movie - adaugă un film
- delete_movie - șterge un film
- update_movie - actualizeaza datele unui film
- get_collections - cere toate colecțiile de filme de pe server
- get_collection - cere informaţie despre o colecție de filme
- add_collection - adaugă o colecție de filme
- delete_collection - șterge o colecție de filme
- add_movie_to_collection - adaugă un film intr-o colecție
- delete_movie_from_collection - șterge un film dintr-o colecție
- logout - efectueaza delogarea utilizatorului
- exit - efectueaza ieșirea din program
Observație
‼️ Textul mesajelor returnate de server sunt alese de voi, însă trebuie să țineți cont de următoarele convenții:
- dacă rezultatul HTTP a fost un cod de eroare, mesajul să conțină cuvantul ERROR
- dacă operațiunea a avut loc cu succes, atunci să conțină cuvantul SUCCESS
‼️ Punctajele pentru fiecare comanda sunt raportate la 100p. De exemplu, comanda get_users valoreaza 10p/100p.
Comenzi
1. Login_admin (2.5p)
Oferă prompt pentru username și password.
login_admin
username=something
password=something
Input
login_admin
username=something
password=something
Output
SUCCESS: Admin autentificat cu succes
2. Add_user (5p)
Oferă prompt pentru username și password.
add_user
username=something
password=something
Input
add_user
username=test
password=test
Output
SUCCESS: Utilizator adăugat cu succes
3. Get_users (10p)
Nu necesită parametri.
get_users
Input
get_users
Output
SUCCESS: Lista utilizatorilor
#1 test:test
#2 john:doe
4. Delete_user (5p)
Oferă prompt pentru username.
delete_user
username=something
Input
delete_user
username=test
Output
SUCCESS: Utilizator șters
5. Login (2.5p)
Oferă prompt pentru admin_username, username și password.
login
admin_username=admin
username=test
password=test
Input
login
admin_username=admin
username=test
password=test
Output
SUCCESS: Autentificare reușită
6. Get_access (10p)
Nu necesită parametri.
get_access
Input
get_access
Output
SUCCESS: Token JWT primit
7. Get_movies (10p)
Nu necesită parametri.
get_movies
Input
get_movies
Output
SUCCESS: Lista filmelor
#1 The Dark Knight
#2 Snow White
8. Get_movie (5p)
Oferă prompt pentru id.
get_movie
id=10
Input
get_movie
id=10
Output
SUCCESS: Detalii film
title: The Dark Knight
year: 2010
description: sci-fi
rating: 8.8
9. Add_movie (5p)
Oferă prompt pentru title, year, description, rating.
add_movie
title=Inception
year=2010
description=sci-fi
rating=8.8
Input
add_movie
title=Inception
year=2010
description=sci-fi
rating=8.8
Output
SUCCESS: Film adăugat
10. Delete_movie (5p)
Oferă prompt pentru id.
delete_movie
id=10
Input
delete_movie
id=10
Output
SUCCESS: Film șters cu succes
11. Update_movie (2.5p)
Oferă prompt pentru id și câmpurile de actualizat.
update_movie
id=2
title=New Title
year=2009
description=sci-fi
rating=10.0
Input
update_movie
id=2
title=New Title
year=2009
description=sci-fi
rating=10.0
Output
SUCCESS: Film actualizat
12. Get_collections (10p)
Nu necesită parametri.
get_collections
Input
get_collections
Output
SUCCESS: Lista colecțiilor
#1: Colectie A
#2: Colectie B
13. Get_collection (5p)
Oferă prompt pentru id.
get_collection
id=10
Input
get_collection
id=10
Output
SUCCESS: Detalii colecție
title: Favorite Movies
owner: test_user
#3: Inception
#5: Interstellar
14. Add_collection (5p)
Oferă prompt pentru title, num_movies și movie_id pentru fiecare film.
add_collection
title=Must See
num_movies=2
movie_id=1
movie_id=3
Input
add_collection
title=Must See
num_movies=2
movie_id[0]=1
movie_id[1]=3
Output
SUCCESS: Colecție adăugată
15. Delete_collection (5p)
Oferă prompt pentru id.
delete_collection
id=10
Input
delete_collection
id=10
Output
SUCCESS: Colecție ștearsă
16. Add_movie_to_collection (2.5p)
Oferă prompt pentru id.
add_movie_to_collection
collection_id10
movie_id3
Input
add_movie_to_collection
collection_id=10
movie_id=3
Output
SUCCESS: Film adăugat în colecție
17. Delete_movie_from_collection (2.5p)
Oferă prompt pentru id.
delete_movie_from_collection
collection_id=10
movie_id=3
Input
delete_movie_from_collection
collection_id=10
movie_id=3
Output
SUCCESS: Film șters din colecție
18. Logout_admin (2.5p)
logout_admin
Input
logout_admin
Output
SUCCESS: Admin delogat
19. Logout (2.5p)
logout
Input
logout
Output
SUCCESS: Utilizator delogat
20. Exit (2.5p)
exit
Input
exit
Output
Programul se închide fără afișarea unui mesaj.
Exemplu sesiune
Comenzile vor fi testate în flux. Exemplele de mai jos nu reprezintă o listă exhaustivă a cazurilor care vor fi testate pentru corectarea temei.
1. Login
login
admin_username=test
username=test
password=test
Cum aceasta comandă este prima din flux, utilizatorul "test" cel mai probabil nu există, întrucât nu a fost încă creat de către admin.
Este datoria clientului să primească răspunsul de la server și să informeze utilizatorul de acest fapt.
2. Login admin
login_admin
username=admin
password=admin
Aici se vor folosi datele de autentificare pentru admin de pe Moodle. Fiecare student are un cont de admin propriu asignat.
Această comandă va avea succes. Puteți afișa un mesaj de succes precum:
SUCCESS: 200 - OK sau SUCCESS: Admin logat cu succes!
3. Add user
add_user
username=test
password=test
Cum utilizatorul "test" nu există, această comandă va avea succes.
Puteți afișa un mesaj de succes precum:
SUCCESS: 200 - OK - Utilizator adăugat cu succes!
4. Logout admin
logout_admin
5. Get movie
get_movie
id=10
În acest moment, utilizatorul nu a executat o cerere de login și nici o cerere de acces.
Apelul va eșua. Clientul va primi răspunsuri corespunzătoare care trebuie să informeze și utilizatorul.
6. Login (cu parolă greșită)
login
admin_username=test
username=test
password=test2
În acest moment, utilizatorul a executat o cerere de login cu parolă incorectă.
Apelul va eșua. Clientul trebuie să afișeze un mesaj informativ.
7. Login (cu date corecte)
login
admin_username=test
username=test
password=test
Apelul se va executa cu succes.
Puteți afișa mesaje precum:
SUCCESS: 200 - OK - Bun venit!
8. Get access
get_access
9. Get movie (film inexistent)
get_movie
id=10
Dacă filmul cu id-ul 10 nu există, clientul va primi un răspuns corespunzător.
Mesaj sugestiv:
ERROR: Filmul cu id=10 nu există!
10. Add movie (date invalide)
add_movie
title=test
year=test
description=test
rating=this will not work
Clientul trebuie să execute o validare a datelor și să informeze utilizatorul despre incorectitudinea acestora.
11. Logout
logout
12. Get movie (după logout)
get_movie
id=10
După apelul logout, clientul trebuie să piardă accesul la library (chiar dacă tokenul este tehnic încă valid).
Puteți afișa un mesaj de eroare: ERROR: Este necesară logarea.
Sistem de punctare
Punctarea se efectuează individual, pentru fiecare comandă realizată cu succes într-un flux de comenzi (vezi secțiunea 5.Exemplu sesiune).
O comandă este considerată funcțională dacă, prin introducerea ei, se trimite cererea corectă către server și se afișează răspunsul acestuia (de succes sau de eroare).
Formatul răspunsurilor trebuie respectat conform celor precizate anterior.
În plus, trebuie ținut cont de accesul la library-ul de filme.
De exemplu, dacă în urma apelului logout, utilizatorul încă mai are acces la library, comanda logout nu va fi considerată funcțională.
Comenzile care trimit date la server (cele care execută POST, PUT, GET și DELETE pe id-uri) sunt considerate funcționale dacă reușesc să trimită cu succes informația corectă la server.
De exemplu, o comandă de autentificare care parsează greșit de la tastatură username sau password, dar totuși trimite către server informația preluată greșit și afișează întotdeauna răspunsul de eroare al serverului nu va fi punctată.
Checker
Pentru a verifica ușor corectitudinea soluției voastre, aveți la dispoziție un checker, care este integrat și pe Moodle.
Acesta va rula automat când încărcați arhiva și va afișa punctajul vostru curent.
Datele pentru loginul de admin sunt username și parola din assignment-ul Tema3_myAdmin, așa cum este ilustrat în imaginea de pe platformă.
Arhiva
Arhiva temei trebuie să conţină sursele de cod, un Makefile şi un Readme prin care să explicaţi implementarea soluţiei voastre. Trebuie justificată şi explicată şi utilizarea bibliotecii de parsare JSON pe care aţi ales să o folosiţi.
‼️ Arhiva va avea numele Grupa_Nume_Prenume_Tema3PC. Formatul arhivei trebuie să fie .zip.
Structura recomandată:
./
├── client.c
├── client.h
├── helper.c
├── helper.h
├── parson.c
├── parson.h
├── requests.c
├── requests.h
├── Makefile
└── README.md
Puteți avea și subdirectoare, dar fisierele Makefile, README.md și binarul rezultat client trebuie să fie în rădăcina arhivei.
Dacă folosiți biblioteci externe (ex: pentru parsare JSON), este OBLIGATORIU să le includeți în arhivă și să le integrați în Makefile!
‼️ Sistemul de testare NU VA AVEA aceste biblioteci instalate, iar compilarea va eșua (⇒ 0 puncte).
Mentiuni
IMPORTANT! A fost implementat în server și un mecanism de protecție pentru limitarea numărului de cereri.
Dacă trimiteți prea multe cereri prea rapid, veți primi un răspuns de forma:
Too many requests, please try again later.
Nu este nevoie să țineți cont de acest aspect sau să adăugați un caz special în implementare.
IMPORTANT! Atenție la tratarea titlurilor de filme sau colecții ce conțin spații.
Datele, headerele, cookie-urile și token-urile trebuie puse în cerere și extrase din răspuns automat.
Hardcodarea acestora va duce la anularea punctajului pentru cerința în care au fost utilizate.
Pentru mai multe detalii legate de modul de funcționare, consultați Laboratorul 9.
‼️ Numele comenzilor trebuie respectat întocmai cum este precizat în enunţ.
‼️ Scrierea comenzilor cu alt nume duce către depunctare pentru comanda respectivă.
‼️ Numele câmpurilor din obiecte trebuie respectat întocmai cum este precizat în enunț.
Altfel, veți primi permanent erori de pe server, deci comanda va fi depunctată.
‼️ Formatul comenzilor trebuie respectat întocmai cum este precizat în enunț. Fiecare comandă, respectiv câmp și valoarea sa, trebuie să fie pe linii separate. Formatul nerespectat duce la pierderea punctajului pentru acea comandă.
‼️ Schema de denumire a arhivei trebuie respectată întocmai. Modificarea acesteia duce la depunctarea totală a temei.
‼️ Lipsa README duce la depunctarea totală a temei.
FAQ
-
Q: Cum demonstrez că utilizatorul are acces la library?
A: Un utilizator are acces la library-ul de filme dacă a executat un apel “access”. În urma apelului ar trebui să fie prezent un token JWT. Acest token este dovada accesului la library. Voi trebuie să vă bazați întotdeauna pe răspunsul venit din partea serverului.
-
Q: Putem folosi codul din laborator?
A: Da! Laboratorul de HTTP poate fi folosit ca schelet de cod pentru această temă. Dacă vreți să integrați altă bibliotecă externă, ar trebui să cereți o aprobare pe forumul temei.
-
Q: Am observat că dacă folosesc comanda logout avem în continuare acces la library-ul de filme cu token-ul obținut anterior. De ce?
A: Serverul nu invalidează tokenele. Puteți însă să eliberați zona de memorie asociată tokenului pe client.
-
Q: Pentru fiecare comandă a clientului va trebui să facem un singur call HTTP ?
A: Nu! Este posibil să combinați mai multe apeluri HTTP ca să implementați o comandă.
-
Q: Va trebui să testăm, dacă se introduce pentru year sau rating altceva în afara de un număr?
A: Da! Validarea datelor este responsabilitatea voastră.
-
Q: La username și la password este permis să fie spații?
A: Nu!
-
Q: În descrierile sau titlurile de filme pot să apară și numere, și spații, și cifre?
A: Da! Validarea datelor este responsabilitatea voastră.