8.1 Mi a production-ready

← 8. Production-ready projekt építés

8.1 Mi a „production-ready"? – A különbség egy tutorialtól


Áttekintő

Valószínűleg láttál már száz tutorial-videót, GitHub repót és blogbejegyzést, amelyek mind azt mutatják meg, „hogyan csináld". Ezek a példák általában működnek – de a legtöbbjük production-ban azonnal megbukna, vagy komoly kockázatot jelentene.

Ez az alfejezet nem új funkciókat tanít. Ehelyett megmutatja azt a minőségi ugrást, ami egy „most megcsináltam és működik" kód és egy „holnap reggel éles felhasználók fogják használni" kód között van. Ez az a különbség, amit a seniorok azonnal észrevesznek a junior kódján – és ami az interjún, az onboarding során, és az első PR-odban is megmutatkozik.

A fejezet többi alfejezetében részletesen is megtanulod, hogyan valósítsd meg ezeket. Most az a cél, hogy értsd a nagy képet: miért számít ez egyáltalán.

Körülbelül 10 perc olvasnivaló + 15 perc feladatok


Részletes leírás

A tutorial-kód és a production-kód különbsége

Amikor valaki tutorial-t ír, az elsődleges cél az érthetőség. Minél rövidebb, minél egyszerűbb, minél kevesebb zavaró részlet – annál jobb tanulási élmény. Ez teljesen rendben van.

A probléma akkor kezdődik, amikor a junior fejlesztő ezt a szemléletet viszi magával az első munkahelyére.

Nézzük meg, mi hiányzik tipikusan egy tutorial-kódból:


1. Hibakezelés hiánya

A legtöbb tutorial „happy path"-on mutatja be a megoldást: minden bemenet érvényes, az API mindig válaszol, az adatbázis mindig elérhető. Valódi production környezetben mindezek bármikor meghibásodhatnak.

Tutorial-kód:

def get_user(user_id):
    response = requests.get(f"https://api.example.com/users/{user_id}")
    return response.json()

Mi hiányzik?

  • Mi történik, ha az API nem elérhető?
  • Mi történik, ha a válasz nem érvényes JSON?
  • Mi történik, ha user_id nem egy szám?
  • Mi történik, ha a felhasználó nem létezik (404)?

A production-kód minden reális hibalehetőséget figyelembe vesz. Nem pánikol, nem omlodik össze, hanem értelmesen kezeli a hibát – és ha kell, tájékoztat róla a megfelelő szinten.


2. Hardcoded konfigurációk és titkos adatok

Ez az egyik legveszélyesebb és leggyakoribb junior hiba.

Tutorial-kód:

const db = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'password123',
  database: 'myapp'
});

const API_KEY = "sk-abc123xyz789abcdef";

Mi a probléma?

  • Ha ezt commitolod GitHubra (akár privát repóba is), a kulcsaid nyilvánossá válnak
  • Ha más gépen, más környezetben futtatják (staging, production), a konfiguráció hibás lesz
  • Ha meg kell változtatni az adatbázis jelszavát, a kódot kell módosítani és redeploy-olni

A production-kód soha nem tartalmaz titkos adatot közvetlenül. Environment változók, titkos tárolók (vault, secrets manager), vagy legalább .env fájlok (amelyek nem kerülnek verziókezelésbe) – ezek a megoldások.


3. Nincs logging

Amikor a production-ban elromlik valami (és el fog), hogyan fogod tudni, mi történt? Ha nincs logging, a válasz: sehogy.

Tutorial-kód:

function processPayment($amount, $userId) {
    $result = $this->paymentGateway->charge($amount);
    if ($result) {
        $this->db->save($userId, $amount);
    }
}

Mi hiányzik?

  • Ki indította a tranzakciót és mikor?
  • Mi volt a pontos összeg?
  • Sikerült a fizetés? Ha nem, miért?
  • Ha az adatbázis-mentés meghiúsult, de a fizetés megtörtént, hogyan rekonstruálod az állapotot?

A production-kód naplóz – értelmesen, szintenként (INFO, WARNING, ERROR), és soha nem logol ki szenzitív adatot (jelszó, kártyaszám, személyes adat).


4. Nincs validáció

A tutorial-kód általában feltételezi, hogy a bemenet érvényes. A production-ban sosem teheted ezt fel.

Tutorial-kód:

@app.route('/users', methods=['POST'])
def create_user():
    data = request.json
    user = User(
        name=data['name'],
        email=data['email'],
        age=data['age']
    )
    db.save(user)
    return jsonify(user)

