diff --git a/src/content/docs/projects/Eventownik/Standaryzacja API.mdx b/src/content/docs/projects/Eventownik/Standaryzacja API.mdx new file mode 100644 index 0000000..f437991 --- /dev/null +++ b/src/content/docs/projects/Eventownik/Standaryzacja API.mdx @@ -0,0 +1,150 @@ +--- +title: Standaryzacja API +description: Standardy wykorzystane w Eventownik V3 +--- + +## Nazewnictwo endpointów + +- zakładając przypadek, w którym domena nie posiada prefixu ‘api', powinien być to pierwszy człon endpointu, +- kolejny człon powinien zawierać informację dotyczą wersjonowania, przykładowo ‘v1', ‘v2', +- następny człon powinien zawierać informację o dostępności, tj. ‘external' dla dostępu publicznego lub ‘internal' dla dostępu wewnętrznego, +- następna powinna być nazwa zasobu, w liczbie mnogiej, np. ‘users', ‘events', +- kolejnym członem powinna być wywoływana funkcjonalość, np. ‘register', ‘login', +- indeksowanie zasobów powinno się odbywać po jednym, ustalonym przez członków projektu kluczu + +### Przykładowy routing: + +- api.eventownik.pl/v1/internal/events/:id +- api.eventownik.pl/v1/external/events/:id + +### Lista endpointów projektu Eventownika: + +[Eventownik Endpoints](https://api.eventownik.solvro.pl/docs) + +## Ogólny format odpowiedzi + +- formatem odpowiedzi powinien być obiekt umieszczony w obiekcie data/data[], +- wszystkie atrybuty paginacji oraz całkowita liczba rekordów powinna znajdować się w obiekcie metadata, +- metody post/put powinny zwracać zaktualizowany obiekt, +- metoda delete powinna zwracać no content, + - w przypadku, gdy usuwany obiekt nie istnieje powinien zostać wywołany NotFoundError +- odpowiedzi nie powinny zawierać zbędnych informacji, typu : \{"message" : "X … successfully."\}, czy też zduplikowany status code + +Przykładowy format odpowiedzi: + +```json +data: [ +{ + "id": 1, + "email": "example@example.com", + "created_at": "2025-08-07T12:34:56.000" + }, + { + "id": 2, + "email": "example2@example.com", + "created_at": "2025-08-07T12:40:00.000" + } + ], +metadata: { + "page": 0, + "per_page" : 10, + "total" : 2 +} +``` + +## Ogólny format błędów + +- do walidacji danych jak i zwracania odpowiedzi błędu, wykorzystujemy domyślną dla NestJS paczkę class-validator, +- błędy powinny być oznaczone odpowiednim status codem + +## Format parametrów metody 'GET' + +### Paginacja + +- ?page=<number> - numer strony (domyślnie 0) +- ?perPage=<number> - liczba obiektów na stronę (opcjonalne, w przypadku gdy wartość nie została podana, wykorzystywana jest domyślna wartość 10 elementów na stronę) + +### Sortowanie + +- ?sort[<column>]=asc/desc, (domyślnie ascending) + +### Filtrowanie + +- filter[<column>]=<value> +- filter[<column>][gt/gte/lt/lte]=<value> (typu numerycznego/daty) +- filter[<column>][not/like]=<value> +- filter[<column1>]=<value1>>...&filter[<columnN>]=<valueN> - dla wielu filtrów +- filter[<column1>]=<value1>,<value2> - dla filtrowania typu IN ( z możliwością podania kilku kolumn, + w takim przypadku warunek filtrowania jest spełniony, gdy istnieje dowolna z podanych wartości w dowolnej z podanych kolumn) + +### Relacje + +- ?join=<relation_name> +- ?join=<relation_name1>,…,<relation_nameN> - dla wielu relacji + +### Select + +- ?select=<column> +- ?select=<column1>,…,<columnN> + +Domyślnie operacja select bez podania nazw kolumn zwróci wszystkie kolumny z danej tabeli. Alternatywnie, istnieje opcja wykluczenia kolumn. + +Przykładowe użycie wykluczenia: + +- ?select=-<column1>,…,-<columnN> + +### Przykład wykorzystania parametrów + +Endpoint: `api.eventownik.pl/v1/internal/events/:eventId/participants?page=1&perPage=20&sort[name]=asc&filter[name][like]=Jakub` + +## Autoryzacja + +- w późniejszej fazie projektu, planowana jest implementacja Solvro Auth + +## Pozostałe nagłówki + +1. accept: application/json, +2. request-id w celu implementacji tracing'u + +## Serializacja i formatowanie danych + +1. Daty powinny być zwracane w standardzie ISO 8601 bez stref czasowych, + + przykład daty: 2012-01-01T00:00:00, + +2. Zasoby oraz jego atrybuty powinny być zwracane w snake_case'ie + +## Dokumentacja + +Do tworzenia dokumentacji API wykorzystujemy Swaggera. +[Dokumentacja Swaggera dla NestJS](https://docs.nestjs.com/openapi/introduction) + +1. Grupowanie endpointów za pomocą ‘@ApiTags' powinno odzwierciedlać faktyczny routing, +2. Dla skomplikowanych/niejednoznacznych odpowiedzi zaleca się dodanie opisu (descriptions), +3. Dokumentacja powinna obejmować wszystkie możliwe odpowiedzi (dla powtarzalnych odpowiedzi można zastosować dekorator dla całego kontrolera), +4. Za pomocą CLI, jesteśmy w stanie automatycznie generować annotacje dla modeli/DTO, domyślnie generowane są tylko dla konkretnych plików, tj. ‘_.dto.ts', ‘_.entity.ts', +5. Dla projektu powinno zostać wybrane estetyczne oraz przejrzyste UI (lub stworzone przez zespół) + +## Testy + +Do przeprowadzania testów korzystamy z domyślnych dla NestJS pakietów: Jest oraz Supertest. + +1. Przede wszystkim, należy skupić się, aby testy powstawały równolegle z rozwojem aplikacji, +2. Testy powinny obejmować, zarówno "scenariusze" pomyślne/zgodne z założeniem działania aplikacji, jak i te zakończone niepowodzeniem, w celu sprawdzenia obsługi błędów, +3. Testy powinny sprawdzać istotne funkcjonalności aplikacji - nie należy się kierować wysokim pokryciem kodu, +4. Podział testów: + a. jednostkowe - jedynie dla złożonych funkcjonalności, + b. integracyjne - powinny stanowić większość testów, + c. e2e - tworzone przez zespół frontendowy + +## Obsługa plików + +Do obsługi plików, wykorzystujemy domyślny dla NestJS pakiet ‘multer', obsługuje on dane przesyłane w formacie ‘multipart/form-data'. + +Zalecane jest również wykorzystanie walidacji metadanych pliku podczas przesyłania, przykładowo dla: + +- liczby przesyłanych plików, +- typu przesyłanego pliku (domyślnie dla NestJS jest to mimetype), +- maksymalnego rozmiaru pliku + +Natomiast same pliki będą przechowywane na hostowanym przez nas systemie S3 (MinIO).