Si treballes amb integracions prou temps, tard o d'hora et trobaràs amb SOAP. No és cap relíquia arqueològica: bancs, asseguradores, administracions públiques i sistemes sanitaris continuen exposant milers de serveis SOAP en producció, i no desapareixeran a curt termini. Entendre què és, per què es va dissenyar així i en què es diferencia de REST et servirà per a dues coses molt concretes: integrar-t'hi quan toqui, i comprendre millor per què REST va prendre les decisions que va prendre. En aquesta lliçó veurem la mateixa consulta de la Botiga Aroma —obtenir les dades d'un cafè— resolta en tots dos estils, costat a costat.
Contingut
- Què és SOAP exactament
- L'estructura del sobre: Envelope, Header i Body
- El contracte: WSDL
- La pila WS-*
- El mateix cas costat a costat: consultar un cafè
- Gestió d'errors: SOAP Fault davant dels codis HTTP
- Taula comparativa completa
- Quan continua tenint sentit SOAP
- Quan triar REST
- Façanes REST sobre serveis SOAP heretats
- Què és SOAP exactament
SOAP va néixer com a acrònim de Simple Object Access Protocol, encara que des de la versió 1.2 el W3C va deixar d'expandir les sigles (entre altres coses, perquè de simple en tenia poc). A diferència de REST, que és un estil arquitectònic, SOAP és un protocol: té una especificació formal que defineix exactament com ha de ser un missatge vàlid.
Els seus trets definitoris:
- Basat en XML: tot missatge és un document XML amb una estructura fixa.
- Independent del transport: pot viatjar sobre HTTP, però també sobre SMTP (correu), JMS (cues de missatges) o TCP pur. Aquesta neutralitat va ser un objectiu de disseny explícit.
- Orientat a operacions, no a recursos: s'invoquen mètodes com ara
obtenirCafeocrearComanda, a l'estil RPC. - Contracte formal descrit en WSDL, llegible per màquines, del qual es generen clients automàticament.
- Extensible mitjançant la pila WS-* per a seguretat, fiabilitat i transaccions.
Quan SOAP viatja sobre HTTP —el cas més habitual— fa servir sempre POST contra un únic endpoint. En reconeixeràs el patró: és exactament el nivell 0 del model de Richardson que vam veure a la lliçó anterior. HTTP actua com a simple túnel de transport.
- L'estructura del sobre: Envelope, Header i Body
Tot missatge SOAP és un "sobre" amb la mateixa anatomia:
graph TD
E["<b>Envelope</b><br/>el sobre; arrel obligatòria"] --> H["<b>Header</b><br/>opcional: seguretat, transaccions,<br/>encaminament, correlació"]
E --> B["<b>Body</b><br/>obligatori: la crida<br/>o el seu resultat"]
B --> F["<b>Fault</b><br/>dins de Body,<br/>només si hi ha error"]
- Envelope: l'element arrel. Identifica el document com a missatge SOAP.
- Header: opcional, conté metadades d'infraestructura. Aquí és on viuen WS-Security (signatures, credencials), els identificadors de transacció i l'encaminament. És l'equivalent conceptual a les capçaleres HTTP, però dins del missatge, cosa que permet que sobrevisquin a qualsevol canvi de transport.
- Body: obligatori, conté la càrrega útil: l'operació invocada amb els seus paràmetres, o el resultat.
- Fault: un element especial dins de
Bodyque representa un error.
Aquesta separació entre Header i Body és més elegant del que sembla: permet que un intermediari processi la seguretat del Header sense tocar el contingut de negoci, i que el missatge signat continuï sent verificable encara que canviï de transport tres vegades al llarg del seu recorregut.
- El contracte: WSDL
WSDL (Web Services Description Language) és un document XML que descriu formalment el servei: quines operacions ofereix, quins tipus de dades fa servir, quins missatges s'intercanvien i a quina adreça està disponible.
El seu valor pràctic és enorme i convé reconèixer-lo: a partir d'un WSDL, les eines generen automàticament el codi client complet en Java, C# o el llenguatge que sigui. El desenvolupador escriu servei.obtenirCafe("caf_001") i no veu ni un sol byte d'XML.
Un fragment simplificat del WSDL de la Botiga Aroma:
<definitions name="ServeiCafes"
targetNamespace="http://botigaaroma.example/serveis"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- 1. Tipus: l'estructura exacta de les dades, validable -->
<types>
<xsd:schema targetNamespace="http://botigaaroma.example/serveis">
<xsd:element name="ObtenirCafePeticio">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="cafeId" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="ObtenirCafeResposta">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="id" type="xsd:string"/>
<xsd:element name="nom" type="xsd:string"/>
<xsd:element name="origen" type="xsd:string"/>
<xsd:element name="torrefaccio" type="xsd:string"/>
<xsd:element name="preuEuros" type="xsd:decimal"/>
<xsd:element name="estoc" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</types>
<!-- 2. Operacions disponibles -->
<portType name="CafesPortType">
<operation name="obtenirCafe">
<input message="tns:ObtenirCafePeticio"/>
<output message="tns:ObtenirCafeResposta"/>
</operation>
</portType>
<!-- 3. On viu el servei -->
<service name="ServeiCafes">
<port name="CafesPort" binding="tns:CafesBinding">
<soap:address location="https://serveis.botigaaroma.example/cafes"/>
</port>
</service>
</definitions>Observa la fortalesa real d'aquest enfocament: preuEuros està declarat com a xsd:decimal i estoc com a xsd:int. Un missatge que enviï "catorze cinquanta" és invàlid i es rebutja automàticament, sense escriure ni una línia de validació. En REST, aquest paper el compleixen avui OpenAPI i JSON Schema, però de manera opcional (lliçons 03-04 i 05-02).
- La pila WS-*
Sobre SOAP s'hi va construir una família d'especificacions per cobrir necessitats empresarials que HTTP no resolia per si mateix:
| Especificació | Què aporta | Equivalent aproximat al món REST |
|---|---|---|
| WS-Security | Signatura i xifratge a nivell de missatge, credencials al Header |
TLS (a nivell de canal) + JWT signats |
| WS-ReliableMessaging | Garantia de lliurament i d'ordre, amb reintents i acusaments | Reintents amb idempotència; cues de missatges |
| WS-AtomicTransaction | Transaccions distribuïdes entre diversos serveis (confirmar-ho tot o res) | No hi ha equivalent directe: patrons saga, compensacions |
| WS-Addressing | Adreçament i correlació independents del transport | Capçaleres HTTP i de correlació |
| WS-Policy | Declaració de requisits (quin xifratge exigeix el servei) | Documentació i configuració del gateway |
Hi ha dues capacitats aquí que REST realment no iguala i convé reconèixer-ho sense complexos:
- Seguretat a nivell de missatge. TLS xifra el canal: a cada salt intermedi el missatge es desxifra. WS-Security signa i xifra el contingut, de manera que pot travessar cinc intermediaris i continuar sent verificable a destinació. Per a una ordre de transferència bancària amb validesa legal, la diferència no és teòrica.
- Transaccions distribuïdes. WS-AtomicTransaction permet coordinar una operació que abasta diversos serveis amb confirmació en dues fases. Al món REST es resol amb patrons de compensació, que són més simples d'operar però ofereixen garanties més febles.
El preu de tot això va ser la complexitat: les especificacions es comptaven per desenes, no totes les implementacions eren compatibles entre si, i desenvolupar sense un IDE que generés el codi era molt costós.
- El mateix cas costat a costat: consultar un cafè
No hi ha res que aclareixi tant com veure la mateixa operació en tots dos estils. Volem obtenir les dades del cafè caf_001 de la Botiga Aroma.
En SOAP
La petició:
POST /serveis/cafes HTTP/1.1
Host: serveis.botigaaroma.example
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://botigaaroma.example/serveis/obtenirCafe"
Content-Length: 412
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:bot="http://botigaaroma.example/serveis">
<soap:Header>
<bot:Credencials>
<bot:usuari>panell_intern</bot:usuari>
<bot:token>eyJhbGciOiJIUzI1NiJ9...</bot:token>
</bot:Credencials>
</soap:Header>
<soap:Body>
<bot:ObtenirCafePeticio>
<bot:cafeId>caf_001</bot:cafeId>
</bot:ObtenirCafePeticio>
</soap:Body>
</soap:Envelope>La resposta:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 498
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:bot="http://botigaaroma.example/serveis">
<soap:Body>
<bot:ObtenirCafeResposta>
<bot:id>caf_001</bot:id>
<bot:nom>Etiòpia Yirgacheffe</bot:nom>
<bot:origen>Etiòpia</bot:origen>
<bot:torrefaccio>clar</bot:torrefaccio>
<bot:preuEuros>14.50</bot:preuEuros>
<bot:estoc>120</bot:estoc>
</bot:ObtenirCafeResposta>
</soap:Body>
</soap:Envelope>Coses que val la pena assenyalar:
- Es fa servir
POSTencara que l'operació només llegeix dades. Conseqüència: cap memòria cau intermèdia no pot reutilitzar aquesta resposta. - L'endpoint és únic (
/serveis/cafes); el cafè concret va al cos. No hi ha cap URL que identifiquicaf_001, així que no es pot enllaçar ni desar com a adreça d'interès. - La capçalera
SOAPActionindica quina operació s'invoca. És un mecanisme propi de SOAP, aliè a HTTP. - Els espais de noms (
xmlns) eviten col·lisions entre vocabularis, a canvi de molt soroll visual. - La resposta és
200 OKfins i tot quan hi ha error de negoci: el resultat real és al cos.
En REST
La petició:
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..." \
-H "Accept: application/json" \
https://api.botigaaroma.example/v1/cafes/caf_001En cru:
GET /v1/cafes/caf_001 HTTP/1.1
Host: api.botigaaroma.example
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...La resposta:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Cache-Control: public, max-age=300
ETag: "a7f3c9"
{
"id": "caf_001",
"nom": "Etiòpia Yirgacheffe",
"origen": "Etiòpia",
"torrefaccio": "clar",
"preuEuros": 14.50,
"estoc": 120
}La comparació de mides és demolidora: uns 900 bytes d'anada i tornada en SOAP davant d'uns 200 en REST, per exactament la mateixa informació. En una app mòbil que consulta el catàleg centenars de vegades, això es tradueix en dades, bateria i temps.
Però l'estalvi de bytes no és el més important. El que és decisiu és que en REST:
- El cafè té una URL pròpia que es pot compartir, enllaçar i provar des del navegador.
- L'operació és un
GET, així que és cacheable (max-age=300) i segura de reintentar. - El resultat es comunica amb el codi d'estat del protocol mateix.
- Qualsevol el pot provar amb
curlen deu segons, sense generar codi ni instal·lar res.
- Gestió d'errors: SOAP Fault davant dels codis HTTP
Quan el cafè no existeix, SOAP respon amb un Fault:
HTTP/1.1 500 Internal Server Error
Content-Type: text/xml; charset=utf-8
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<soap:Fault>
<soap:Code>
<soap:Value>soap:Sender</soap:Value>
</soap:Code>
<soap:Reason>
<soap:Text xml:lang="ca">El cafè sol·licitat no existeix</soap:Text>
</soap:Reason>
<soap:Detail>
<bot:CodiError>CAFE_NO_TROBAT</bot:CodiError>
<bot:CafeId>caf_999</bot:CafeId>
</soap:Detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>Fixa't en la incoherència que arrossega el model: l'error és del client (ha demanat un cafè inexistent), però HTTP retorna 500, que vol dir "error del servidor". SOAP 1.1 hi obligava; SOAP 1.2 ho va flexibilitzar, però el patró continua viu en molts serveis. El resultat és que el monitoratge basat en codis HTTP no serveix: cal obrir l'XML per saber què ha passat.
En REST, el mateix error:
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": {
"codi": "cafe_no_trobat",
"missatge": "No existeix cap cafè amb l'identificador caf_999"
}
}El codi d'estat ja ho diu tot per a les màquines, i el cos aporta el detall per a les persones. Un panell de monitoratge distingeix d'un cop d'ull entre "els clients demanen coses que no existeixen" (4xx) i "el meu servei està trencat" (5xx). El disseny detallat d'errors el veurem a 02-04 i 03-07.
| Aspecte | SOAP Fault | Codis HTTP |
|---|---|---|
| On viu l'error | Al cos XML | A la línia d'estat |
| Distingeix la culpa | Sender / Receiver dins de l'XML |
4xx / 5xx, visible sense analitzar-ho |
| Visible per als intermediaris | No | Sí |
| Estandarditzat | Sí, estructura fixa | Sí, els codis; el cos és lliure (o RFC 9457) |
| Detall de negoci | A Detail |
Al cos JSON |
- Taula comparativa completa
| Criteri | SOAP | REST |
|---|---|---|
| Naturalesa | Protocol amb especificació formal | Estil arquitectònic |
| Format | Només XML | Qualsevol; a la pràctica JSON |
| Contracte | WSDL obligatori i formal | OpenAPI opcional |
| Transport | Agnòstic: HTTP, SMTP, JMS, TCP | HTTP exclusivament |
| Verbs | Només POST (quan va sobre HTTP) |
GET, POST, PUT, PATCH, DELETE |
| Adreçament | Un endpoint per servei | Una URI per recurs |
| Estat | Pot ser amb estat o sense | Sense estat per definició |
| Memòria cau | No aprofita la d'HTTP | Nativa del protocol |
| Seguretat | WS-Security (nivell de missatge) + TLS | TLS + OAuth 2.0 / JWT (nivell de canal) |
| Transaccions | WS-AtomicTransaction | No estàndard; sagues i compensació |
| Errors | SOAP Fault al cos | Codis d'estat + cos |
| Mida del missatge | Gran (sobre, espais de noms, XML) | Reduïda |
| Rendiment | Menor: anàlisi de l'XML i verbositat | Major |
| Corba d'aprenentatge | Pronunciada | Suau |
| Tooling | Excel·lent en Java i .NET; escàs fora | Universal; n'hi ha prou amb un navegador o curl |
| Generació de clients | Automàtica des del WSDL | Automàtica des d'OpenAPI, si existeix |
| Consum des del navegador | Molt incòmode | Natural |
| Adopció actual | Sistemes heretats i sectors regulats | Estàndard de facto al web |
- Quan continua tenint sentit SOAP
Seria un error caricaturitzar SOAP com "allò antic i dolent". Hi ha contextos on les seves propietats continuen sent les adequades:
- Banca i sistemes de pagament interbancaris. Molts protocols financers exigeixen signatura digital del missatge amb validesa probatòria, i sovint l'estàndard del sector ja està definit en SOAP.
- Assegurances. Els intercanvis entre asseguradores i amb organismes reguladors estan estandarditzats en esquemes XML consolidats fa vint anys.
- Sanitat. HL7 i altres estàndards clínics tenen una llarga tradició XML, amb requisits estrictes d'estructura i validació.
- Administració pública. Molts serveis de facturació electrònica, notificacions i signatura estan definits com a serveis SOAP.
- Sistemes heretats. Un ERP amb quinze anys de vida exposa SOAP, i reescriure'l no és una opció realista.
- Requisits de transaccionalitat distribuïda. Quan de debò cal "tot o res" entre diversos serveis amb garanties fortes.
- Contractes que han de ser vinculants i verificables entre organitzacions, amb validació estricta i no-repudi.
El denominador comú: entorns regulats, amb contractes entre organitzacions, requisits legals de signatura i sistemes de llarga vida.
- Quan triar REST
Per a tota la resta, i sens dubte per a un projecte nou orientat al web:
- APIs públiques que vols que la gent adopti sense fricció.
- Aplicacions web i mòbils, on el pes del missatge i la simplicitat del client importen.
- Contingut cacheable, com el catàleg de la Botiga Aroma.
- Ecosistemes de tercers: com més fàcil sigui començar, més integracions tindràs.
- Equips heterogenis amb llenguatges diferents i sense tooling empresarial uniforme.
- Iteració ràpida, on generar i regenerar contractes formals frenaria el desenvolupament.
Per a la Botiga Aroma la decisió és evident: la seva API la consumeixen un web, una app mòbil, un panell intern i socis externs. No hi ha signatura digital amb valor legal, ni transaccions distribuïdes entre organitzacions, i sí una necessitat clara de memòria cau i d'adopció fàcil. REST, sense dubtar-ho.
- Façanes REST sobre serveis SOAP heretats
Un patró que trobaràs amb enorme freqüència a empreses mitjanes i grans: no es pot llençar el sistema SOAP heretat, però els clients moderns (mòbil, web, socis) no volen tocar XML. La solució és una façana REST que tradueix.
graph LR
A["Aroma Mòbil"] -->|"GET /v1/factures/fac_88<br/>JSON"| F["Façana REST<br/>(Node.js / gateway)"]
W["Web"] -->|JSON| F
F -->|"SOAP + XML<br/>obtenirFactura"| L["Sistema de facturació<br/>heretat (SOAP)"]
F -->|"SOAP + XML"| C["ERP comptable<br/>(SOAP)"]
Suposem que la facturació de la Botiga Aroma la porta un ERP antic que només parla SOAP. La façana:
- Rep
GET /v1/comandes/com_5001/facturaamb un token modern. - Valida permisos i tradueix la petició a un sobre SOAP amb les credencials que l'ERP espera.
- Rep l'XML, n'extreu les dades i les converteix en JSON net amb noms coherents amb la resta de l'API.
- Tradueix els
Faulten codis d'estat HTTP adequats (404,403,503). - Hi afegeix memòria cau on tingui sentit, i alleuja la càrrega sobre un sistema antic i fràgil.
Avantatges: els clients nous veuen una API homogènia, el sistema heretat no es toca i es pot substituir per darrere sense que ningú se n'assabenti. Inconvenients: un salt més de latència, una peça més per mantenir i el risc que la façana acabi filtrant conceptes estranys del sistema antic (codis críptics, camps amb noms incomprensibles) si no es cuida el disseny.
Aquesta feina de traducció i homogeneïtzació és exactament una de les funcions d'un API gateway, que veurem a la lliçó 05-06.
Errors Comuns i Consells
- Dir "una API SOAP RESTful". Són coses de categories diferents: SOAP és un protocol, REST un estil. Un servei SOAP és, per construcció, al nivell 0 de Richardson.
- Menysprear SOAP per antic. Si et toca integrar-te amb banca o administració, hi trobaràs solucions sòlides que fa dècades que funcionen. L'actitud professional és entendre per què són així.
- Creure que TLS equival a WS-Security. TLS protegeix el canal punt a punt; WS-Security protegeix el missatge d'extrem a extrem, travessant intermediaris. Són garanties diferents.
- Reproduir SOAP amb JSON. Un endpoint únic que rep
{"operacio": "..."}és SOAP sense els seus avantatges: tens la rigidesa del nivell 0 i cap de les seves garanties formals. - Oblidar el
Content-Typecorrecte en cridar un servei SOAP. SOAP 1.1 esperatext/xml; SOAP 1.2,application/soap+xml. Confondre'ls produeix errors desconcertants. - Dissenyar una façana REST com a calc del servei SOAP. Si la teva API exposa
POST /v1/obtenirFacturaRequest, has traslladat el problema en comptes de resoldre'l. - Consell: si treballes amb un servei SOAP, demana sempre el WSDL primer. Amb ell, eines com SoapUI o els generadors del teu llenguatge et donen un client funcional en minuts.
Exercicis
Exercici 1: analitzar un missatge SOAP
Donat aquest missatge, respon: (a) quina operació invoca?; (b) on viatgen les credencials i per què allà i no en una capçalera HTTP?; (c) es podria posar la resposta a la memòria cau?; (d) quin seria l'equivalent REST d'aquesta operació?
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:bot="http://botigaaroma.example/serveis">
<soap:Header>
<bot:Credencials><bot:token>abc123</bot:token></bot:Credencials>
</soap:Header>
<soap:Body>
<bot:LlistarComandesClientPeticio>
<bot:clientId>cli_842</bot:clientId>
<bot:des>2026-01-01</bot:des>
</bot:LlistarComandesClientPeticio>
</soap:Body>
</soap:Envelope>Exercici 2: triar tecnologia amb criteri
Per a cada escenari, decideix SOAP o REST i justifica-ho amb dos arguments concrets:
- La Botiga Aroma vol que blogs de cafè mostrin el seu catàleg.
- Un banc ha d'enviar ordres de transferència signades digitalment a un altre banc, amb no-repudi i validesa legal.
- Aroma Mòbil necessita carregar el catàleg de pressa en xarxes mòbils lentes.
- Una asseguradora ha d'intercanviar comunicats de sinistre amb un consorci que ja té definit un esquema XML estàndard.
- Un servei intern d'inventari ha d'actualitzar l'estoc en tres sistemes i garantir que, si un falla, cap no queda modificat.
Exercici 3: dissenyar una façana REST
L'ERP heretat de la Botiga Aroma exposa aquestes tres operacions SOAP. Dissenya'n la façana REST equivalent indicant mètode, ruta, codi d'estat en cas d'èxit i quin error HTTP retornaries en el cas indicat.
| Operació SOAP | Descripció | Cas d'error |
|---|---|---|
obtenirFacturaPerComanda(comandaId) |
Retorna la factura d'una comanda | La comanda encara no té factura |
anullarFactura(facturaId, motiu) |
Anul·la una factura emesa | La factura ja està anul·lada |
llistarFacturesClient(clientId, any) |
Factures d'un client en un any | El client no existeix |
Solucions
Solució 1
- (a) Invoca
LlistarComandesClient, i demana les comandes del clientcli_842des de l'1 de gener del 2026. - (b) Les credencials viatgen al
Headerdel sobre SOAP. La raó de disseny és la independència del transport: si el missatge viatja per SMTP o per una cua JMS en comptes d'HTTP, no hi ha capçaleres HTTP on posar-les. A més, així poden anar signades juntament amb el missatge i sobreviure als intermediaris. - (c) No. És un
POSTa un endpoint únic, i ni les memòries cau HTTP ni els servidors intermediaris poden saber que en realitat és una lectura. Es perd del tot el mecanisme de memòria cau del protocol. - (d)
GET /v1/comandes?clientId=cli_842&des=2026-01-01, ambAuthorization: Bearer abc123i resposta200 OK. Alternativa igualment vàlida:GET /v1/clients/cli_842/comandes?des=2026-01-01, que expressa la relació a la ruta.
Solució 2
- REST. L'adopció per part de tercers ha de ser immediata (n'hi ha prou amb
curlofetch), i el catàleg és contingut cacheable, amb la qual cosa es redueixen càrrega i latència. - SOAP. Cal signatura a nivell de missatge amb no-repudi (WS-Security), que TLS no proporciona, i el més probable és que l'estàndard interbancari del sector ja estigui definit en SOAP.
- REST. Els missatges JSON pesen una fracció d'un sobre SOAP, i les respostes del catàleg es poden posar a la memòria cau del dispositiu i d'un CDN.
- SOAP. L'esquema XML ja existeix i és vinculant entre les parts; el WSDL genera clients validats automàticament i la validació estricta és un requisit, no una comoditat.
- Depèn, i és el cas més matisat. Si s'exigeix atomicitat estricta entre sistemes heterogenis, WS-AtomicTransaction l'ofereix de manera estàndard. En una arquitectura moderna, però, l'habitual és resoldre-ho amb REST o missatgeria més un patró saga amb operacions de compensació, i acceptar consistència eventual a canvi de molta menys complexitat operativa. L'important és que la decisió sigui explícita.
Solució 3
GET /v1/comandes/com_5001/factura -> 200 OK | error: 404 Not Found POST /v1/factures/fac_88/anullacio -> 201 Created (o 200 OK) | error: 409 Conflict GET /v1/clients/cli_842/factures?any=2026 -> 200 OK | error: 404 Not Found
Justificació:
- Obtenir factura: és una lectura, per tant
GET. La factura es modela com a subrecurs de la comanda, cosa que en reflecteix la relació. Si encara no existeix,404 Not Found, perquè el recurs sol·licitat no hi és. - Anul·lar factura: no es fa servir
DELETE, perquè anul·lar no és esborrar: la factura continua existint amb estat anul·lat, i en comptabilitat això és obligatori. L'anul·lació es modela com un subrecurs al qual es faPOST, enviant-hi el motiu al cos. Si ja estava anul·lada,409 Conflict, que expressa exactament "l'estat actual del recurs impedeix aquesta operació". (Una alternativa defensable ésPATCH /v1/factures/fac_88amb{"estat":"anullada"}; el subrecurs resulta més expressiu quan l'acció exigeix dades pròpies com ara el motiu.) - Llistar factures d'un client:
GETsobre la subcol·lecció, amb l'any com a filtre a la query string, ja que modula la consulta i no identifica el recurs. Si el client no existeix,404; si existeix però no té factures aquell any,200 OKamb una llista buida, no404: la col·lecció existeix, simplement és buida.
Conclusió
SOAP i REST responen a dues filosofies diferents: SOAP és un protocol formal, agnòstic respecte al transport, amb contracte WSDL i una pila d'extensions per a seguretat, fiabilitat i transaccions; REST és un estil que s'assenta en HTTP i n'aprofita els recursos, verbs, codis i memòria cau. Hem vist la mateixa consulta d'un cafè en tots dos, i hem comprovat que SOAP multiplica per quatre la mida del missatge, renuncia a la memòria cau i amaga el resultat dins del cos, mentre que REST converteix el cafè en un recurs adreçable, cacheable i provable des del navegador. També hem reconegut què fa millor SOAP —signatura de missatge d'extrem a extrem, validació estricta i transaccions distribuïdes— i per què continua viu a la banca, les assegurances, la sanitat i l'administració, així com el patró habitual d'embolcallar aquests serveis amb una façana REST.
Queda una última peça del mapa. A la lliçó següent, REST davant de GraphQL, gRPC i webhooks, veurem les alternatives contemporànies: quins problemes concrets de REST resol cadascuna, quins problemes nous introdueixen i per què avui el normal no és triar-ne una de sola, sinó combinar-les. Amb això tancarem el mòdul i estarem a punt per dissenyar l'API de la Botiga Aroma al mòdul 2.
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
