Introducció a les APIs RESTful
Les APIs RESTful (Representational State Transfer) són un estil arquitectònic per a la creació de serveis web que permeten la comunicació entre sistemes mitjançant HTTP. Aquest estil es basa en un conjunt de principis i restriccions que faciliten la creació de serveis escalables i mantenibles.
Conceptes Clau de REST
- Recursos: En REST, tot és un recurs. Un recurs pot ser qualsevol cosa que es pugui identificar de manera única, com ara un usuari, un producte o una comanda. Els recursos es representen mitjançant URLs.
 - Verbs HTTP: REST utilitza els verbs HTTP per realitzar operacions sobre els recursos. Els verbs més comuns són:
- GET: Obtenir una representació d'un recurs.
 - POST: Crear un nou recurs.
 - PUT: Actualitzar un recurs existent.
 - DELETE: Eliminar un recurs.
 
 - Estatless: Les interaccions amb l'API han de ser sense estat, és a dir, cada sol·licitud del client al servidor ha de contenir tota la informació necessària per entendre i processar la sol·licitud.
 - Representacions: Els recursos es poden representar en diferents formats, com ara JSON, XML, HTML, etc. JSON és el format més utilitzat en APIs RESTful.
 - HATEOAS (Hypermedia As The Engine Of Application State): Els clients interactuen amb l'API principalment a través d'hipervincles proporcionats per les respostes del servidor.
 
Estructura d'una API RESTful
Una API RESTful ben dissenyada segueix una estructura clara i consistent. A continuació es mostra un exemple d'una API per gestionar usuaris:
| Mètode HTTP | URL | Descripció | 
|---|---|---|
| GET | /users | Obtenir una llista d'usuaris | 
| GET | /users/{id} | Obtenir un usuari específic | 
| POST | /users | Crear un nou usuari | 
| PUT | /users/{id} | Actualitzar un usuari existent | 
| DELETE | /users/{id} | Eliminar un usuari | 
Exemple Pràctic
A continuació es mostra un exemple pràctic d'una API RESTful utilitzant Node.js i Express:
const express = require('express');
const app = express();
const port = 3000;
app.use(express.json());
let users = [
    { id: 1, name: 'John Doe' },
    { id: 2, name: 'Jane Doe' }
];
// Obtenir una llista d'usuaris
app.get('/users', (req, res) => {
    res.json(users);
});
// Obtenir un usuari específic
app.get('/users/:id', (req, res) => {
    const user = users.find(u => u.id === parseInt(req.params.id));
    if (!user) return res.status(404).send('Usuari no trobat');
    res.json(user);
});
// Crear un nou usuari
app.post('/users', (req, res) => {
    const newUser = {
        id: users.length + 1,
        name: req.body.name
    };
    users.push(newUser);
    res.status(201).json(newUser);
});
// Actualitzar un usuari existent
app.put('/users/:id', (req, res) => {
    const user = users.find(u => u.id === parseInt(req.params.id));
    if (!user) return res.status(404).send('Usuari no trobat');
    user.name = req.body.name;
    res.json(user);
});
// Eliminar un usuari
app.delete('/users/:id', (req, res) => {
    const userIndex = users.findIndex(u => u.id === parseInt(req.params.id));
    if (userIndex === -1) return res.status(404).send('Usuari no trobat');
    users.splice(userIndex, 1);
    res.status(204).send();
});
app.listen(port, () => {
    console.log(`API RESTful escoltant a http://localhost:${port}`);
});Exercici Pràctic
Objectiu: Crear una API RESTful per gestionar productes.
Requisits:
- Crear un nou projecte Node.js amb Express.
 - Definir un array de productes amb els camps 
idiname. - Implementar les operacions CRUD (Create, Read, Update, Delete) per als productes.
 
Solució:
const express = require('express');
const app = express();
const port = 3000;
app.use(express.json());
let products = [
    { id: 1, name: 'Producte A' },
    { id: 2, name: 'Producte B' }
];
// Obtenir una llista de productes
app.get('/products', (req, res) => {
    res.json(products);
});
// Obtenir un producte específic
app.get('/products/:id', (req, res) => {
    const product = products.find(p => p.id === parseInt(req.params.id));
    if (!product) return res.status(404).send('Producte no trobat');
    res.json(product);
});
// Crear un nou producte
app.post('/products', (req, res) => {
    const newProduct = {
        id: products.length + 1,
        name: req.body.name
    };
    products.push(newProduct);
    res.status(201).json(newProduct);
});
// Actualitzar un producte existent
app.put('/products/:id', (req, res) => {
    const product = products.find(p => p.id === parseInt(req.params.id));
    if (!product) return res.status(404).send('Producte no trobat');
    product.name = req.body.name;
    res.json(product);
});
// Eliminar un producte
app.delete('/products/:id', (req, res) => {
    const productIndex = products.findIndex(p => p.id === parseInt(req.params.id));
    if (productIndex === -1) return res.status(404).send('Producte no trobat');
    products.splice(productIndex, 1);
    res.status(204).send();
});
app.listen(port, () => {
    console.log(`API RESTful escoltant a http://localhost:${port}`);
});Errors Comuns i Consells
- No utilitzar verbs en les URLs: Les URLs han de representar recursos, no accions. Per exemple, utilitzar 
/usersen lloc de/getUsers. - No gestionar correctament els codis d'estat HTTP: Assegura't d'utilitzar els codis d'estat HTTP adequats per a cada resposta (200 OK, 201 Created, 404 Not Found, etc.).
 - No validar les dades d'entrada: Sempre valida les dades d'entrada per evitar errors i problemes de seguretat.
 
Conclusió
Les APIs RESTful són una eina poderosa per a la comunicació entre microserveis. Comprendre els principis bàsics i les millors pràctiques per dissenyar i implementar APIs RESTful és essencial per construir aplicacions escalables i mantenibles. En el proper tema, explorarem la missatgeria asíncrona com una alternativa a les APIs RESTful per a la comunicació entre microserveis.
Curs de Microserveis
Mòdul 1: Introducció als Microserveis
- Conceptes Bàsics de Microserveis
 - Avantatges i Desavantatges dels Microserveis
 - Comparació amb Arquitectura Monolítica
 
Mòdul 2: Disseny de Microserveis
- Principis de Disseny de Microserveis
 - Descomposició d'Aplicacions Monolítiques
 - Definició de Bounded Contexts
 
