diff --git a/Backend/elso gyakorlat/Egyéni Feladat – User Management Rendszer.pdf b/Backend/elso gyakorlat/Egyéni Feladat – User Management Rendszer.pdf new file mode 100644 index 0000000..9dafb3c Binary files /dev/null and b/Backend/elso gyakorlat/Egyéni Feladat – User Management Rendszer.pdf differ diff --git a/Backend/elso gyakorlat/FELADAT_LEIRAS_USER_MANAGEMENT.md b/Backend/elso gyakorlat/FELADAT_LEIRAS_USER_MANAGEMENT.md deleted file mode 100644 index 48c2975..0000000 --- a/Backend/elso gyakorlat/FELADAT_LEIRAS_USER_MANAGEMENT.md +++ /dev/null @@ -1,1564 +0,0 @@ -# User Management Rendszer - Feladat Leírás - -## Projekt Áttekintés - -Egy **User Management (felhasználó kezelési)** rendszer elkészítése Node.js és Express.js használatával, **Clean Architecture** elveket követve, **CQRS (Command Query Responsibility Segregation)** pattern alkalmazásával. - -## Célkitűzés - -Egy RESTful API létrehozása felhasználók kezeléséhez (CRUD műveletek), amely követi a modern szoftver architektúra elveket és jól strukturált, karbantartható kódot eredményez. - ---- - -## Technológiai Stack - -### Kötelező Technológiák -- **Node.js** (v18 vagy újabb) -- **Express.js** (v5.2.1 vagy újabb) - Web framework -- **ES6 Modules** - `import/export` szintaxis használata -- **JSON File Storage** - Adattárolás fájl alapú megoldással (későbbi adatbázis integrációhoz előkészítve) - -### Fejlesztői Eszközök -- **nodemon** - Automatikus újraindítás fejlesztés közben - ---- - -## Architektúra Áttekintés - -A projekt **4 fő réteget** tartalmaz: - -``` -src/ -├── API/ # Prezentációs réteg (Web API) -├── Application/ # Üzleti logika réteg (CQRS) -├── Domain/ # Domain modell és interfészek -└── Infrastructure/ # Adatelérési réteg és külső szolgáltatások -``` - -### Rétegek Részletes Leírása - -#### 1. **Domain Réteg** (Domain Layer) -- **Felelősség**: Az alkalmazás magját képező interfészek és domain modellek -- **Tartalma**: Repository interfészek (IUserRepository) -- **Függőség**: Nincs más rétegre való függősége - -#### 2. **Infrastructure Réteg** (Infrastructure Layer) -- **Felelősség**: Technikai implementációk (adatbázis, fájlkezelés, külső API-k) -- **Tartalma**: Repository implementációk, adattárolás -- **Függőség**: Domain rétegtől függ (implementálja az interfészeket) - -#### 3. **Application Réteg** (Application Layer) -- **Felelősség**: Üzleti logika, use case-ek implementálása -- **Tartalma**: Commands, CommandHandlers, Queries, QueryHandlers -- **Függőség**: Domain rétegtől függ -- **CQRS Pattern**: Írás (Command) és olvasás (Query) műveletek szétválasztása - -#### 4. **API Réteg** (API Layer) -- **Felelősség**: HTTP kérések kezelése, routing, válaszok küldése -- **Tartalma**: Controllers, Routers, Server konfiguráció -- **Függőség**: Application és Infrastructure rétegtől függ - ---- - -## CQRS Pattern Magyarázat - -### Mi az a CQRS? - -**Command Query Responsibility Segregation** - Az írási és olvasási műveletek szétválasztása. - -### Command (Parancs) - Írási műveletek -- Megváltoztatja a rendszer állapotát -- Nem ad vissza értéket (vagy csak a létrehozott entitást) -- Példák: CreateUser, UpdateUser, DeleteUser - -**Struktúra:** -1. **Command osztály** - Tartalmazza a parancs adatait -2. **CommandHandler osztály** - Végrehajtja a parancsot, validálja az adatokat - -### Query (Lekérdezés) - Olvasási műveletek -- Nem változtatja meg a rendszer állapotát -- Adatokat ad vissza -- Példák: GetAllUsers, GetUserById - -**Struktúra:** -1. **Query osztály** - Tartalmazza a lekérdezés paramétereit -2. **QueryHandler osztály** - Végrehajtja a lekérdezést - ---- - -## Részletes Implementációs Útmutató - -### 1. Projekt Inicializálás - -#### 1.1 Projekt struktúra létrehozása - -``` -Backend/ -└── elso gyakorlat/ - ├── package.json - └── src/ - ├── API/ - │ ├── server.js - │ ├── controllers/ - │ │ └── userController.js - │ └── routers/ - │ └── userRouter.js - ├── Application/ - │ └── users/ - │ ├── command/ - │ │ ├── createUserCommand.js - │ │ ├── createUserCommandHandler.js - │ │ ├── updateUserCommand.js - │ │ ├── updateUserCommandHandler.js - │ │ ├── deleteUserCommand.js - │ │ └── deleteUserCommandHandler.js - │ └── query/ - │ ├── getAllUsersQuery.js - │ ├── getAllUsersQueryHandler.js - │ ├── getUserByIdQuery.js - │ └── getUserByIdQueryHandler.js - ├── Domain/ - │ └── IUserRepository.js - └── Infrastructure/ - ├── user.json - └── userRepository.js -``` - -#### 1.2 package.json létrehozása - -**Cél**: Node.js projekt konfigurációs fájl létrehozása ES6 modul támogatással. - -**Részletes leírás:** - -A `package.json` az **npm projekt szíve** - tartalmazza a metaadatokat, függőségeket és script-eket. - -**Kulcsfontosságú mezők:** - -**1. Alapinformációk:** -- `name`: Projekt neve (lowercase, kötőjellel) -- `version`: Verzió szám (semantic versioning: MAJOR.MINOR.PATCH) -- `description`: Rövid leírás -- `main`: Belépési pont (itt nem használt) - -**2. `"type": "module"` ⚠️ KRITIKUS!** -- Engedélyezi az ES6 modulok használatát (`import/export`) -- Nélküle csak `require()`/`module.exports` működne (CommonJS) -- Ez kötelező, hogy `import` szintaxist használhassunk! - -**3. Scripts:** -- `start`: A szerver indítása nodemon-nal - - `nodemon src/API/server.js` - automatikus újraindítás fájl módosításkor - - Így nem kell minden változtatás után manuálisan újraindítani -- `test`: Placeholder teszt script (később Jest/Mocha tesztek jöhetnek ide) - -**4. Dependencies (Futásidejű függőségek):** -- `express`: ^5.2.1 - Web framework - - `^` (caret): Automatikus minor/patch update-ek engedélyezése - - 5.x.x verzió tartományon belül -- `nodemon`: ^3.1.11 - Fejlesztői szerver automatikus újraindítása - - Érdemes `devDependencies`-be tenni (csak fejlesztéshez kell) - -**Létrehozási módok:** - -**Manuális:** -Hozd létre a fájlt és másold be a tartalmat. - -**npm init:** -```bash -npm init -y # Gyors, alapértelmezett értékekkel -``` -Utána add hozzá: `"type": "module"` - -**Későbbi bővítések:** -```json -"devDependencies": { - "nodemon": "^3.1.11", // Ide kellene - "jest": "^29.0.0" // Teszteléshez -}, -"engines": { - "node": ">=18.0.0" // Node verzió megkötés -} -``` - -
-📄 Teljes package.json tartalom - -```json -{ - "name": "elso-gyakorlat", - "version": "1.0.0", - "description": "User Management System", - "main": "index.js", - "type": "module", - "scripts": { - "start": "nodemon src/API/server.js", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC", - "dependencies": { - "express": "^5.2.1", - "nodemon": "^3.1.11" - } -} -``` - -
- -**FONTOS**: Ne felejtsed el hozzáadni a `"type": "module"` sort! - -#### 1.3 Függőségek telepítése - -```bash -npm install -``` - ---- - -### 2. Domain Réteg Implementálás - -#### 2.1 IUserRepository.js - Repository Interface - -**Fájl**: `src/Domain/IUserRepository.js` - -**Cél**: Egy interfész-szerű osztály létrehozása, amely definiálja a user repository alapvető műveleteit. - -**Részletes leírás:** - -A Domain réteg középpontjában az interfészek állnak. JavaScript-ben nincs natív interfész támogatás (mint pl. TypeScript-ben vagy Java-ban), de osztályokkal szimulálhatjuk ezt a viselkedést. - -**Mit kell létrehozni:** - -1. **IUserRepository osztály** - Ez lesz a "szerződés", amit minden repository implementációnak követnie kell - -2. **5 metódus**, mind aszinkron (`async`): - - `getAll()` - Összes felhasználó lekérése (paraméter nélkül) - - `getById(id)` - Egy felhasználó lekérése ID alapján - - `create(user)` - Új felhasználó létrehozása (user objektumot vár paraméterként) - - `update(id, userData)` - Felhasználó módosítása (ID és új adatok) - - `delete(id)` - Felhasználó törlése (ID alapján) - -3. **Error dobás** - Minden metódus dobjon hibát alapértelmezetten (`throw new Error('Method not implemented')`) - - Miért? Mert ez biztosítja, hogy ha valaki implementálja ezt az osztályt, de elfelejt egy metódust felülírni, egyből hibát kapjon - -**Fontos elvek:** -- Ez az osztály NEM tartalmaz implementációt, csak az "interfészt" definiálja -- Minden metódus async, mert később fájlkezelés/adatbázis műveleteket fogunk végezni -- Ez a Dependency Inversion Principle része - a magasabb szintű kód ettől az interface-től függ, nem a konkrét implementációtól - -
-📄 Teljes kód megtekintése - -```javascript -export class IUserRepository { - async getAll() { - throw new Error('Method not implemented'); - } - - async getById(id) { - throw new Error('Method not implemented'); - } - - async create(user) { - throw new Error('Method not implemented'); - } - - async update(id, userData) { - throw new Error('Method not implemented'); - } - - async delete(id) { - throw new Error('Method not implemented'); - } -} -``` - -
- ---- - -### 3. Infrastructure Réteg Implementálás - -#### 3.1 user.json - Adat fájl - -**Fájl**: `src/Infrastructure/user.json` - -**Cél**: Egyszerű JSON fájl alapú adattárolás létrehozása. - -**Részletes leírás:** - -Ez lesz az "adatbázisunk" - egy egyszerű JSON fájl, amely a felhasználókat tárolja. Később ezt könnyedén lecserélhetjük valódi adatbázisra (MongoDB, PostgreSQL, stb.) anélkül, hogy az alkalmazás többi részét módosítanánk. - -**Mit tartalmaz:** -- Kezdetben egy üres tömb (`[]`) -- A repository fog írni/olvasni ebből a fájlból -- Minden user objektumként lesz tárolva a tömbben - -**Miért JSON fájl?** -- Egyszerű és gyors kezdéshez -- Nem kell adatbázist telepíteni -- Könnyen olvasható és debuggolható -- Demonstrálja a repository pattern használatát - -
-📄 Fájl tartalma megtekintése - -```json -[] -``` - -
- -#### 3.2 userRepository.js - Repository Implementáció - -**Fájl**: `src/Infrastructure/userRepository.js` - -**Cél**: Az IUserRepository interfész konkrét implementációja JSON fájl alapú tárolással. - -**Részletes leírás:** - -Ez az osztály valósítja meg a tényleges adatelérési logikát. Kiterjeszti (`extends`) az `IUserRepository` interfészt, tehát felül kell írnia minden metódust. - -**Importok és inicializálás:** - -1. **fs/promises** - Node.js fájlrendszer modul aszinkron verzió (promise-based) -2. **path** - Fájl útvonalak kezeléséhez -3. **fileURLToPath** - ES6 modulokban szükséges a `__dirname` eléréséhez -4. **IUserRepository** - A szülő interfész - -**Fontos ES6 Modules trükk:** -```javascript -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); -``` -ES6 modulokban nem elérhető a `__dirname`, így ezt a workaround-ot kell használni. - -**Metódusok részletes működése:** - -**1. getAll() - Összes user lekérése** -- `fs.readFile()` - Beolvassa a JSON fájlt (async) -- `JSON.parse()` - String-ből objektummá alakítja -- Try-catch: ha a fájl nem létezik/üres, üres tömböt ad vissza -- **Fontos**: Ez a metódus lesz a többi metódus alapja is! - -**2. getById(id) - Egy user keresése** -- Meghívja a `getAll()`-t -- `find()` - Tömb metódus, megkeresi az első egyező elemet -- Ha nincs találat, `undefined`-et ad vissza - -**3. create(user) - Új user létrehozása** -- Lekéri az összes user-t -- **Új objektum létrehozása:** - - `id: Date.now().toString()` - Timestamp alapú egyedi ID - - `...user` - Spread operator, bemásol minden property-t - - `createdAt` - ISO formátumú timestamp -- `users.push()` - Hozzáadja a tömb végéhez -- `fs.writeFile()` - Visszamenti a fájlba - - `JSON.stringify(users, null, 2)` - Pretty print, 2 szóköz indentálás -- Visszaadja az új user objektumot - -**4. update(id, userData) - User módosítása** -- `findIndex()` - Megkeresi az user indexét a tömbben -- Ha `index === -1`, nem létezik → `null` visszatérés -- **Merge művelet spread operator-ral:** - - `...users[index]` - Régi adatok - - `...userData` - Új adatok (felülírják a régieket) - - `id: users[index].id` - ID megtartása (biztonsági okokból) - - `updatedAt` - Új timestamp -- Fájl frissítése és módosított user visszaadása - -**5. delete(id) - User törlése** -- `filter()` - Új tömb létrehozása az adott user nélkül -- Hossz összehasonlítás: ha egyenlő, nem volt mit törölni → `false` -- Fájl frissítése és `true` visszaadása - -**Best practices:** -- Minden metódus `async` - konzisztens API -- Try-catch csak ahol szükséges (getAll) -- Spread operator használata immutábilis műveleteknél -- Pretty print a JSON fájlban - könnyebb debuggolni - -
-📄 Teljes kód megtekintése - -```javascript -import fs from 'fs/promises'; -import path from 'path'; -import { fileURLToPath } from 'url'; -import { IUserRepository } from '../Domain/IUserRepository.js'; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); -const USER_FILE = path.join(__dirname, 'user.json'); - -export class UserRepository extends IUserRepository { - async getAll() { - try { - const data = await fs.readFile(USER_FILE, 'utf-8'); - return JSON.parse(data); - } catch (error) { - return []; - } - } - - async getById(id) { - const users = await this.getAll(); - return users.find(user => user.id === id); - } - - async create(user) { - const users = await this.getAll(); - const newUser = { - id: Date.now().toString(), - ...user, - createdAt: new Date().toISOString() - }; - users.push(newUser); - await fs.writeFile(USER_FILE, JSON.stringify(users, null, 2)); - return newUser; - } - - async update(id, userData) { - const users = await this.getAll(); - const index = users.findIndex(user => user.id === id); - if (index === -1) return null; - - users[index] = { - ...users[index], - ...userData, - id: users[index].id, - updatedAt: new Date().toISOString() - }; - await fs.writeFile(USER_FILE, JSON.stringify(users, null, 2)); - return users[index]; - } - - async delete(id) { - const users = await this.getAll(); - const filteredUsers = users.filter(user => user.id !== id); - if (users.length === filteredUsers.length) return false; - - await fs.writeFile(USER_FILE, JSON.stringify(filteredUsers, null, 2)); - return true; - } -} -``` - -
- ---- - -### 4. Application Réteg - Query Implementálás - -#### 4.1 GetAllUsersQuery - -**Fájl**: `src/Application/users/query/getAllUsersQuery.js` - -**Cél**: Query objektum létrehozása az összes felhasználó lekérdezéséhez. - -**Részletes leírás:** - -A CQRS pattern-ben minden lekérdezésnek (Query) van egy saját Query osztálya, még akkor is, ha az üres. Ez a konzisztencia és a kód későbbi bővíthetősége szempontjából fontos. - -**Miért üres ez az osztály?** -- Az összes user lekérdezéséhez nincs szükség paraméterekre (nincs szűrés, nincs ID, stb.) -- A konstruktor üres marad -- Később könnyedén bővíthető (pl. pagination: `page`, `limit` paraméterek) - -**CQRS elv:** Minden use case-nek (ebben az esetben: "add meg az összes user-t") saját Query objektuma van, még ha paraméter nélküli is. - -
-📄 Teljes kód megtekintése - -```javascript -export class GetAllUsersQuery { - constructor() {} -} -``` - -
- -#### 4.2 GetAllUsersQueryHandler - -**Fájl**: `src/Application/users/query/getAllUsersQueryHandler.js` - -**Cél**: A GetAllUsersQuery feldolgozása és végrehajtása. - -**Részletes leírás:** - -A Handler az, amely ténylegesen végrehajtja a műveletet. Ez a "use case" implementáció. - -**Struktúra:** - -1. **Konstruktor:** - - Fogad egy `userRepository` paramétert (Dependency Injection) - - Eltárolja azt instance változóban (`this.userRepository`) - - **Miért DI?** Később könnyű tesztelni (mock repository-val), és nem függ konkrét implementációtól - -2. **handle(query) metódus:** - - Fogadja a Query objektumot (jelen esetben üres) - - Meghívja a repository `getAll()` metódusát - - Visszaadja az eredményt - - `async/await` használata az aszinkron művelethez - -**Ez a Handler felelőssége:** -- Query feldolgozása -- Repository meghívása -- Eredmény visszaadása -- (Itt lehetne üzleti logika, validáció, stb. - de ennél az egyszerű lekérdezésnél nincs rá szükség) - -**Nem a Handler felelőssége:** -- HTTP kérések kezelése (ezt a Controller végzi) -- Adatbázis műveletek (ezt a Repository végzi) - -
-📄 Teljes kód megtekintése - -```javascript -export class GetAllUsersQueryHandler { - constructor(userRepository) { - this.userRepository = userRepository; - } - - async handle(query) { - return await this.userRepository.getAll(); - } -} -``` - -
- -#### 4.3 GetUserByIdQuery - -**Fájl**: `src/Application/users/query/getUserByIdQuery.js` - -**Cél**: Query objektum egyedi felhasználó lekérdezéséhez ID alapján. - -**Részletes leírás:** - -Ez a Query már tartalmaz paramétert - a keresendő user ID-t. - -**Konstruktor paraméter:** -- `id` - A keresendő felhasználó egyedi azonosítója (string formátumban) -- Eltároljuk `this.id`-ben, hogy a Handler hozzáférjen - -**Példa használat:** -```javascript -const query = new GetUserByIdQuery('1707825600000'); -``` - -**CQRS elv:** A Query objektum tiszta adatstruktúra (Data Transfer Object - DTO), csak az adatokat hordozza, logika nélkül. - -
-📄 Teljes kód megtekintése - -```javascript -export class GetUserByIdQuery { - constructor(id) { - this.id = id; - } -} -``` - -
- -#### 4.4 GetUserByIdQueryHandler - -**Fájl**: `src/Application/users/query/getUserByIdQueryHandler.js` - -**Cél**: Egyedi felhasználó lekérdezésének feldolgozása validációval. - -**Részletes leírás:** - -**Konstruktor:** -- Ugyanaz a DI pattern, mint a GetAllUsersQueryHandler-nél - -**handle(query) metódus lépései:** - -1. **Repository meghívása:** - ```javascript - const user = await this.userRepository.getById(query.id); - ``` - - Lekéri a user-t a query-ben kapott ID alapján - - A repository `undefined`-et ad vissza, ha nincs találat - -2. **Validáció:** - ```javascript - if (!user) { - throw new Error('User not found'); - } - ``` - - Ha nincs találat, kivételt dob - - Ez az **üzleti logika része**: egy használhatatlan Query-t hibának tekintünk - -3. **Eredmény visszaadása:** - - Ha megvan a user, visszaadjuk - -**Error Handling:** -- A dobott hiba később a Controller-ben lesz elkapva -- A Controller alakítja át HTTP 404 válasszá -- Ez szépen szétválasztja a rétegeket: Application réteg nem tud HTTP-ről, csak üzleti hibákat dob - -
-📄 Teljes kód megtekintése - -```javascript -export class GetUserByIdQueryHandler { - constructor(userRepository) { - this.userRepository = userRepository; - } - - async handle(query) { - const user = await this.userRepository.getById(query.id); - if (!user) { - throw new Error('User not found'); - } - return user; - } -} -``` - -
- ---- - -### 5. Application Réteg - Command Implementálás - -#### 5.1 CreateUserCommand - -**Fájl**: `src/Application/users/command/createUserCommand.js` - -**Cél**: Command objektum új felhasználó létrehozásához. - -**Részletes leírás:** - -**CQRS: Command vs Query** -- A **Query** adatokat kér le (olvasás) - nem változtatja a rendszer állapotát -- A **Command** műveletet hajt végre (írás) - megváltoztatja a rendszer állapotát - -**Konstruktor paraméterek:** -- `name` (string) - A felhasználó neve (kötelező) -- `email` (string) - A felhasználó email címe (kötelező) -- `age` (number) - A felhasználó életkora (opcionális) - -**Fontos:** -- Az ID-t NEM adjuk meg - azt a Repository generálja automatikusan -- A `createdAt` timestamp-et sem - azt is a Repository adja hozzá -- A Command csak az "üzleti adatokat" tartalmazza - -**Példa használat:** -```javascript -const command = new CreateUserCommand('John Doe', 'john@example.com', 30); -``` - -**Clean Architecture elv:** A Command egy egyszerű DTO (Data Transfer Object), tisztán adatok, logika nélkül. - -
-📄 Teljes kód megtekintése - -```javascript -export class CreateUserCommand { - constructor(name, email, age) { - this.name = name; - this.email = email; - this.age = age; - } -} -``` - -
- -#### 5.2 CreateUserCommandHandler - -**Fájl**: `src/Application/users/command/createUserCommandHandler.js` - -**Cél**: Új felhasználó létrehozási parancs végrehajtása validációval. - -**Részletes leírás:** - -**Konstruktor:** -- DI pattern: userRepository injektálás - -**handle(command) metódus lépései:** - -**1. Validáció (Üzleti szabályok):** -```javascript -if (!command.name || !command.email) { - throw new Error('Name and email are required'); -} -``` -- Name és email **kötelező mezők** -- Ez üzleti logika - az Application réteg felelőssége -- Ha valamelyik hiányzik, kivételt dobunk -- Later: Bővíthető email formátum ellenőrzéssel, egyediség ellenőrzéssel, stb. - -**2. User objektum összeállítása:** -```javascript -const userData = { - name: command.name, - email: command.email, - age: command.age -}; -``` -- A Command adataiból létrehozunk egy plain objektumot -- Csak a "tiszta" adatok mennek tovább a Repository-nak -- Az age lehet `undefined` ha nem adták meg - ez rendben van - -**3. Repository meghívása:** -```javascript -return await this.userRepository.create(userData); -``` -- A Repository hozzáadja az ID-t és a createdAt-et -- Visszaadja a teljes user objektumot (ID-val és timestamp-el együtt) - -**CommandHandler felelősségei:** -- ✅ Validáció (üzleti szabályok) -- ✅ Adatok előkészítése -- ✅ Repository meghívása -- ❌ NEM HTTP kezelés (azt a Controller végzi) -- ❌ NEM adatbázis műveletek (azt a Repository végzi) - -
-📄 Teljes kód megtekintése - -```javascript -export class CreateUserCommandHandler { - constructor(userRepository) { - this.userRepository = userRepository; - } - - async handle(command) { - if (!command.name || !command.email) { - throw new Error('Name and email are required'); - } - - const userData = { - name: command.name, - email: command.email, - age: command.age - }; - - return await this.userRepository.create(userData); - } -} -``` - -
- -#### 5.3 UpdateUserCommand - -**Fájl**: `src/Application/users/command/updateUserCommand.js` - -**Cél**: Command objektum felhasználó módosításához. - -**Részletes leírás:** - -**Konstruktor paraméterek:** -- `id` (string) - A módosítandó user egyedi azonosítója (kötelező!) -- `name` (string) - Az új/frissített név -- `email` (string) - Az új/frissített email -- `age` (number) - Az új/frissített életkor - -**Különbség a CreateUserCommand-hoz képest:** -- Ez tartalmaz **ID-t** is - tudnunk kell, melyik user-t módosítjuk -- Az ID a URL-ből jön majd (pl. `PUT /users/123456`) - -**Példa használat:** -```javascript -const command = new UpdateUserCommand( - '1707825600000', - 'John Updated', - 'john.new@example.com', - 31 -); -``` - -
-📄 Teljes kód megtekintése - -```javascript -export class UpdateUserCommand { - constructor(id, name, email, age) { - this.id = id; - this.name = name; - this.email = email; - this.age = age; - } -} -``` - -
- -#### 5.4 UpdateUserCommandHandler - -**Fájl**: `src/Application/users/command/updateUserCommandHandler.js` - -**Cél**: Felhasználó módosítási parancs végrehajtása. - -**Részletes leírás:** - -**handle(command) metódus lépései:** - -**1. Adatok előkészítése:** -```javascript -const userData = { - name: command.name, - email: command.email, - age: command.age -}; -``` -- Összegyjük a módosítandó adatokat -- **Fontos**: Az ID-t NEM küldjük tovább a userData-ban! -- Az ID külön paraméterként megy a repository-nak (biztonság és tisztaság) - -**2. Repository meghívása:** -```javascript -const updatedUser = await this.userRepository.update(command.id, userData); -``` -- A repository `update()` metódusa várja az ID-t és az új adatokat -- Visszaad `null`-t ha nem található a user -- Visszaadja a frissített user objektumot (updatedAt timestamp-el) ha sikeres - -**3. Validáció (létezés ellenőrzés):** -```javascript -if (!updatedUser) { - throw new Error('User not found'); -} -``` -- Ha `null` jött vissza, nem létezett ilyen ID-jű user -- Kivételt dobunk, amit a Controller HTTP 404-re alakít - -**4. Eredmény visszaadása:** -- A frissített user objektum megy vissza a Controller-nek - -**Későbbi bővítési lehetőségek:** -- Validáció csak a megváltozott mezőkre (partial update) -- Verzió kontroll (optimistic locking) -- Jogosultság ellenőrzés (csak saját profil módosítható) - -
-📄 Teljes kód megtekintése - -```javascript -export class UpdateUserCommandHandler { - constructor(userRepository) { - this.userRepository = userRepository; - } - - async handle(command) { - const userData = { - name: command.name, - email: command.email, - age: command.age - }; - - const updatedUser = await this.userRepository.update(command.id, userData); - if (!updatedUser) { - throw new Error('User not found'); - } - - return updatedUser; - } -} -``` - -
- -#### 5.5 DeleteUserCommand - -**Fájl**: `src/Application/users/command/deleteUserCommand.js` - -**Cél**: Command objektum felhasználó törléséhez. - -**Részletes leírás:** - -**Konstruktor paraméterek:** -- `id` (string) - A törlendő user egyedi azonosítója - -**Egyszerű struktúra:** -- Csak egy ID-t tartalmaz - ez az egyetlen információ, ami kell a törléshez -- Hasonló a GetUserByIdQuery-hez, de szándékban különbözik (írás vs olvasás) - -**Példa használat:** -```javascript -const command = new DeleteUserCommand('1707825600000'); -``` - -**CQRS szétválasztás:** Bár hasonló a Query-hez, külön osztály kell, mert ez Command (írási művelet, állapot változtatás). - -
-📄 Teljes kód megtekintése - -```javascript -export class DeleteUserCommand { - constructor(id) { - this.id = id; - } -} -``` - -
- -#### 5.6 DeleteUserCommandHandler - -**Fájl**: `src/Application/users/command/deleteUserCommandHandler.js` - -**Cél**: Felhasználó törlési parancs végrehajtása. - -**Részletes leírás:** - -**handle(command) metódus lépései:** - -**1. Repository meghívása:** -```javascript -const deleted = await this.userRepository.delete(command.id); -``` -- A repository `delete()` metódusa boolean-t ad vissza -- `true` - sikeres törlés -- `false` - nem létezett ilyen ID-jű user - -**2. Validáció:** -```javascript -if (!deleted) { - throw new Error('User not found'); -} -``` -- Ha törlés sikertelen (false), kivételt dobunk -- Ez konzisztens a többi handler validációjával - -**3. Visszatérési érték:** -- **Nincs explicit return!** -- DELETE művelet nem ad vissza adatot (ún. "void" művelet) -- A Controller HTTP 204 No Content választ küld - -**Fontos különbség:** -- Ez az egyetlen Handler, ami nem ad vissza user objektumot -- REST convention: DELETE művelet után nincs response body - -**Későbbi bővítési lehetőségek:** -- Soft delete (csak megjelölés töröltként, fizikai törlés helyett) -- Cascade delete (kapcsolódó adatok törlése is) -- Audit log (ki, mikor törölte) - -
-📄 Teljes kód megtekintése - -```javascript -export class DeleteUserCommandHandler { - constructor(userRepository) { - this.userRepository = userRepository; - } - - async handle(command) { - const deleted = await this.userRepository.delete(command.id); - if (!deleted) { - throw new Error('User not found'); - } - } -} -``` - -
- ---- - -### 6. API Réteg Implementálás - -#### 6.1 userController.js - Controller - -**Fájl**: `src/API/controllers/userController.js` - -**Cél**: HTTP kérések kezelése és koordináció az Application réteggel. - -**Részletes leírás:** - -A Controller a **Presentation réteg** része - ő az, aki tudja, mi az a HTTP, mi az a request és response. Az Application réteget (Handler-ek) használja az üzleti logika végrehajtására. - -**Fájl szerkezete:** - -**1. Importok:** -- Repository és összes Query/Command osztály -- Összes QueryHandler és CommandHandler osztály -- Összesen 11 import (1 Repository + 5 Query/Command pár) - -**2. Dependency Injection beállítása:** -```javascript -const userRepository = new UserRepository(); -const getAllUsersQueryHandler = new GetAllUsersQueryHandler(userRepository); -// ... stb -``` -- Egy közös repository példány minden handler-nek -- Handler példányok modul szinten (singleton pattern) -- Ez egyszerűsíti a kódot - nem kell minden metódusban létrehozni - -**3. Controller metódusok (5 db):** - -**getAll(req, res)** - Összes user lekérése -- Query létrehozása (paraméter nélkül) -- Handler meghívása -- Eredmény visszaküldése JSON formátumban -- Error handling: 500 (szerver hiba) - -**getById(req, res)** - Egy user lekérése -- Query létrehozása `req.params.id`-val (URL paraméter) -- Handler meghívása -- Eredmény visszaküldése -- Error handling: 404 (nem található) - -**create(req, res)** - Új user létrehozása -- Command létrehozása `req.body` adatokból (POST body) -- Handler meghívása -- Eredmény visszaküldése **201 Created** státusszal -- Error handling: 400 (validációs hiba) - -**update(req, res)** - User módosítása -- Command létrehozása ID-val (URL) + adatok (POST body) -- Handler meghívása -- Eredmény visszaküldése -- Error handling: 404 (nem található) - -**delete(req, res)** - User törlése -- Command létrehozása csak ID-val -- Handler meghívása -- **204 No Content** státusz, üres body -- Error handling: 404 (nem található) - -**HTTP Státusz kódok:** -- **200 OK** - Sikeres GET, PUT (default Express-ben) -- **201 Created** - Sikeres POST (új resource) -- **204 No Content** - Sikeres DELETE (nincs response body) -- **400 Bad Request** - Validációs hiba (hiányzó/helytelen adatok) -- **404 Not Found** - Resource nem található -- **500 Internal Server Error** - Váratlan szerver hiba - -**Felelősségek:** -- ✅ HTTP kérés/válasz kezelése -- ✅ URL paraméterek és body adatok kinyerése -- ✅ Command/Query objektumok létrehozása -- ✅ Handler-ek hívása -- ✅ HTTP státusz kódok beállítása -- ✅ Error handling és átkonvertálása HTTP válaszokra -- ❌ NINCS üzleti logika (azt a Handler végzi) -- ❌ NINCS adatbázis művelet (azt a Repository végzi) - -
-📄 Teljes kód megtekintése - -```javascript -import { UserRepository } from '../../Infrastructure/userRepository.js'; -import { GetAllUsersQuery } from '../../Application/users/query/getAllUsersQuery.js'; -import { GetAllUsersQueryHandler } from '../../Application/users/query/getAllUsersQueryHandler.js'; -import { GetUserByIdQuery } from '../../Application/users/query/getUserByIdQuery.js'; -import { GetUserByIdQueryHandler } from '../../Application/users/query/getUserByIdQueryHandler.js'; -import { CreateUserCommand } from '../../Application/users/command/createUserCommand.js'; -import { CreateUserCommandHandler } from '../../Application/users/command/createUserCommandHandler.js'; -import { UpdateUserCommand } from '../../Application/users/command/updateUserCommand.js'; -import { UpdateUserCommandHandler } from '../../Application/users/command/updateUserCommandHandler.js'; -import { DeleteUserCommand } from '../../Application/users/command/deleteUserCommand.js'; -import { DeleteUserCommandHandler } from '../../Application/users/command/deleteUserCommandHandler.js'; - -const userRepository = new UserRepository(); -const getAllUsersQueryHandler = new GetAllUsersQueryHandler(userRepository); -const getUserByIdQueryHandler = new GetUserByIdQueryHandler(userRepository); -const createUserCommandHandler = new CreateUserCommandHandler(userRepository); -const updateUserCommandHandler = new UpdateUserCommandHandler(userRepository); -const deleteUserCommandHandler = new DeleteUserCommandHandler(userRepository); - -export class UserController { - async getAll(req, res) { - try { - const query = new GetAllUsersQuery(); - const users = await getAllUsersQueryHandler.handle(query); - res.json(users); - } catch (error) { - res.status(500).json({ error: error.message }); - } - } - - async getById(req, res) { - try { - const query = new GetUserByIdQuery(req.params.id); - const user = await getUserByIdQueryHandler.handle(query); - res.json(user); - } catch (error) { - res.status(404).json({ error: error.message }); - } - } - - async create(req, res) { - try { - const command = new CreateUserCommand( - req.body.name, - req.body.email, - req.body.age - ); - const user = await createUserCommandHandler.handle(command); - res.status(201).json(user); - } catch (error) { - res.status(400).json({ error: error.message }); - } - } - - async update(req, res) { - try { - const command = new UpdateUserCommand( - req.params.id, - req.body.name, - req.body.email, - req.body.age - ); - const user = await updateUserCommandHandler.handle(command); - res.json(user); - } catch (error) { - res.status(404).json({ error: error.message }); - } - } - - async delete(req, res) { - try { - const command = new DeleteUserCommand(req.params.id); - await deleteUserCommandHandler.handle(command); - res.status(204).send(); - } catch (error) { - res.status(404).json({ error: error.message }); - } - } -} -``` - -
- -#### 6.2 userRouter.js - Router - -**Fájl**: `src/API/routers/userRouter.js` - -**Cél**: RESTful route-ok definiálása és Controller metódusokhoz kötése. - -**Részletes leírás:** - -A Router az Express moduláris routing rendszere - külön fájlban definiálhatjuk a route-okat, majd a főalkalmazásba importálhatjuk. - -**Fájl szerkezete:** - -**1. Importok:** -- `express` - Express framework -- `UserController` - A korábban létrehozott controller - -**2. Router és Controller példányosítás:** -```javascript -const router = express.Router(); -const userController = new UserController(); -``` - -**3. Route definíciók (5 db):** - -**REST API konvenciók:** - -| HTTP Metódus | URL Pattern | Controller Metódus | Leírás | -|--------------|-------------|-------------------|--------| -| GET | `/` | `getAll()` | Összes user listázása | -| GET | `/:id` | `getById()` | Egyedi user lekérése | -| POST | `/` | `create()` | Új user létrehozása | -| PUT | `/:id` | `update()` | User teljes módosítása | -| DELETE | `/:id` | `delete()` | User törlése | - -**Cél**: Express alkalmazás konfigurálása, middleware-ek és route-ok beállítása, szerver indítása. - -**Részletes leírás:** - -Ez az alkalmazás belépési pontja (entry point) - ez a fájl indul el, amikor `npm start`-ot futtatunk. - -**Fájl szerkezete:** - -**1. Importok:** -```javascript -import express from 'express'; -import userRouter from './routers/userRouter.js'; -``` -- Express framework -- User router (korábban definiált route-ok) - -**2. Express app instance:** -```javascript -const app = express(); -``` -- Létrehozza az Express alkalmazás objektumot -- Ezen fogunk middleware-eket és route-okat regisztrálni - -**3. Konfigurációs változók:** -```javascript -const PORT = 3000; -``` -- Port szám, ahol a szerver hallgatózni fog -- Később környezeti változóból is jöhet: `process.env.PORT || 3000` - -**4. Middleware-ek:** -```javascript -app.use(express.json()); -``` -- **Kritikus fontosságú!** Ez parse-olja a JSON body-t a POST/PUT kérésekben -- Nélküle a `req.body` undefined lenne -- Az Express beépített middleware-je (korábban külön `body-parser` package volt) -- Automatikusan parse-olja ha `Content-Type: application/json` - -**5. Route regisztráció:** -```javascript -app.use('/users', userRouter); -``` -- Base path: `/users` -- A userRouter-ben definiált relatív útvonalak eléje kerül ez a prefix -- Így a `router.get('/')` valójában `GET /users` lesz -- Moduláris: könnyen hozzáadhatunk más router-eket (pl. `/posts`, `/comments`) - -**Teljes útvonalak:** -- `GET /users` → összes user -- `GET /users/:id` → egy user -- `POST /users` → új user -- `PUT /users/:id` → user módosítás -- `DELETE /users/:id` → user törlés - -**6. Szerver indítása:** -```javascript -app.listen(PORT, () => { - console.log(`Server running on http://localhost:${PORT}`); -}); -``` -- `app.listen()` - Express metódus a szerver indításához -- Callback function - lefut, amikor a szerver sikeresen elindult -- Console log - visszajelzés, hogy minden OK - -**Fontos koncepciók:** - -**Middleware sorrend:** -- A middleware-ek **sorrendben** futnak! -- `express.json()` a route-ok ELŐTT kell legyen -- Így a route handler-ek már parse-olt body-t kapnak - -**További bővítési lehetőségek:** -```javascript -app.use(cors()); // CORS engedélyezése -app.use(morgan('dev')); // HTTP logging -app.use(helmet()); // Biztonsági headers -app.use('/posts', postRouter); // További entitások -``` - -
-📄 Teljes kód megtekintése - -```javascript -import express from 'express'; -import userRouter from './routers/userRouter.js'; - -const app = express(); -const PORT = 3000; - -// Middleware -app.use(express.json()); - -// Routes -app.use('/users', userRouter); - -// Server -app.listen(PORT, () => { - console.log(`Server running on http://localhost:${PORT}`); -}); -``` - -```javascript -import express from 'express'; -import { UserController } from '../controllers/userController.js'; - -const router = express.Router(); -const userController = new UserController(); - -router.get('/', (req, res) => userController.getAll(req, res)); -router.get('/:id', (req, res) => userController.getById(req, res)); -router.post('/', (req, res) => userController.create(req, res)); -router.put('/:id', (req, res) => userController.update(req, res)); -router.delete('/:id', (req, res) => userController.delete(req, res)); - -export default router; -``` - -
- -#### 6.3 server.js - Szerver konfiguráció - -**Fájl**: `src/API/server.js` - -```javascript -import express from 'express'; -import userRouter from './routers/userRouter.js'; - -const app = express(); -const PORT = 3000; - -// Middleware -app.use(express.json()); - -// Routes -app.use('/users', userRouter); - -// Server -app.listen(PORT, () => { - console.log(`Server running on http://localhost:${PORT}`); -}); -``` - - - ---- - -## Futtatás és Tesztelés - -### Szerver Indítása - -```bash -npm start -``` - -Ez elindítja a nodemon-t, ami automatikusan újraindítja a szervert fájl módosítások esetén. - -### API Endpoint-ok Tesztelése - -#### 1. Összes User Lekérése - -**Request:** -```http -GET http://localhost:3000/users -``` - -**Válasz:** -```json -[] -``` - -#### 2. Új User Létrehozása - -**Request:** -```http -POST http://localhost:3000/users -Content-Type: application/json - -{ - "name": "John Doe", - "email": "john@example.com", - "age": 30 -} -``` - -**Válasz:** -```json -{ - "id": "1707825600000", - "name": "John Doe", - "email": "john@example.com", - "age": 30, - "createdAt": "2026-02-13T10:00:00.000Z" -} -``` - -#### 3. User Lekérése ID alapján - -**Request:** -```http -GET http://localhost:3000/users/1707825600000 -``` - -**Válasz:** -```json -{ - "id": "1707825600000", - "name": "John Doe", - "email": "john@example.com", - "age": 30, - "createdAt": "2026-02-13T10:00:00.000Z" -} -``` - -#### 4. User Módosítása - -**Request:** -```http -PUT http://localhost:3000/users/1707825600000 -Content-Type: application/json - -{ - "name": "John Updated", - "email": "john.updated@example.com", - "age": 31 -} -``` - -**Válasz:** -```json -{ - "id": "1707825600000", - "name": "John Updated", - "email": "john.updated@example.com", - "age": 31, - "createdAt": "2026-02-13T10:00:00.000Z", - "updatedAt": "2026-02-13T10:05:00.000Z" -} -``` - -#### 5. User Törlése - -**Request:** -```http -DELETE http://localhost:3000/users/1707825600000 -``` - -**Válasz:** -``` -204 No Content -``` - -### Tesztelési Eszközök - -- **Postman**: GUI alapú API tesztelő -- **Thunder Client**: VS Code extension -- **cURL**: Parancssori eszköz -- **REST Client**: VS Code extension (.http fájlokkal) - ---- - -## User Adatmodell - -```javascript -{ - "id": "string", // Automatikusan generált (timestamp) - "name": "string", // Kötelező - "email": "string", // Kötelező - "age": number, // Opcionális - "createdAt": "ISO8601", // Automatikusan generált létrehozáskor - "updatedAt": "ISO8601" // Automatikusan generált módosításkor -} -``` - ---- - -## Hibakezelés - -### Validációs Hibák - -- **400 Bad Request**: Hiányzó kötelező mezők (name, email) -- Üzenet: `"Name and email are required"` - -### Not Found Hibák - -- **404 Not Found**: User nem található (GET, PUT, DELETE) -- Üzenet: `"User not found"` - -### Szerver Hibák - -- **500 Internal Server Error**: Váratlan hiba (pl. fájl írási probléma) -- Üzenet: Részletes hibaüzenet - ---- - -## Best Practice-ek és Elvek - -### 1. Separation of Concerns (SoC) -- Minden réteg csak a saját felelősségével foglalkozik -- Controller nem tartalmaz üzleti logikát -- Repository nem validál - -### 2. Dependency Inversion Principle (DIP) -- A magasabb szintű modulok nem függenek az alacsonyabb szintűektől -- Mindketten az absztrakciótól (interface) függenek -- `UserController` → `IUserRepository` interface-től függ, nem a konkrét implementációtól - -### 3. Single Responsibility Principle (SRP) -- Minden osztálynak egy felelőssége van -- Command/Query külön handler-ben -- Repository csak adatelérésért felelős - -### 4. CQRS Benefits -- Egyszerűbb kód, könnyebb megérteni -- Optimalizálható külön az olvasás és írás -- Könnyebb tesztelni - -### 5. Async/Await használata -- Minden I/O művelet (fájl olvasás/írás) aszinkron -- Try-catch az error handling-hez - ---- - -## Gyakori Problémák és Megoldások - -### 1. ES6 Module hibák - -**Hiba**: `SyntaxError: Cannot use import statement outside a module` - -**Megoldás**: `package.json`-ben add hozzá: `"type": "module"` - -### 2. __dirname not defined - -**Hiba**: `ReferenceError: __dirname is not defined in ES module scope` - -**Megoldás**: -```javascript -import { fileURLToPath } from 'url'; -const __dirname = path.dirname(fileURLToPath(import.meta.url)); -``` - -### 3. Port already in use - -**Hiba**: `Error: listen EADDRINUSE: address already in use :::3000` - -**Megoldás**: -- Másik port használata -- Folyamat leállítása: Windows-on `netstat -ano | findstr :3000` majd `taskkill /PID /F` - -### 4. JSON parse error - -**Hiba**: JSON fájl sérült vagy üres - -**Megoldás**: Try-catch blokk a repository-ban, üres tömb visszaadása hiba esetén - ---- - -## Ellenőrző Lista (Checklist) - -- [ ] Projekt struktúra létrehozva -- [ ] package.json konfigurálva (`"type": "module"`) -- [ ] Függőségek telepítve -- [ ] Domain réteg: IUserRepository létrehozva -- [ ] Infrastructure réteg: UserRepository és user.json létrehozva -- [ ] Application réteg: Összes Query és Command létrehozva -- [ ] Application réteg: Összes Handler létrehozva -- [ ] API réteg: UserController létrehozva -- [ ] API réteg: userRouter létrehozva -- [ ] API réteg: server.js létrehozva és konfigurálva -- [ ] Szerver elindul hiba nélkül -- [ ] GET /users működik -- [ ] POST /users működik és ment a JSON fájlba -- [ ] GET /users/:id működik -- [ ] PUT /users/:id működik -- [ ] DELETE /users/:id működik -- [ ] Hibakezelés működik mindenhol -- [ ] Kód tiszta, kommentek megfelelőek - ---- - -## Összegzés - -Ez a User Management rendszer egy jól strukturált, modern Node.js alkalmazás, amely követi a Clean Architecture és CQRS elveket. A kód könnyen karbantartható, skálázható, és előkészített későbbi bővítésekre (pl. adatbázis integráció). - -**Főbb tanulságok:** -- Rétegelt architektúra előnyei -- CQRS pattern alkalmazása -- Dependency Injection használata -- REST API best practice-ek -- Async/Await és hibakezelés -- ES6 modulok használata Node.js-ben - -**Fejlesztési idő becslés**: 3-5 óra (tapasztalattól függően) - -**Nehézségi szint**: Közép-haladó - ---- - -**Dátum**: 2026. február 13. -**Verzió**: 1.0 diff --git a/Backend/elso gyakorlat/FELADAT_LEIRAS_USER_MANAGEMENT_EGYENI.md b/Backend/elso gyakorlat/FELADAT_LEIRAS_USER_MANAGEMENT_EGYENI.md deleted file mode 100644 index ca89965..0000000 --- a/Backend/elso gyakorlat/FELADAT_LEIRAS_USER_MANAGEMENT_EGYENI.md +++ /dev/null @@ -1,222 +0,0 @@ -# Egyéni Feladat – User Management Rendszer - -> **Ez a leírás teljesen kezdőknek is szól! Ha még soha nem fejlesztettél, akkor is végig tudsz menni rajta. Minden lépésnél részletes magyarázatot, példákat és forrásokat találsz.** - ---- - -## 0. Alapok, amiket tudni érdemes - -### Mi az a User Management rendszer? -Egy olyan program, amiben felhasználókat tudsz létrehozni, listázni, módosítani, törölni. Ilyen van minden weboldalon, ahol regisztrálni lehet. - -### Mik azok a REST API-k? -Olyan szabályok szerint működő webes szolgáltatások, amikhez más programok (vagy akár te is) tudsz kéréseket küldeni (pl. "add vissza az összes felhasználót"). - -### Mik azok a rétegek (layer-ek)? -A programot több részre bontjuk, hogy átláthatóbb legyen. Pl. külön rész kezeli az adatokat, külön rész a webes kéréseket. - -### Mik azok a parancsok (Command) és lekérdezések (Query)? -- **Command:** Valamit módosít (pl. új user létrehozása) -- **Query:** Csak lekérdez (pl. összes user listázása) - ---- - -## 1. Szükséges eszközök, telepítés - -1. **Node.js letöltése:** - - Menj a https://nodejs.org/ oldalra, töltsd le a LTS verziót, telepítsd. -2. **Kód szerkesztő:** - - Ajánlott: [Visual Studio Code](https://code.visualstudio.com/) -3. **Postman vagy Thunder Client:** - - Ezekkel tudod tesztelni az API-t. [Postman letöltése](https://www.postman.com/downloads/) - ---- - -## 2. Projekt létrehozása, első lépések - -1. Hozz létre egy új mappát pl. `user-management` néven. -2. Nyisd meg a mappát VS Code-ban. -3. Nyiss egy terminált (Terminal > New Terminal). -4. Írd be: `npm init -y` (létrehozza a package.json-t) -5. Telepítsd az Express-t: `npm install express` -6. (Ha JSON fájlt használsz adattárolásra, nem kell adatbázis.) - ---- - -## 3. Mappastruktúra kialakítása - -Javasolt szerkezet: - -``` -user-management/ - src/ - API/ - Application/ - Domain/ - Infrastructure/ - package.json -``` - -Minden mappába majd külön fájlokat teszünk (lásd lentebb). - ---- - -## 4. Kódolás lépésről lépésre (példákkal) - -### 4.1. API réteg (Express szerver) -- Hozz létre egy `src/API/server.js` fájlt. -- Írd bele az alábbi mintát: - -
-Express szerver példa - -```js -import express from 'express'; -const app = express(); -app.use(express.json()); - -app.get('/', (req, res) => { - res.send('Hello, User Management!'); -}); - -app.listen(3000, () => { - console.log('Szerver fut a http://localhost:3000 címen'); -}); -``` -
- -- Futtasd: `node src/API/server.js` (ha hibát ír, nézd meg, hogy mindenhol helyes-e az elérési út és a kód) - -### 4.2. Domain réteg (interfész, entitás) -- Hozz létre egy `src/Domain/IUserRepository.js` fájlt. -- Írd bele, hogy milyen műveleteket vársz el (pl. createUser, getUserById, stb.) - -
-IUserRepository.js példa - -```js -export default class IUserRepository { - createUser(user) {} - getUserById(id) {} - getAllUsers() {} - updateUser(id, user) {} - deleteUser(id) {} -} -``` -
- -### 4.3. Infrastructure réteg (adattárolás) -- Hozz létre egy `src/Infrastructure/userRepository.js` fájlt. -- Ebben valósítsd meg az IUserRepository metódusait, pl. JSON fájlba írással/olvasással. - -
-userRepository.js példa (részlet) - -```js -import fs from 'fs/promises'; -import path from 'path'; -import IUserRepository from '../Domain/IUserRepository.js'; - -const DATA_PATH = path.resolve('src/Infrastructure/user.json'); - -export default class UserRepository extends IUserRepository { - async createUser(user) { - // ... - } - // ... többi metódus ... -} -``` -
- -- Hozz létre egy `user.json` fájlt is, pl. így: - -
-user.json példa - -```json -[] -``` -
- -### 4.4. Application réteg (Command/Query handlerek) -- Hozz létre minden CRUD művelethez külön Command/Query és Handler fájlt. -- Pl. `createUserCommand.js`, `createUserCommandHandler.js`, stb. - -
-createUserCommand.js példa - -```js -export default class CreateUserCommand { - constructor(user) { - this.user = user; - } -} -``` -
- -
-createUserCommandHandler.js példa - -```js -import UserRepository from '../../Infrastructure/userRepository.js'; -export default class CreateUserCommandHandler { - constructor() { - this.userRepository = new UserRepository(); - } - async handle(command) { - return await this.userRepository.createUser(command.user); - } -} -``` -
- -### 4.5. API végpontok (Controller, Router) -- Hozz létre egy `userController.js`-t és egy `userRouter.js`-t az API mappában. -- A controller hívja a handlereket, a router összeköti az útvonalakat a controllerrel. - -
-userController.js példa - -```js -import CreateUserCommand from '../../Application/users/command/createUserCommand.js'; -import CreateUserCommandHandler from '../../Application/users/command/createUserCommandHandler.js'; - -export async function createUser(req, res) { - const command = new CreateUserCommand(req.body); - const handler = new CreateUserCommandHandler(); - const result = await handler.handle(command); - res.status(201).json(result); -} -``` -
- ---- - -## 5. Tesztelés, hibakeresés - -- Indítsd el a szervert: `node src/API/server.js` -- Küldj kéréseket Postmanből vagy Thunder Clientből (GET, POST, PUT, DELETE) -- Ha hibát kapsz, olvasd el figyelmesen a hibaüzenetet, keresd meg a fájlban a hibás sort. -- Próbáld ki az összes végpontot, nézd meg, hogy minden működik-e. - ---- - -## 6. Dokumentáció, beadás - -- Készíts egy rövid leírást (README.md), amiben leírod: - - Mit csinál a programod? - - Hogyan kell elindítani? - - Milyen extra funkciót raktál bele? -- Csatold a forráskódot és a tesztadatokat. - ---- - -## 7. Hasznos források, videók - -- [Node.js alapok magyarul (videó)](https://www.youtube.com/watch?v=U8XF6AFGqlc) -- [Express.js alapok magyarul (videó)](https://www.youtube.com/watch?v=1n_V2A4bHqw) -- [REST API magyarázat (videó)](https://www.youtube.com/watch?v=Q-BpqyOT3a8) -- [JSON fájlok kezelése Node.js-ben (angol)](https://www.digitalocean.com/community/tutorials/how-to-read-and-write-json-files-in-node-js) -- [VS Code rövid bemutató (magyar)](https://www.youtube.com/watch?v=VqCgcpAypFQ) - ---- \ No newline at end of file diff --git a/Backend/elso gyakorlat/User Management Rendszer - Feladat Leírás.pdf b/Backend/elso gyakorlat/User Management Rendszer - Feladat Leírás.pdf new file mode 100644 index 0000000..ae1b6a6 Binary files /dev/null and b/Backend/elso gyakorlat/User Management Rendszer - Feladat Leírás.pdf differ