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
