Skip to content

Cum să validezi request-urile unui API cu Pydantic și Marshmallow

DodaTech Updated 2025-01-15 3 min read

In this tutorial, you'll learn about Cum să validezi request. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

Validarea request-urilor asigură că datele primite de API sunt corecte, complete și sigure. În acest ghid vei învăța cum să validezi request-urile API cu Pydantic, Marshmallow și scheme personalizate.

Problema

API-ul tău primește date invalide -- câmpuri lipsă, tipuri greșite, string-uri în loc de numere. Fără validare, aceste date ajung în baza de date și cauzează erori greu de depanat.

Soluția Rapidă

1. Validare cu Pydantic (recomandat)

pip install pydantic
from pydantic import BaseModel, EmailStr, Field, validator
from typing import Optional

class UtilizatorCreate(BaseModel):
    nume: str = Field(..., min_length=2, max_length=100)
    email: str
    varsta: int = Field(..., ge=18, le=120)
    rol: Optional[str] = "user"

    @validator("email")
    def email_valid(cls, v):
        if "@" not in v:
            raise ValueError("Email invalid")
        return v.lower()

    @validator("nume")
    def nume_fara_spatii_duble(cls, v):
        return " ".join(v.split())
from fastapi import FastAPI

app = FastAPI()

@app.post("/utilizatori")
def creeaza_utilizator(u: UtilizatorCreate):
    # Pydantic validează automat request body-ul
    return {"mesaj": "Utilizator creat", "date": u.model_dump()}

2. Validare cu Marshmallow (Flask)

pip install marshmallow
from marshmallow import Schema, fields, validate, ValidationError

class ProdusSchema(Schema):
    nume = fields.String(required=True, validate=validate.Length(min=2))
    pret = fields.Float(required=True, validate=validate.Range(min=0))
    stoc = fields.Integer(missing=0)

schema = ProdusSchema()

@app.route("/produse", methods=["POST"])
def creeaza_produs():
    try:
        date = schema.load(request.get_json())
        return jsonify({"produs": date}), 201
    except ValidationError as err:
        return jsonify({"eroare": err.messages}), 422

3. Validare avansată cu Pydantic

from datetime import datetime
from enum import Enum
from typing import List

class StatusComanda(str, Enum):
    nou = "nou"
    procesat = "procesat"
    trimis = "trimis"

class ArticolComanda(BaseModel):
    produs_id: int
    cantitate: int = Field(..., ge=1)

class ComandaCreate(BaseModel):
    utilizator_id: int
    articole: List[ArticolComanda] = Field(..., min_length=1)
    status: StatusComanda = StatusComanda.nou
    data_livrare: Optional[datetime] = None

    @validator("articole")
    def articole_unice(cls, v):
        ids = [a.produs_id for a in v]
        if len(ids) != len(set(ids)):
            raise ValueError("Produse duplicate in comanda")
        return v

Testare cu request invalid:

curl -X POST http://localhost:8000/utilizatori \
  -H "Content-Type: application/json" \
  -d '{"nume": "A", "varsta": 15}'

Output:

{
  "detail": [
    {"loc": ["body", "nume"], "msg": "ensure this value has at least 2 characters"},
    {"loc": ["body", "email"], "msg": "field required"},
    {"loc": ["body", "varsta"], "msg": "ensure this value is greater than or equal to 18"}
  ]
}

Prevenție

  • Definește scheme de validare pentru fiecare endpoint care primește date
  • Folosește type hints Python și Pydantic pentru validare automată
  • Returnează cod 422 pentru erori de validare, nu 400
  • Validează și pe client (frontend) dar niciodată doar pe client

Greșeli Comune

  1. Validare doar pe frontend -- request-urile pot veni direct prin curl, Postman sau alte servicii
  2. Mesaje de eroare vagi -- "eroare de validare" fără a specifica ce câmp este greșit
  3. Ignorarea tipurilor de date -- un int trimis ca string "123" trebuie convertit și validat
  4. Câmpuri opționale fără valoare implicită -- None poate cauza erori în logica de business
  5. Validare doar pe request body -- nu uita de query parameters și path parameters

Exercițiu Practic

Creează un API cu endpoint POST /comenzi care validează: ID client (int pozitiv), lista de produse (minim 1, maxim 50), adresa de livrare (string 10-200 caractere) și metoda de plată (card, ramburs, transfer).

FAQ

### De ce să folosesc Pydantic și nu validare manuală?

Pydantic oferă validare automată, Type Checking, serializare și documentație OpenAPI generată. Reducerea codului și prevenirea erorilor justifică dependența.

Pydantic vs Marshmallow -- care aleg?

Pydantic este integrat nativ cu FastAPI și oferă performanță mai bună. Marshmallow este mai potrivit pentru Flask și oferă serializare/deserializare flexibilă.

Ce înseamnă Field(...) în Pydantic?

Field(...) cu puncte indică un câmp obligatoriu. Poți adăuga default sau default_Factory pentru valori implicite. ge, le, min_length sunt validatori încorporați.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro