Arribem al nucli conceptual del curs. A la lliçó anterior vam aprendre com funciona HTTP; ara veurem com es fa servir bé, segons l'estil arquitectònic que Roy Fielding va descriure l'any 2000. REST no és una biblioteca que s'instal·la ni una especificació que es valida: és un conjunt de restriccions que, si les acceptes, et regalen escalabilitat, evolució independent i simplicitat; i si les ignores, et deixen amb una API que es diu REST però es comporta com qualsevol altra cosa. En aquesta lliçó desmuntarem les sis restriccions una a una, aplicades a la Botiga Aroma, i fixarem tres conceptes que es confonen constantment: recurs, identificador i representació.
Contingut
- Què és REST (i què no és)
- Restricció 1: client-servidor
- Restricció 2: sense estat
- Restricció 3: cacheable
- Restricció 4: sistema en capes
- Restricció 5: interfície uniforme
- Restricció 6: codi sota demanda (opcional)
- Recurs, identificador i representació
- Què hi guanya realment una API en complir cada restricció
- Què vol dir "RESTful" i per què gairebé cap API no ho és del tot
- Què és REST (i què no és)
REST vol dir Representational State Transfer: transferència d'estat representacional. El nom, que sona críptic, descriu amb precisió el mecanisme: el client i el servidor s'intercanvien representacions de l'estat d'uns recursos. Quan demanes GET /v1/cafes/caf_001, no reps "el cafè" (que és una fila d'una base de dades i uns sacs en un magatzem): reps una representació en JSON del seu estat en aquell moment.
És fonamental entendre quina categoria de cosa és REST:
| REST és | REST no és |
|---|---|
| Un estil arquitectònic: un conjunt de restriccions de disseny | Un protocol (això és HTTP) |
| Independent de la tecnologia concreta | Un estàndard amb una especificació que es pugui validar |
| Un model derivat de per què el web escala | Sinònim de "JSON sobre HTTP" |
| Aplicable amb diferent grau de fidelitat | Una biblioteca o un framework |
No existeix cap "validador REST", ni cap certificat de conformitat. Existeixen restriccions, i una API les compleix en més o menys mesura. Aquesta gradualitat és precisament el que mesura el model de maduresa de Richardson, tema de la lliçó vinent.
Fielding va definir sis restriccions: cinc d'obligatòries i una d'opcional. Cadascuna elimina possibilitats de disseny, i a canvi d'aquesta renúncia n'obtens propietats desitjables. És un intercanvi conscient.
graph TD
R["REST<br/>estil arquitectònic"] --> C1["1. Client-servidor"]
R --> C2["2. Sense estat"]
R --> C3["3. Cacheable"]
R --> C4["4. Sistema en capes"]
R --> C5["5. Interfície uniforme"]
R --> C6["6. Codi sota demanda<br/><i>opcional</i>"]
C5 --> U1["Identificació de recursos"]
C5 --> U2["Manipulació per representacions"]
C5 --> U3["Missatges autodescriptius"]
C5 --> U4["HATEOAS"]
- Restricció 1: client-servidor
Enunciat: la interfície d'usuari i l'emmagatzematge de dades estan separats en components diferents que es comuniquen mitjançant una interfície acordada.
Això separa dos mons amb ritmes i responsabilitats diferents:
- El client s'ocupa de la presentació i de l'experiència d'usuari.
- El servidor s'ocupa de les dades, les regles de negoci i la seva integritat.
A la Botiga Aroma, això vol dir que:
- El web es pot redissenyar del tot sense tocar el servidor.
- Aroma Mòbil pot publicar una versió nova mentre el backend continua igual.
- El backend pot migrar de MySQL a PostgreSQL sense que cap client se n'assabenti.
La regla pràctica: si un canvi d'aspecte visual obliga a modificar l'API, la separació està trencada. Un símptoma clàssic és un camp com ara colorBoto o textDestacatHome a la resposta d'un cafè: això és presentació colant-se dins del contracte.
// ✗ La presentació s'ha colat dins de l'API
{ "nom": "Etiòpia Yirgacheffe", "preuFormatat": "14,50 €", "classeCss": "destacat-vermell" }
// ✓ L'API dona dades; el client decideix com mostrar-les
{ "nom": "Etiòpia Yirgacheffe", "preuEuros": 14.50, "moneda": "EUR", "destacat": true }A la segona versió, el client decideix si formata 14,50 € o €14.50 segons la configuració regional de l'usuari, i quin aspecte té un producte destacat. L'API aporta el fet, no la forma.
- Restricció 2: sense estat
Enunciat: cada petició del client ha de contenir tota la informació necessària per ser compresa. El servidor no emmagatzema context de sessió entre peticions.
Aquí convé distingir amb precisió dos tipus d'estat:
| Tipus d'estat | On viu en REST | Exemple a la Botiga Aroma |
|---|---|---|
| Estat del recurs (d'aplicació) | Al servidor, de manera persistent | La comanda com_5001 existeix i està pagada |
| Estat de la sessió (de client) | Al client, i viatja a cada petició | Qui soc, per quina pàgina del catàleg vaig |
La cistella de la Botiga Aroma és un bon cas per afinar-ne la comprensió. La cistella sí que es desa al servidor, però no com a "sessió": és un recurs amb identitat pròpia, /v1/cistelles/cis_77. El client en desa només l'identificador i l'envia quan el necessita. La diferència és subtil però decisiva: un recurs es pot consultar, compartir entre dispositius i sobreviure a un reinici del servidor; una sessió en memòria, no.
Comparem dos dissenys:
# ✗ Amb estat de sessió al servidor: la segona petició depèn de la primera
POST /v1/cistella/seleccionar-client # el servidor "recorda" el client a la seva memòria
POST /v1/cistella/afegir # a quina cistella? depèn de l'anterior
# ✓ Sense estat: cada petició és autosuficient
POST /v1/cistelles/cis_77/linies
Authorization: Bearer <token del client cli_842>
{ "cafeId": "caf_001", "quantitat": 2 }A la segona versió, la petició identifica la cistella a la URL, el client mitjançant el token i el contingut al cos. Qualsevol servidor del grup la pot atendre sense coneixement previ.
Què s'hi guanya:
- Escalabilitat horitzontal: afegir servidors és trivial, no cal sincronitzar sessions.
- Tolerància a fallades: si un servidor cau, la petició següent l'atén un altre sense pèrdua de context.
- Visibilitat: qualsevol intermediari pot entendre una petició aïllada, cosa que fa possibles memòries cau, tallafocs i monitoratge.
Què es paga: cada petició és més gran, perquè repeteix les credencials i el context. Amb la compressió de capçaleres d'HTTP/2 el cost és menor del que sembla.
- Restricció 3: cacheable
Enunciat: cada resposta ha d'indicar, explícitament o implícitament, si és cacheable i durant quant de temps.
A la Botiga Aroma, no totes les dades tenen el mateix ritme de canvi:
| Recurs | Canvia sovint? | Política raonable |
|---|---|---|
| Catàleg de cafès | Rarament | Cache-Control: public, max-age=300 |
| Detall d'un cafè | Poc (l'estoc, més) | max-age=60 + ETag per revalidar |
| Comanda d'un client | És privada i crítica | Cache-Control: no-store |
| Ressenyes d'un cafè | Poc | public, max-age=600 |
Així es veu a la pràctica:
GET /v1/cafes HTTP/1.1
Host: api.botigaaroma.example
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: public, max-age=300
ETag: "a7f3c9"El servidor està dient dues coses: "pots reutilitzar aquesta resposta durant 300 segons sense preguntar-m'ho" i "aquesta versió del contingut té l'empremta a7f3c9". Passats els 5 minuts, el client pot preguntar si ha canviat enviant aquesta empremta, i si no ha canviat el servidor respon 304 Not Modified sense cos: estalvi d'amplada de banda i de temps.
Res d'això no és exclusiu del teu servidor: navegadors, CDN, servidors intermediaris i gateways entenen aquestes capçaleres de sèrie. Aquest és el gran regal d'assentar-se en HTTP en comptes d'inventar-se un mecanisme propi. Tota la mecànica de memòria cau s'estudia a la lliçó 04-06.
Compte amb el risc: posar dades privades a la memòria cau amb public és una bretxa de seguretat. Si un servidor intermediari desa la comanda d'un client i la serveix a un altre, has filtrat dades personals.
- Restricció 4: sistema en capes
Enunciat: l'arquitectura es compon de capes jeràrquiques; cada component només coneix la capa immediata amb la qual interactua, no tota la topologia.
El client de la Botiga Aroma es pensa que parla amb "l'API". En realitat, la seva petició travessa diverses capes:
graph LR
C["Aroma Mòbil"] --> CDN["CDN / memòria cau"]
CDN --> GW["API Gateway<br/>auth, límits, mètriques"]
GW --> LB["Balancejador"]
LB --> S1["Servidor API 1"]
LB --> S2["Servidor API 2"]
S1 --> BD[("Base de dades")]
S2 --> BD
Cap dels extrems no coneix la cadena completa: el client no sap quants servidors hi ha, i el servidor d'aplicació no sap si la petició va venir d'un CDN o directament. Això permet:
- Inserir un gateway que centralitzi autenticació i límits d'ús sense canviar ni una línia del client (lliçó 05-06).
- Posar un CDN al davant per servir el catàleg des d'ubicacions properes a l'usuari.
- Afegir o treure servidors segons la càrrega.
- Reescriure un servei intern sense que ningú de fora ho noti.
La contrapartida és la latència addicional de cada salt i la dificultat de depurar: per això importa tant l'observabilitat (lliçó 04-07) i les capçaleres de correlació que permeten seguir una petició a través de totes les capes.
- Restricció 5: interfície uniforme
És la restricció central, la que distingeix REST de qualsevol altre estil. La idea: en comptes que cada servei s'inventi la seva manera de parlar, tots fan servir la mateixa interfície genèrica. Es descompon en quatre subrestriccions.
6.1. Identificació de recursos
Cada recurs té un identificador únic i estable, la seva URI:
https://api.botigaaroma.example/v1/cafes -> la col·lecció de cafès https://api.botigaaroma.example/v1/cafes/caf_001 -> un cafè concret https://api.botigaaroma.example/v1/comandes/com_5001 -> una comanda concreta https://api.botigaaroma.example/v1/cafes/caf_001/ressenyes -> les ressenyes d'aquest cafè
La URI identifica una cosa, no una acció. Això explica per què /v1/obtenirCafe?id=1 o /v1/crearComanda no són URI REST: anomenen verbs, no substantius. Les regles concretes de disseny d'URI les treballarem a la lliçó 02-02.
6.2. Manipulació de recursos mitjançant representacions
El client no modifica el recurs directament: envia una representació de l'estat que desitja, i el servidor decideix si l'aplica.
PUT /v1/cafes/caf_001 HTTP/1.1
Content-Type: application/json
{
"nom": "Etiòpia Yirgacheffe",
"origen": "Etiòpia",
"torrefaccio": "clar",
"preuEuros": 15.00,
"estoc": 95
}El client diu: "vull que el cafè caf_001 quedi així". El servidor valida, comprova permisos, aplica regles de negoci i decideix. Pot acceptar (200), rebutjar per dades no vàlides (422) o per manca de permisos (403). El client proposa, el servidor disposa.
6.3. Missatges autodescriptius
Cada missatge conté la informació necessària per ser interpretat tot sol, sense coneixement extern:
POST /v1/comandes HTTP/1.1
Host: api.botigaaroma.example
Content-Type: application/json <- el format del cos va declarat
Accept: application/json <- el que espero rebre, declarat
Authorization: Bearer ... <- qui soc, declarat
HTTP/1.1 201 Created <- el resultat, en un codi estàndard
Content-Type: application/json <- el format de la resposta, declarat
Location: /v1/comandes/com_5001 <- on ha quedat, declaratUn intermediari que no hagi sentit a parlar mai de cafès pot, tot i així, entendre que s'ha creat alguna cosa i on. Per això importa fer servir els codis d'estat correctes i declarar bé els tipus de contingut: és el que permet que la infraestructura genèrica faci la seva feina.
6.4. Hipermèdia com a motor de l'estat de l'aplicació (HATEOAS)
La resposta inclou enllaços que indiquen què es pot fer a continuació:
{
"id": "com_5001",
"estat": "pendent_pagament",
"totalEuros": 29.00,
"_links": {
"self": { "href": "/v1/comandes/com_5001" },
"pagar": { "href": "/v1/comandes/com_5001/pagament", "method": "POST" },
"cancellar": { "href": "/v1/comandes/com_5001", "method": "DELETE" },
"client": { "href": "/v1/clients/cli_842" }
}
}El client no necessita tenir codificades les adreces ni les regles de negoci: descobreix que aquesta comanda es pot pagar o cancel·lar perquè el servidor l'hi diu. Si la comanda ja estigués enviada, l'enllaç cancellar senzillament no hi apareixeria.
És la subrestricció més ignorada de tot REST, i la que més debat genera. L'estudiarem a fons a la lliçó vinent, 01-05.
- Restricció 6: codi sota demanda (opcional)
Enunciat: el servidor pot estendre temporalment la funcionalitat del client enviant-li codi executable.
És l'única restricció opcional de les sis. L'exemple canònic és una pàgina web que envia JavaScript al navegador: el navegador no sabia validar aquell formulari i el servidor li envia el codi per fer-ho.
En APIs REST gairebé no es fa servir, i amb raó: enviar codi executable a un client és un risc de seguretat considerable i trenca la simplicitat. La Botiga Aroma no la farà servir. N'hi ha prou de saber que existeix i per què és opcional: redueix la visibilitat del sistema, i per això Fielding la va deixar fora del conjunt obligatori.
- Recurs, identificador i representació
Aquests tres conceptes són la base de tot, i confondre'ls és la causa de la majoria de dissenys dolents.
| Concepte | Definició | Exemple |
|---|---|---|
| Recurs | Qualsevol cosa amb identitat i interès per al negoci | El cafè Etiòpia Yirgacheffe |
| Identificador (URI) | L'adreça única i estable d'aquest recurs | /v1/cafes/caf_001 |
| Representació | Una forma concreta d'expressar-ne l'estat en un moment donat | Un document JSON, XML o HTML |
La clau: un recurs pot tenir moltes representacions, i cap d'elles és el recurs. El mateix /v1/cafes/caf_001 es pot retornar en formats diferents segons el que demani el client:
GET /v1/cafes/caf_001 HTTP/1.1
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
{"id":"caf_001","nom":"Etiòpia Yirgacheffe","preuEuros":14.50}GET /v1/cafes/caf_001 HTTP/1.1
Accept: application/xml
HTTP/1.1 200 OK
Content-Type: application/xml
<cafe><id>caf_001</id><nom>Etiòpia Yirgacheffe</nom><preuEuros>14.50</preuEuros></cafe>Mateix recurs, mateix identificador, dues representacions. Aquest mecanisme s'anomena negociació de contingut i és matèria de la lliçó 02-05.
Tres conseqüències pràctiques d'aquesta distinció:
- La representació no ha de reflectir per força la taula de la base de dades. El recurs "cafè" pot compondre's de tres taules internes, i la representació pot ometre camps interns com ara
costProveidorEuros. - Hi pot haver representacions diferents per a contextos diferents. El llistat pot retornar una versió resumida i el detall una de completa. Continua sent el mateix recurs.
- Un recurs no és necessàriament una entitat de dades. Pot ser un concepte o un procés:
/v1/cafes/mes-venutsés un recurs perfectament legítim encara que no existeixi cap taula "més venuts".
- Què hi guanya realment una API en complir cada restricció
Les restriccions no són burocràcia: cadascuna compra una propietat concreta.
| Restricció | A què t'obliga a renunciar | Què n'obtens a canvi |
|---|---|---|
| Client-servidor | A barrejar presentació i dades | Evolució independent de cada costat; diversos clients sobre un backend |
| Sense estat | A desar sessió a la memòria del servidor | Escalabilitat horitzontal, tolerància a fallades, visibilitat |
| Cacheable | A tractar totes les respostes igual | Menys latència, menys càrrega, menys cost |
| Sistema en capes | A que el client conegui la topologia | Poder inserir gateways, CDN i balancejadors sense trencar res |
| Interfície uniforme | A inventar-te la teva pròpia semàntica | Eines genèriques que funcionen sense conèixer el teu domini |
| Codi sota demanda | (opcional) | Clients extensibles, a canvi de visibilitat i seguretat |
El preu global és real: la interfície uniforme és menys eficient que una interfície a mida per a un cas concret. Fielding ho reconeix explícitament. L'aposta és que, a escala d'internet i a llarg termini, la generalitat val més que l'optimització puntual. Quan aquesta aposta no compensa —comunicació interna d'altíssim rendiment, o clients que necessiten dades a mida—, apareixen gRPC i GraphQL, que veurem a 01-07.
- Què vol dir "RESTful" i per què gairebé cap API no ho és del tot
S'anomena RESTful una API que segueix l'estil REST. A la pràctica, el terme es fa servir amb molta màniga ampla. Aquests són els incompliments més habituals:
| Pràctica freqüent | Restricció que incompleix | Per què passa |
|---|---|---|
URI amb verbs: /v1/crearComanda |
Interfície uniforme (identificació) | Es pensa en funcions, no en recursos |
Tot per POST, incloses les consultes |
Interfície uniforme + cacheable | Comoditat, o herència de SOAP |
Retornar 200 OK amb {"error": ...} |
Missatges autodescriptius | Por que el client "no sàpiga gestionar" un 4xx |
| Sessions a la memòria del servidor | Sense estat | S'arrossega el model del web tradicional |
| Respostes sense cap enllaç | HATEOAS | Cost d'implementació i clients que no ho aprofiten |
Ignorar Cache-Control |
Cacheable | Es desconeix el mecanisme |
La conclusió honesta: la majoria de les APIs anomenades REST són, en realitat, "APIs HTTP ben organitzades". Compleixen les restriccions estructurals importants (client-servidor, sense estat, recursos amb URI, verbs i codis correctes) però no implementen HATEOAS.
És un problema? Depèn del context, i mereix una resposta matisada:
- Els incompliments greus sí que importen: desar sessió al servidor t'impedeix escalar; fer servir
POSTper llegir et deixa sense memòria cau; retornar200als errors trenca el monitoratge. Són costos tècnics mesurables. - L'absència d'HATEOAS és discutible: aporta menys quan controles tots els clients i el seu cicle de vida.
L'important és que sàpigues què estàs incomplint i per què. Una decisió conscient de no implementar HATEOAS és professional; no saber que existeix, no. Per mesurar amb precisió on és la teva API en aquesta escala, hi ha una eina que veurem tot seguit.
Errors Comuns i Consells
- Creure que fer servir JSON i HTTP ja és REST. És condició necessària a la pràctica, però no suficient ni de bon tros.
- Confondre "sense estat" amb "sense dades". El servidor desa recursos persistents; el que no desa és context de conversa entre peticions.
- Modelar accions com a recursos per defecte. Si et surt
/v1/cafes/caf_001/actualitzarPreu, el verb ha d'estar al mètode (PATCH), no a la URI. - Ficar presentació dins de les respostes. Cadenes ja formatades, textos traduïts o classes CSS lliguen l'API a un client concret.
- Posar dades privades a la memòria cau com si fossin públiques. És una fuita de dades personals esperant a passar.
- Discutir de puresa REST en comptes de resoldre problemes. L'objectiu és una API útil, mantenible i evolutiva, no guanyar una discussió.
- Consell: quan dubtis d'un disseny, pregunta't "quin recurs és aquest i què li estic fent?". Si la resposta s'expressa amb un substantiu i un dels mètodes HTTP, vas bé.
Exercicis
Exercici 1: identificar la restricció incomplerta
Per a cada disseny, indica quina restricció REST s'incompleix i proposa una alternativa correcta:
POST /v1/cercarCafesamb cos{"origen":"Etiòpia"}.- L'API desa la cistella a la memòria del servidor després de
POST /v1/iniciarCompra, i les peticions següents en depenen. GET /v1/cafesrespon200 OKamb{"exit": false, "missatge": "servei caigut"}.- La resposta d'un cafè inclou
"preuHtml": "<span class='oferta'>14,50 €</span>".
Exercici 2: recurs, identificador i representació
La Botiga Aroma vol exposar l'"informe de vendes del mes actual". Respon:
- És això un recurs legítim encara que no existeixi cap taula anomenada
informes? - Proposa'n la URI.
- Proposa dues representacions diferents del mateix recurs i com les demanaria el client.
- Hauria de ser cacheable? Justifica-ho.
Exercici 3: redissenyar una API que no és RESTful
Un equip ha entregat aquesta API per gestionar ressenyes. Redissenya les quatre operacions respectant les restriccions REST i explica cada canvi.
POST /v1/api?accio=novaRessenya cos: {ressenya}
POST /v1/api?accio=llistarRessenyes cos: {cafeId}
POST /v1/api?accio=esborrarRessenya cos: {ressenyaId}
POST /v1/api?accio=editarPuntuacio cos: {ressenyaId, puntuacio}Solucions
Solució 1
- Interfície uniforme i cacheable. Una cerca és una lectura, i fer servir
POSTamb un verb a la URI impedeix posar-ho a la memòria cau i indueix a error. Alternativa:GET /v1/cafes?origen=Etiopia. (Nota: quan els criteris de cerca són enormes i no caben en una URL,POSTa un recurs de cerca és una excepció acceptada i conscient.) - Sense estat. El servidor desa context entre peticions, cosa que impedeix escalar i es trenca si cau el node. Alternativa: la cistella és un recurs,
POST /v1/cistellesretornacis_77, i les peticions següents van a/v1/cistelles/cis_77/liniesamb l'identificador explícit. - Missatges autodescriptius. Una fallada del servidor s'ha de senyalar amb
503 Service Unavailable; retornar200enganya memòries cau, reintents i monitoratge, que es pensaran que tot va bé. - Client-servidor. La presentació (HTML i classes CSS) envaeix el contracte de dades. Alternativa:
{"preuEuros": 14.50, "enOferta": true}i que cada client decideixi com es pinta.
Solució 2
- Sí que és un recurs legítim. Un recurs és qualsevol cosa amb identitat i interès per al negoci; no ha de correspondre per força a una taula. L'informe és un concepte perfectament identificable.
- URI proposada:
/v1/informes/vendes?periode=2026-08. La ruta identifica el tipus d'informe i el paràmetre n'acota el període. Alternativa igualment vàlida i més "de recurs":/v1/informes/vendes/2026-08. - Dues representacions: JSON per al panell intern (
Accept: application/json) i CSV perquè l'equip financer l'obri en un full de càlcul (Accept: text/csv). Mateix recurs, mateix identificador, representació diferent negociada per capçalera. - Sí, amb compte. És un càlcul costós que no canvia cada segon, així que
Cache-Control: private, max-age=600és raonable: es reutilitza durant deu minuts però es marcaprivateperquè és informació sensible que cap memòria cau compartida no ha de desar. L'informe d'un mes ja tancat es podria posar a la memòria cau molt més temps.
Solució 3
POST /v1/cafes/caf_001/ressenyes cos: {"puntuacio":5,"comentari":"..."} -> 201 Created
GET /v1/cafes/caf_001/ressenyes -> 200 OK
DELETE /v1/ressenyes/res_101 -> 204 No Content
PATCH /v1/ressenyes/res_101 cos: {"puntuacio":4} -> 200 OKCanvis i justificació:
- Desapareix l'endpoint únic
/v1/apii el paràmetreaccio. Cada recurs té la seva pròpia URI identificable: es compleix la subrestricció d'identificació de recursos. - El verb passa de la URL al mètode HTTP.
POSTcrea,GETllegeix,DELETEesborra,PATCHmodifica parcialment. Ara els intermediaris entenen la intenció sense conèixer el domini. - Llistar ressenyes passa a
GET, cosa que la fa segura, idempotent i cacheable: un canvi amb impacte directe en rendiment i cost. - Els identificadors surten del cos i entren a la URI, perquè identifiquen el recurs destinatari, no són dades de l'operació.
- Les ressenyes d'un cafè pengen del cafè (
/v1/cafes/caf_001/ressenyes), cosa que expressa la relació en la mateixa estructura; per operar sobre una ressenya concreta n'hi ha prou amb la seva URI pròpia. - S'hi afegeixen codis d'estat significatius:
201amb capçaleraLocationen crear,204en esborrar (no hi ha res a retornar).
Conclusió
REST és un estil arquitectònic, no un protocol: sis restriccions —client-servidor, sense estat, cacheable, sistema en capes, interfície uniforme i codi sota demanda— que renuncien a certa llibertat de disseny a canvi d'escalabilitat, evolució independent i compatibilitat amb tota la infraestructura genèrica del web. Hem vist que la interfície uniforme n'és el cor, amb les seves quatre subrestriccions, i hem fixat la distinció entre recurs (la cosa), identificador (la seva adreça) i representació (la forma concreta en què viatja). També hem admès amb honestedat que la majoria de les APIs reals incompleixen alguna cosa, sobretot HATEOAS, i que el que és professional és saber què s'incompleix i per què.
Falta una eina per mesurar aquest "quant" amb precisió. A la lliçó següent, Model de maduresa de Richardson i HATEOAS, recorrerem els quatre nivells del model reescrivint la mateixa operació de la Botiga Aroma —crear una comanda— en cadascun d'ells, veurem formats hipermèdia reals com HAL i JSON:API, i discutirem sense dogmatisme quan compensa arribar al nivell 3.
Curs de REST API: Principis de Disseny i Desenvolupament d'APIs RESTful
Mòdul 1: Introducció a les APIs RESTful
- Què és una API?
- Història i evolució de les APIs
- Fonaments d'HTTP per a APIs
- Principis bàsics de REST
- Model de maduresa de Richardson i HATEOAS
- REST vs. SOAP
- REST davant de GraphQL, gRPC i webhooks
Mòdul 2: Disseny d'APIs RESTful
- Principis de disseny d'APIs RESTful
- Recursos i URIs
- Mètodes HTTP
- Codis d'estat HTTP
- Representacions, capçaleres i negociació de contingut
- Filtratge, ordenació, paginació i cerca
- Versionat d'APIs
- Documentació d'APIs
Mòdul 3: Desenvolupament d'APIs RESTful
- Configuració de l'entorn de desenvolupament
- Creació d'un servidor bàsic
- Gestió de peticions i respostes
- Validació de dades d'entrada
- Persistència i capa d'accés a dades
- Autenticació i autorització
- Gestió d'errors
- Proves i validació
Mòdul 4: Bones Pràctiques i Seguretat
- Bones pràctiques en el disseny d'APIs
- Seguretat en APIs RESTful
- OAuth 2.0 i OpenID Connect a la pràctica
- Rate limiting i throttling
- CORS i polítiques de seguretat
- Memòria cau HTTP i rendiment
- Observabilitat: logs, mètriques i traces
Mòdul 5: Eines i Frameworks
- Postman per a proves d'APIs
- Swagger i OpenAPI per a documentació
- Frameworks populars per a APIs RESTful
- Contractes, mocks i proves automatitzades d'API
- Integració contínua i desplegament
- API gateways i portals de desenvolupador