Mi hiányzik?

  • Mi történik, ha name hiányzik a kérésből? (KeyError)
  • Mi történik, ha email nem érvényes email-cím?
  • Mi történik, ha age szöveg helyett szám?
  • Mi történik, ha valaki szándékosan hibás adatot küld?

A validáció nem csak UX-kérdés (jó hibaüzenet a felhasználónak), hanem biztonsági kérdés is. Validáció nélküli bemenet az SQL injection, XSS és egyéb támadások kapuját nyitja meg.


5. Nincs dokumentáció

A tutorial-kódhoz van egy cikk vagy videó, ami elmagyarázza, mit csinál. A te kódodhoz hat hónap múlva nem lesz ott a jövőbeli kollégád fejében az az összefüggés.

Ami hiányzik tipikusan:

  • README.md: hogyan lehet elindítani a projektet?
  • Environment változók listája és leírása
  • API dokumentáció (ha publikus API-t írsz)
  • Fontos architekturális döntések magyarázata

Ez nem azt jelenti, hogy minden sort kommentálni kell. Ellenkezőleg: a jól megnevezett változók és függvények önmagukban dokumentálnak. De az egész rendszer működéséhez, az indításhoz, a konfiguráláshoz írásos útmutató kell.


6. Nincs figyelembe véve a karbantarthatóság

A tutorial-kód egyszer fut le, demonstrációs célból. A production-kódot fejlesztők fogják olvasni, módosítani és debuggolni – hónapokkal, évekkel a megírás után.

Tipikus tünetek:

  • Óriási függvények, amelyek egyszerre sok mindent csinálnak
  • Mágikus számok (if status == 3) magyarázat nélkül
  • Duplikált kód, mert „copy-paste gyorsabb volt"
  • Inkonzisztens elnevezések

A nagy kép: a production-ready skála

Nem kell tökéletesen production-ready kódot írni az első naptól – de tudnod kell, hogy mi az az irány, amelybe haladni kell.

Tutorial kód          Csapat kód            Production kód
───────────           ──────────            ──────────────
Működik               Működik +             Működik +
                      Olvasható +           Olvasható +
                      Reviewolható          Reviewolható +
                                            Hibatűrő +
                                            Konfigurálható +
                                            Monitorozható +
                                            Karbantartható

Az első állásodban senki nem várja, hogy azonnal a legjobb production-kódot írd. De elvárják, hogy tudd, mire kell figyelni – és aktívan törekedj rá.

Ez a fejezet (8. fejezet) a production-ready kód legfontosabb pilléreit járja végig:

AlfejezetTéma
8.1Ez az alfejezet – áttekintő, nagy kép
8.2Environment változók és konfiguráció
8.3Hibakezelés és hibaüzenetek
8.4README és dokumentáció
8.5Input validáció és adattisztítás
8.6Verziókezelés és dependency management
8.7Kódbázis navigáció és onboarding

Életszerű példák

Példa 1: Az első PR élménye

Ádám frissen végzett, és az első ticketje egy egyszerű: „Adj hozzá egy API végpontot, ami visszaadja az aktuálisan bejelentkezett felhasználó adatait."

Ádám megírja a végpontot. Működik a lokális gépen. Örömmel nyitja meg a PR-t.

A reviewer visszaküldi:

„Hibakezelés? Mi van, ha a token lejárt? Mi van, ha a felhasználó nem létezik az adatbázisban? Az API kulcs miért van hardcode-olva? Nincs log arról, mikor hívják meg ezt a végpontot. Nincs validáció a header-en."

Ádám elkeseredik – úgy érzi, mindent rosszul csinált. Valójában csak a tutorial-szemléletet hozta magával, ahol ezek a kérdések irrelevánsak. A fejezet többi részét elolvasva mindegyik problémára konkrét megoldást fog tanulni.


Példa 2: A production-ban derül ki

Eszter egyedül fejleszt egy kisebb projektet, ő a „senior" a csapatban. Az alkalmazásuk egy éve fut, és most egyszerre sok felhasználó panaszkodik, hogy az adataik nem frissülnek.

Néz a logokat – de nincs log. Néz a hibakezelőt – de nincs hibakezelés, az exceptions elnyelődnek. Az adatbázis connection string hardcode-ban van, senki nem tudja, melyik adatbázisra mutat a production.

Két napig tart kideríteni, hogy az adatbázis connection pool kimerült, mert egy loop nem zárta le a connection-t. Két nap, ami egyetlen logger.error(...) és egy try-catch-finally-vel pár perc lett volna.

Ez nem ritka eset. Ez a valóság.


Példa 3: Az interjún

