En aquest cas d'estudi, dissenyarem i desenvoluparem una API RESTful per a una botiga en línia. Aquest projecte ens permetrà aplicar els conceptes apresos en els mòduls anteriors i veure com es poden implementar en un escenari real.
Objectius del cas d'estudi
- Dissenyar l'arquitectura de l'API: Definir els recursos, les URIs, els mètodes HTTP i els codis d'estat.
- Desenvolupar l'API: Implementar l'API utilitzant un framework popular.
- Provar l'API: Assegurar-nos que l'API funciona correctament i compleix amb els requisits.
- Documentar l'API: Crear una documentació clara i completa per a l'API.
- Disseny de l'arquitectura de l'API
Recursos i URIs
Els recursos principals de la nostra botiga en línia seran:
- Productes: Informació sobre els productes disponibles.
- Categories: Classificació dels productes.
- Usuaris: Informació sobre els clients.
- Comandes: Informació sobre les comandes realitzades pels clients.
Recurs | URI Base |
---|---|
Productes | /products |
Categories | /categories |
Usuaris | /users |
Comandes | /orders |
Mètodes HTTP
Utilitzarem els següents mètodes HTTP per interactuar amb els recursos:
Operació | Mètode HTTP | URI | Descripció |
---|---|---|---|
Obtenir productes | GET |
/products |
Obtenir una llista de productes |
Crear producte | POST |
/products |
Afegir un nou producte |
Obtenir producte | GET |
/products/{id} |
Obtenir un producte específic |
Actualitzar producte | PUT |
/products/{id} |
Actualitzar un producte |
Eliminar producte | DELETE |
/products/{id} |
Eliminar un producte |
Obtenir categories | GET |
/categories |
Obtenir una llista de categories |
Crear categoria | POST |
/categories |
Afegir una nova categoria |
Obtenir categoria | GET |
/categories/{id} |
Obtenir una categoria específica |
Actualitzar categoria | PUT |
/categories/{id} |
Actualitzar una categoria |
Eliminar categoria | DELETE |
/categories/{id} |
Eliminar una categoria |
Obtenir usuaris | GET |
/users |
Obtenir una llista d'usuaris |
Crear usuari | POST |
/users |
Afegir un nou usuari |
Obtenir usuari | GET |
/users/{id} |
Obtenir un usuari específic |
Actualitzar usuari | PUT |
/users/{id} |
Actualitzar un usuari |
Eliminar usuari | DELETE |
/users/{id} |
Eliminar un usuari |
Obtenir comandes | GET |
/orders |
Obtenir una llista de comandes |
Crear comanda | POST |
/orders |
Afegir una nova comanda |
Obtenir comanda | GET |
/orders/{id} |
Obtenir una comanda específica |
Actualitzar comanda | PUT |
/orders/{id} |
Actualitzar una comanda |
Eliminar comanda | DELETE |
/orders/{id} |
Eliminar una comanda |
Codis d'estat HTTP
Utilitzarem els següents codis d'estat HTTP per indicar el resultat de les operacions:
Codi d'estat | Descripció |
---|---|
200 OK |
Operació realitzada correctament |
201 Created |
Recurs creat correctament |
400 Bad Request |
Sol·licitud incorrecta |
401 Unauthorized |
No autoritzat |
404 Not Found |
Recurs no trobat |
500 Internal Server Error |
Error del servidor |
- Desenvolupament de l'API
Configuració de l'entorn de desenvolupament
Per aquest cas d'estudi, utilitzarem Node.js amb Express, un framework popular per al desenvolupament d'APIs RESTful.
Instal·lació de Node.js i Express
# Instal·lació de Node.js (si no està instal·lat) $ sudo apt-get install nodejs $ sudo apt-get install npm # Creació d'un nou projecte $ mkdir online-store-api $ cd online-store-api $ npm init -y # Instal·lació d'Express $ npm install express
Creació d'un servidor bàsic
// server.js const express = require('express'); const app = express(); const port = 3000; app.use(express.json()); app.get('/', (req, res) => { res.send('Benvingut a la botiga en línia!'); }); app.listen(port, () => { console.log(`Servidor escoltant a http://localhost:${port}`); });
Gestió de peticions i respostes
Afegirem rutes per gestionar les peticions als recursos definits anteriorment.
// routes/products.js const express = require('express'); const router = express.Router(); let products = []; // Obtenir tots els productes router.get('/', (req, res) => { res.status(200).json(products); }); // Crear un nou producte router.post('/', (req, res) => { const product = req.body; products.push(product); res.status(201).json(product); }); // Obtenir un producte específic router.get('/: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.status(200).json(product); }); // Actualitzar un producte router.put('/: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; product.price = req.body.price; res.status(200).json(product); }); // Eliminar un producte router.delete('/: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(200).send('Producte eliminat'); }); module.exports = router;
Integració de les rutes al servidor principal
// server.js const express = require('express'); const app = express(); const port = 3000; app.use(express.json()); const productsRouter = require('./routes/products'); app.use('/products', productsRouter); app.get('/', (req, res) => { res.send('Benvingut a la botiga en línia!'); }); app.listen(port, () => { console.log(`Servidor escoltant a http://localhost:${port}`); });
- Proves i validació
Utilitzarem Postman per provar les diferents rutes de la nostra API. Crearem col·leccions de peticions per a cada recurs i verificarem que les respostes siguin correctes.
Exemple de peticions amb Postman
- GET /products: Obtenir tots els productes.
- POST /products: Crear un nou producte.
- GET /products/{id}: Obtenir un producte específic.
- PUT /products/{id}: Actualitzar un producte.
- DELETE /products/{id}: Eliminar un producte.
- Documentació de l'API
Utilitzarem Swagger per documentar la nostra API. Swagger ens permet crear una documentació interactiva que facilita la comprensió i l'ús de l'API.
Instal·lació de Swagger
Configuració de Swagger
// server.js const express = require('express'); const app = express(); const port = 3000; app.use(express.json()); const productsRouter = require('./routes/products'); app.use('/products', productsRouter); const swaggerUi = require('swagger-ui-express'); const swaggerJsdoc = require('swagger-jsdoc'); const swaggerOptions = { swaggerDefinition: { info: { title: 'Botiga en línia API', version: '1.0.0', description: 'API per gestionar una botiga en línia', }, }, apis: ['./routes/*.js'], }; const swaggerDocs = swaggerJsdoc(swaggerOptions); app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocs)); app.get('/', (req, res) => { res.send('Benvingut a la botiga en línia!'); }); app.listen(port, () => { console.log(`Servidor escoltant a http://localhost:${port}`); });
Documentació de les rutes amb Swagger
// routes/products.js const express = require('express'); const router = express.Router(); let products = []; /** * @swagger * /products: * get: * summary: Obtenir tots els productes * responses: * 200: * description: Llista de productes */ router.get('/', (req, res) => { res.status(200).json(products); }); /** * @swagger * /products: * post: * summary: Crear un nou producte * parameters: * - in: body * name: product * description: El producte a crear * schema: * type: object * required: * - name * - price * properties: * name: * type: string * price: * type: number * responses: * 201: * description: Producte creat correctament */ router.post('/', (req, res) => { const product = req.body; products.push(product); res.status(201).json(product); }); /** * @swagger * /products/{id}: * get: * summary: Obtenir un producte específic * parameters: * - in: path * name: id * required: true * description: ID del producte * schema: * type: integer * responses: * 200: * description: Producte trobat * 404: * description: Producte no trobat */ router.get('/: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.status(200).json(product); }); /** * @swagger * /products/{id}: * put: * summary: Actualitzar un producte * parameters: * - in: path * name: id * required: true * description: ID del producte * schema: * type: integer * - in: body * name: product * description: El producte a actualitzar * schema: * type: object * properties: * name: * type: string * price: * type: number * responses: * 200: * description: Producte actualitzat correctament * 404: * description: Producte no trobat */ router.put('/: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; product.price = req.body.price; res.status(200).json(product); }); /** * @swagger * /products/{id}: * delete: * summary: Eliminar un producte * parameters: * - in: path * name: id * required: true * description: ID del producte * schema: * type: integer * responses: * 200: * description: Producte eliminat correctament * 404: * description: Producte no trobat */ router.delete('/: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(200).send('Producte eliminat'); }); module.exports = router;
Conclusió
En aquest cas d'estudi, hem dissenyat i desenvolupat una API RESTful per a una botiga en línia, aplicant els principis i pràctiques apreses en els mòduls anteriors. Hem creat una arquitectura clara, implementat les rutes necessàries, provat l'API amb Postman i documentat l'API amb Swagger. Aquest projecte ens ha permès veure com es poden aplicar els conceptes teòrics en un escenari pràctic i real.
Curs de REST API: Principis de Disseny i Desenvolupament d'APIs RESTful
Mòdul 1: Introducció a les APIs RESTful
Mòdul 2: Disseny d'APIs RESTful
- Principis de disseny d'APIs RESTful
- Recursos i URIs
- Mètodes HTTP
- Codis d'estat HTTP
- 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
- 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
- Rate limiting i throttling
- CORS i polítiques de seguretat
Mòdul 5: Eines i Frameworks
- Postman per a proves d'APIs
- Swagger per a documentació
- Frameworks populars per a APIs RESTful
- Integració contínua i desplegament