Loading src/fonaments/frameworks.md +18 −15 Original line number Diff line number Diff line Loading @@ -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. Loading src/fonaments/frameworks_practica.md +47 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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/) Loading Loading
src/fonaments/frameworks.md +18 −15 Original line number Diff line number Diff line Loading @@ -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. Loading
src/fonaments/frameworks_practica.md +47 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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/) Loading