Kata technikai interjún van. A feladat: írj egy egyszerű REST API végpontot, ami felhasználót hoz létre.

Kata megírja a kódot. Működik. Az interviewer megkérdezi:

„Mi történik, ha az email mező hiányzik?" „Hogyan konfigurálnád az adatbázis kapcsolatot különböző környezetekre?" „Hogyan figyelnéd meg, hogy ez a végpont milyen hibákat dob production-ban?"

Kata nem tud válaszolni. Nem rossz fejlesztő – csak senki nem tanította meg, hogy ezek is a kód részei.

Aki ezeket meg tudja válaszolni, az kitűnik a többi junior közül.


Feladatok és tesztek

Gyakorlati feladat

Az alábbi kódrészlet egy egyszerű bejelentkezési funkció – tipikus tutorial-stílusban. Elemezd, és írd le, mit kellene hozzáadni ahhoz, hogy production-ready legyen! Nem kell megírni a javított kódot – elég felsorolni, mi hiányzik és miért.

from flask import Flask, request, jsonify
import mysql.connector

app = Flask(__name__)

db = mysql.connector.connect(
    host="localhost",
    user="root",
    password="admin",
    database="users_db"
)

@app.route('/login', methods=['POST'])
def login():
    data = request.json
    username = data['username']
    password = data['password']
    
    cursor = db.cursor()
    cursor.execute(f"SELECT * FROM users WHERE username='{username}' AND password='{password}'")
    user = cursor.fetchone()
    
    if user:
        return jsonify({"success": True, "user": user})
    else:
        return jsonify({"success": False})

if __name__ == '__main__':
    app.run(debug=True)

Vezérfonál a megoldáshoz – amiket keress:

  • Hány biztonsági problémát találsz? (Legalább 3 van)
  • Mi hiányzik a hibakezelésből?
  • Mi a gond a konfigurációval?
  • Mi hiányzik a logging-ból?
  • Mi hiányzik a validációból?
  • Van még valami, ami production-ban gondot okozna?

Tesztkérdések

1. kérdés: Melyik állítás igaz a production-ready kódról?

a) A production-ready kód mindig hosszabb és bonyolultabb, mint a tutorial-kód
b) A production-ready kód figyelembe veszi a hibalehetőségeket, a konfigurálhatóságot és a megfigyelhetőséget
c) Production-ready kód csak seniorok feladata – juniortól nem várják el
d) Ha a kód fut és nincs hiba, akkor production-ready

Megoldás

b) A production-ready kód nem feltétlenül hosszabb – de figyelembe veszi, mi történik, ha valami elromlik, hogyan konfigurálható különböző környezetekre, és hogyan lehet megfigyelni futás közben.


2. kérdés: Miért veszélyes hardcoded API kulcsot tartalmazó kódot commitolni?

a) Lassítja a build folyamatot
b) A kulcsok nyilvánosságra kerülhetnek (akár privát repóban is), és nem cserélhetők a kód módosítása nélkül
c) Csak akkor veszélyes, ha public repóba kerül
d) Nem veszélyes, ha erős jelszót használunk

Megoldás

b) Privát repóban is fennáll a kockázat (szivárgás, jogosultságkezelés), és a kulcs cseréjéhez kód-módosítás + redeploy szükséges. A helyes megoldás: environment változók.


3. kérdés: Egy végpont nem logol semmit. Mi a legnagyobb probléma ezzel production-ban?

a) A kód lassabban fut logging nélkül
b) Ha hiba keletkezik, nincs nyom, ami segítene a diagnosztikában
c) A felhasználók látni fogják a hibaüzeneteket
d) A kód nem fog lefordulni logging nélkül

Megoldás

b) Logging nélkül production-hibánál nem lehet tudni, mi történt, mikor, és milyen bemenetre. Ez a debuggolást szinte lehetetlenné teszi.


4. kérdés: Melyik kódrészlet a production-ready megközelítés?

A:

const port = 3000;
const dbPassword = "mypassword";

B:

const port = process.env.PORT || 3000;
const dbPassword = process.env.DB_PASSWORD;

a) A, mert egyszerűbb és könnyebben olvasható
b) B, mert environment változókból olvassa a konfigurációt
c) Mindkettő egyformán production-ready
d) Egyik sem, mert a portot sem szabad változóban tárolni

Megoldás

b) A B verzió environment változókból olvassa a konfigurációt, így különböző környezeteken (local, staging, production) különböző értékeket kaphat anélkül, hogy a kódot módosítani kellene. Az A verzióban a jelszó kódba van égetve.


5. kérdés: Miért kell szerver oldali validáció akkor is, ha kliens oldalon már validálunk?

