ruta backend / módulo 7

M7 — Git avanzado & semántica HTTP

Dos fundamentos que el mercado da por sentados y hunden entrevistas cuando fallan (ambos aparecieron como gap en pruebas técnicas reales).

Outcome del módulo: resolver un conflicto de merge sin romper nada, reescribir historia local con criterio, y diseñar una API que respete la semántica HTTP (métodos, status, idempotencia).


Concepto 1 — Git avanzado (rebase, cherry-pick, conflictos)

Idea núcleo: más allá de add/commit/push, un senior maneja historia: integra ramas limpio, mueve commits puntuales y resuelve conflictos con criterio.

Entender (capa 1)

Texto:

Visual:

flowchart TD
    Q{¿qué necesito?} -->|integrar rama compartida| MERGE[merge · preserva historia]
    Q -->|limpiar historia local antes de PR| REBASE[rebase · lineal, solo local]
    Q -->|un commit puntual a otra rama| CP[cherry-pick]
    Q -->|encontrar qué commit rompió| BISECT[git bisect]

Video: Git Merge vs Rebase Explained in 100 Seconds — Thetips4you

Ejemplo:

# resolver conflicto durante un rebase
git rebase main
# ... Git marca conflicto en archivo.py ...
# editás, elegís la versión correcta, luego:
git add archivo.py
git rebase --continue          # (o git rebase --abort para cancelar todo)

# llevar solo un hotfix a otra rama
git cherry-pick <hash-del-commit>

# encontrar el commit que introdujo un bug
git bisect start; git bisect bad; git bisect good <hash-viejo>

Fijar (capa 2)

Nota atómica:

Feynman: “Merge es unir dos ríos y dejar ver dónde se juntaron. Rebase es reescribir tu diario para que parezca que siempre fuiste por el mismo camino — genial para tu diario privado, catástrofe si reescribís el diario compartido del equipo.”

Aplicar (capa 3)

Creá dos ramas que toquen la misma línea, provocá un conflicto y resolvelo. Después hacé un rebase -i para hacer squash de 3 commits en 1, y un cherry-pick de un commit a otra rama.

Límites


Concepto 2 — Semántica HTTP

Idea núcleo: cada método y status code tiene un significado contractual. Respetarlo hace tu API predecible, cacheable y correcta; ignorarlo la vuelve un campo minado.

Entender (capa 1)

Texto:

Visual:

flowchart LR
    M[método] --> G[GET · seguro · cacheable]
    M --> PO[POST · crea · NO idempotente]
    M --> PU[PUT · reemplaza · idempotente]
    M --> DE[DELETE · idempotente]

Video: HTTP Methods Explained | GET, POST, PUT, and Idempotency in Simple Terms — Leela Web Dev

Ejemplo (mal → bien):

# ❌ todo por POST y siempre 200: rompe caching, retries y clientes
@app.post("/get-user")           # debería ser GET
def get_user(): return {"ok": True}   # 200 hasta cuando falla

# ✅ semántica correcta
@app.get("/users/{id}")          # GET para leer
def get_user(id):
    u = db.get(id)
    if u is None:
        raise HTTPException(404)  # no existe → 404, no 200
    return u                      # 200 con el recurso

@app.post("/users", status_code=201)  # crear → 201
def create_user(data): ...

Fijar (capa 2)

Nota atómica:

Feynman: “PUT es el interruptor de la luz: lo aprietes una o cinco veces, queda en el estado que pediste. POST es agregar un plato a la mesa: cada vez que lo mandás, aparece otro plato.”

Aplicar (capa 3)

Tomá una API que usa POST para todo y devuelve 200 siempre; reescribila con métodos y status correctos (GET/POST/PUT/DELETE, 201/404/422). Verificá con curl -i que los status son correctos.

Límites


Concepto 3 — Code review como señal de seniority (no LGTM, no nitpick)

Idea núcleo: un review superficial (“LGTM” o solo nitpicks de estilo) es la señal más rápida de que alguien no es senior todavía — el review es donde se demuestra criterio, no solo conocimiento.

Entender (capa 1)

Texto:

Visual:

flowchart TD
    C[comentario en PR] --> T{tipo}
    T -->|nit: preferencia| N[no bloquea, opcional]
    T -->|issue: bug/seguridad/perf| I[bloquea o se negocia con dato]
    T -->|question: duda genuina| Q[pregunta, no asume mala intención]
    T -->|praise: algo bien hecho| P[reforzar, no solo criticar]

Ejemplo (comentario débil vs fuerte):

❌ "Esto no me gusta."
❌ "¿Por qué hiciste esto así?" (suena a acusación)

✅ "nit: preferiría `user_count` sobre `cnt` acá — no bloquea."
✅ "issue: esto corre N+1 queries si `posts` tiene más de 1 item —
    ver M2/Índices. ¿Consideraste `select_related`?"
✅ "question: ¿este endpoint necesita ser idempotente? Si un cliente
    reintenta, ¿duplicamos el registro?"

Fijar (capa 2)

Nota atómica:

Feynman: “LGTM sin leer es como firmar un contrato sin leerlo porque confiás en la otra persona — puede salir bien, pero no es tu trabajo confiar, es tu trabajo revisar. Conventional Comments es ponerle una etiqueta a cada comentario para que el autor sepa de entrada si tiene que actuar ya o si es solo una sugerencia.”

Aplicar (capa 3)

Elegí un PR real (tuyo o de otro repo público) y escribí 3 comentarios usando el formato nit:/issue:/question:. Para el issue:, incluí la alternativa concreta, no solo el problema.

Límites


Checklist de dominio M7

Marcás cuando podés explicar (Feynman) + aplicar:

Salida verificable del módulo: resolver un conflicto de rebase real + hacer squash de una rama antes de un PR; y una API con métodos/status/idempotencia correctos verificados con curl -i.