Commit 2778068c authored by jg5dev's avatar jg5dev 💬
Browse files

better

parent 28c7a9cd
Loading
Loading
Loading
Loading
+18 −15
Original line number Diff line number Diff line
@@ -594,24 +594,27 @@ que és una decisió de desplegament abans que de codi.

### Dades i vista

| Framework | ORM habitual | Patró de mapatge | Vista per defecte |
| --- | --- | --- | --- |
| Django | Django ORM | Active Record | Django Templates |
| Rails | Active Record | Active Record | ERB, amb Hotwire |
| Spring | JPA amb Hibernate | Data Mapper | Thymeleaf |
| Laravel | Eloquent | Active Record | Blade |
| Symfony | Doctrine | Data Mapper | Twig |
| ASP.NET Core | Entity Framework Core | Data Mapper | Razor o Blazor |
| Express | A triar | El de l'ORM triat | Cap, motors opcionals |
| FastAPI | A triar, sovint SQLAlchemy | Data Mapper | Cap, JSON |
| NestJS | Prisma, Drizzle o TypeORM | El de l'ORM triat | Cap, JSON |
| Gin | A triar (GORM, `sqlc`) | El de la llibreria | `html/template` |
| Next.js | A triar (Prisma, Drizzle) | El de l'ORM triat | React, integrat |
| Phoenix | Ecto, que no és un ORM | Consultes explícites | HEEx i LiveView |
| Framework | ORM habitual | Patró de mapatge | Migracions | Vista per defecte |
| --- | --- | --- | --- | --- |
| Django | Django ORM | Active Record | Integrades, generades | Django Templates |
| Rails | Active Record | Active Record | Integrades | ERB, amb Hotwire |
| Spring | JPA amb Hibernate | Data Mapper | Flyway o Liquibase | Thymeleaf |
| Laravel | Eloquent | Active Record | Integrades | Blade |
| Symfony | Doctrine | Data Mapper | Bundle de Doctrine | Twig |
| ASP.NET Core | Entity Framework Core | Data Mapper | EF Core Migrations | Razor o Blazor |
| Express | A triar | El de l'ORM triat | Les de l'ORM triat | Cap, motors opcionals |
| FastAPI | A triar, sovint SQLAlchemy | Data Mapper | Alembic | Cap, JSON |
| NestJS | Prisma, Drizzle o TypeORM | El de l'ORM triat | Les de l'ORM triat | Cap, JSON |
| Gin | A triar (GORM, `sqlc`) | El de la llibreria | Eina externa | `html/template` |
| Next.js | A triar (Prisma, Drizzle) | El de l'ORM triat | Prisma Migrate | React, integrat |
| Phoenix | Ecto, que no és un ORM | Consultes explícites | Integrades a Ecto | HEEx i LiveView |

Als microframeworks el patró de mapatge no el marca el framework sinó l'ORM que triïs, i n'hi ha que
et deixen triar a tu. La columna de la vista, per la seva banda, deixa veure a simple cop d'ull quins
frameworks esperen servir HTML i quins esperen servir dades. I a Rails el nom de l'ORM és literalment
frameworks esperen servir HTML i quins esperen servir dades. I la de migracions amaga una decisió
que es paga cara si es descobreix tard: allà on són generades a partir dels models (Django, Doctrine,
Entity Framework Core) la font de veritat de l'esquema és el codi, mentre que amb Flyway o
`golang-migrate` la font de veritat és el SQL que escrius tu. I a Rails el nom de l'ORM és literalment
Active Record, cosa que explica per què el patró es coneix tant: Rails el va convertir en la manera
per defecte de fer aplicacions web durant una dècada.

+47 −1
Original line number Diff line number Diff line
@@ -42,7 +42,8 @@ tant, no és si en vols un, sinó si en vols un de compartit.
Els casos on la resposta és que no en cal cap són pocs i es reconeixen fàcilment: un script d'un sol
punt d'entrada, una tasca programada, una biblioteca, o un entorn molt limitat. I un matís: a Go,
"sense framework" vol dir amb la llibreria estàndard, que ja porta un servidor HTTP complet. Es
tracta d'una frontera molt més borrosa del que sembla.
tracta d'una frontera molt més borrosa del que sembla. Si ets en aquest cas, l'última secció diu com
[muntar-lo amb llibreries](#muntar-lo-amb-llibreries) sense acabar amb un framework accidental.

## Triar un framework

@@ -182,6 +183,51 @@ llibertat d'un microframework només és llibertat de veritat si les decisions e
queden escrites, per exemple en un [ADR](./arquitectura.md#decisions-explícites-els-adr). Si no,
cadascú en pren de diferents i el projecte acaba tenint totes les respostes alhora.

## Muntar-lo amb llibreries

Queda el cas que la primera secció donava per poc freqüent: has decidit que no vols framework i vols
construir l'arquitectura tu, ajuntant llibreries. És una decisió legítima quan el servei fa una sola
cosa, quan l'arrencada i la mida del binari són crítiques (serverless, sistemes encastats) o quan el
llenguatge hi convida, com Go. Però recorda la trampa de la primera secció: no en tenir cap vol dir
tenir-ne un de propi, així que val més muntar-lo a consciència.

**Fes la llista de peces abans d'escriure res.** Un framework és, essencialment, aquesta llista ja
resolta. Si te la fas tu, no te'n descuidaràs cap a mitges:

| Peça | Què has de decidir |
| --- | --- |
| Servidor HTTP i encaminament | Sovint ja el porta la llibreria estàndard |
| Validació de l'entrada | Quina llibreria i on s'aplica |
| Accés a dades | Controlador, generador de consultes o ORM |
| Migracions | Eina i on viuen els fitxers |
| Registre (logs) | Format estructurat des del primer dia |
| Configuració | D'on surt i com es valida en arrencar |
| Autenticació | Resum de contrasenyes i format de token |
| Gestió d'errors | Com es tradueixen a codis HTTP |

**Segueix la mateixa cadena que faria un framework.** Sense middleware integrat, la fas a mà: una
funció que n'embolcalla una altra. Amb tres embolcalls (registre, autenticació i errors) ja tens la
cadena de responsabilitats de qualsevol framework, i el pas 4 de la secció anterior segueix valent.

**Escriu el composition root de veritat.** És l'única peça que no et donarà cap llibreria i la que
decideix si el projecte serà provable: un fitxer que crea la connexió, els repositoris i els
serveis, i els lliga a les rutes.

**No escriguis mai tu** el resum de contrasenyes, la signatura de tokens, la generació
d'identificadors de sessió, l'escapament d'HTML ni la construcció de SQL per concatenació. Són el
mateix consell de [Disseny segur](../m9/uf1s/disseny_segur.md), i aquí es concentra tot el risc de
la decisió: el framework te'ls donava resolts i ara els has de portar tu.

**Assumeix el manteniment.** Deu llibreries són deu calendaris d'actualitzacions i deu llistes
d'avisos de seguretat que ara mires tu. Val la pena triar-les avorrides i molt usades, fixar-ne les
versions i posar una anàlisi de dependències a la canonada.

**I para atenció al senyal d'aturada.** Quan el codi de connexió comença a tenir registre de rutes,
convencions de noms i utilitats genèriques, és que estàs escrivint un framework. Aleshores hi ha dues
sortides bones, i totes dues passen per admetre-ho: adoptar-ne un de fet, o extreure el teu com a
llibreria interna, amb documentació i un [ADR](./arquitectura.md#decisions-explícites-els-adr) que
expliqui per què existeix.

## Referències

- [Architecture decision records](https://adr.github.io/)