a) Mert a szerver oldali validáció gyorsabb
b) Mert a kliens oldali validáció kihagyható (pl. direkt API hívással), ezért sosem bízhatunk benne egyedül
c) Mert a kliens oldali validáció nem működik mobil eszközökön
d) Nincs szükség szerver oldali validációra, ha kliens oldalon validálunk

Megoldás

b) Bárki küldhet HTTP kérést közvetlenül az API-ra (curl, Postman, script), teljesen megkerülve a kliens oldali validációt. A szerver oldali validáció az egyetlen, amiben megbízhatunk.


6. kérdés: Egy új fejlesztő csatlakozik a csapathoz. A projekt nem tartalmaz README-t, és nincs dokumentáció. Mi a legvalószínűbb következmény?

a) Semmi gond – a kódból mindent ki lehet olvasni
b) A fejlesztő napokat tölt azzal, hogy megértse, hogyan kell elindítani és konfigurálni a projektet
c) A CI/CD pipeline hibát fog jelezni
d) Csak a külső fejlesztőknek okoz gondot

Megoldás

b) Dokumentáció nélkül az onboarding lassú és frusztráló. A setup, a szükséges environment változók, a service-ek, az architektúra – mindezeket valakitől meg kell kérdezni, vagy napokig kell keresgélni.


7. kérdés: Melyik állítás igaz a „graceful degradation" fogalmára?

a) Ha egy komponens meghibásodik, az egész alkalmazásnak le kell állnia, hogy jelezze a problémát
b) Ha egy nem kritikus komponens meghibásodik, az alkalmazás tovább működhet csökkentett funkcionalitással
c) A graceful degradation csak frontend technológiákra vonatkozik
d) A graceful degradation azt jelenti, hogy a kód fokozatosan romlik az idő múlásával

Megoldás

b) Pl. ha a recommendation engine leáll, az e-commerce oldal még tud terméket mutatni és vásárlást kezelni – csak az ajánlások nem jelennek meg. Az alkalmazás nem omlik össze teljesen egy részkomponens hibájától.


8. kérdés: Miért nem biztonságos az alábbi kód?

cursor.execute(f"SELECT * FROM users WHERE username='{username}'")

a) Mert f-string helyett %-os formázást kellene használni
b) Mert az SQL lekérdezés sebezhetővé teszi az alkalmazást SQL injection ellen
c) Mert a cursor nem megfelelő típusú
d) Mert SELECT helyett GET-et kellene használni

Megoldás

b) Ha username értéke pl. ' OR '1'='1, a lekérdezés minden felhasználót visszaad. Ez SQL injection – az egyik leggyakoribb és legveszélyesebb biztonsági sérülékenység. A megoldás: paraméteres lekérdezések.


9. kérdés: Melyik a helyes megközelítés, ha egy API hívás sikertelen?

a) Figyelmen kívül hagyni és visszatérni egy üres eredménnyel
b) Az egész alkalmazást leállítani és hibát dobni a felhasználónak
c) A hibát logolni, a felhasználónak értelmes hibaüzenetet adni, és a rendszer többi részét működtetni tovább
d) Automatikusan végtelen hurokig próbálkozni a hívással

Megoldás

c) A production-kód logol (hogy a fejlesztő tudja mi történt), a felhasználónak értelmesen és biztonságosan kommunikálja a hibát (nem stack trace!), és ahol lehetséges, a rendszer többi funkciója folytatja működését.


10. kérdés: Egy fejlesztő azt mondja: „Az én kódom production-ready, mert nálam minden teszteset átment." Mi hiányzik ebből az álláspontból?

a) Semmi – ha a tesztek átmennek, a kód production-ready
b) A tesztek a funkcionalitást ellenőrzik, de a production-readiness magában foglalja a hibakezelést, a konfigurálhatóságot, a loggingot és a biztonságot is, amelyekre lehet, hogy nincsenek tesztek
c) A teszteket seniornak kell futtatni, nem a juniornak
d) Csak ha 100%-os a code coverage, production-ready

Megoldás

b) A funkcionális tesztek nem fedik le a production-readiness összes dimenzióját. Pl. egy teszt ellenőrzi, hogy a regisztráció működik – de nem teszteli, hogy a jelszó environment változóból jön-e, hogy a hibák loggolódnak-e, vagy hogy a bemenet validált-e SQL injection ellen.


Ez az alfejezet alapozta meg a fejezet többi részét. A következő alfejezetekben konkrétan is megtanulod, hogyan valósíts meg minden egyes pilléert – kezdve az environment változókkal (8.2).

Scroll to Top