En este caso de estudio, diseñaremos y desarrollaremos una API RESTful para una tienda en línea. Este ejercicio práctico te permitirá aplicar los conceptos aprendidos en los módulos anteriores y comprender cómo se integran en un proyecto real.
Objetivos del Caso de Estudio
- Diseñar la estructura de la API: Definir los recursos, URIs, métodos HTTP y códigos de estado.
- Desarrollar la API: Implementar la API utilizando un framework popular.
- Asegurar la API: Implementar autenticación, autorización y manejo de errores.
- Documentar y probar la API: Utilizar herramientas como Swagger y Postman.
- Diseño de la API
1.1 Recursos y URIs
Los recursos principales de nuestra tienda en línea serán:
- Productos: Información sobre los productos disponibles.
- Usuarios: Información sobre los usuarios registrados.
- Órdenes: Información sobre las órdenes de compra.
Estructura de URIs
| Recurso | URI Base | Descripción |
|---|---|---|
| Productos | /api/products |
Gestión de productos |
| Usuarios | /api/users |
Gestión de usuarios |
| Órdenes | /api/orders |
Gestión de órdenes de compra |
1.2 Métodos HTTP
| Recurso | Método HTTP | URI | Descripción |
|---|---|---|---|
| Productos | GET | /api/products |
Obtener lista de productos |
| Productos | GET | /api/products/{id} |
Obtener un producto específico |
| Productos | POST | /api/products |
Crear un nuevo producto |
| Productos | PUT | /api/products/{id} |
Actualizar un producto existente |
| Productos | DELETE | /api/products/{id} |
Eliminar un producto |
| Usuarios | GET | /api/users |
Obtener lista de usuarios |
| Usuarios | GET | /api/users/{id} |
Obtener un usuario específico |
| Usuarios | POST | /api/users |
Crear un nuevo usuario |
| Usuarios | PUT | /api/users/{id} |
Actualizar un usuario existente |
| Usuarios | DELETE | /api/users/{id} |
Eliminar un usuario |
| Órdenes | GET | /api/orders |
Obtener lista de órdenes |
| Órdenes | GET | /api/orders/{id} |
Obtener una orden específica |
| Órdenes | POST | /api/orders |
Crear una nueva orden |
| Órdenes | PUT | /api/orders/{id} |
Actualizar una orden existente |
| Órdenes | DELETE | /api/orders/{id} |
Eliminar una orden |
1.3 Códigos de Estado HTTP
| Código | Descripción |
|---|---|
| 200 | OK |
| 201 | Created |
| 204 | No Content |
| 400 | Bad Request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not Found |
| 500 | Internal Server Error |
- Desarrollo de la API
2.1 Configuración del Entorno de Desarrollo
Para este caso de estudio, utilizaremos Node.js con el framework Express.
Instalación de Node.js y Express
# Instalar Node.js sudo apt-get install nodejs # Instalar npm (Node Package Manager) sudo apt-get install npm # Crear un nuevo proyecto mkdir online-store-api cd online-store-api npm init -y # Instalar Express npm install express
2.2 Creación de un Servidor Básico
// server.js
const express = require('express');
const app = express();
const port = 3000;
app.use(express.json());
app.get('/', (req, res) => {
res.send('Bienvenido a la API de la tienda en línea');
});
app.listen(port, () => {
console.log(`Servidor escuchando en http://localhost:${port}`);
});2.3 Manejo de Peticiones y Respuestas
Ejemplo: Obtener lista de productos
// products.js
const express = require('express');
const router = express.Router();
let products = [
{ id: 1, name: 'Producto 1', price: 100 },
{ id: 2, name: 'Producto 2', price: 200 },
];
router.get('/', (req, res) => {
res.status(200).json(products);
});
router.get('/:id', (req, res) => {
const product = products.find(p => p.id === parseInt(req.params.id));
if (!product) return res.status(404).send('Producto no encontrado');
res.status(200).json(product);
});
router.post('/', (req, res) => {
const product = {
id: products.length + 1,
name: req.body.name,
price: req.body.price,
};
products.push(product);
res.status(201).json(product);
});
router.put('/:id', (req, res) => {
const product = products.find(p => p.id === parseInt(req.params.id));
if (!product) return res.status(404).send('Producto no encontrado');
product.name = req.body.name;
product.price = req.body.price;
res.status(200).json(product);
});
router.delete('/:id', (req, res) => {
const productIndex = products.findIndex(p => p.id === parseInt(req.params.id));
if (productIndex === -1) return res.status(404).send('Producto no encontrado');
products.splice(productIndex, 1);
res.status(204).send();
});
module.exports = router;Integración del Router en el Servidor Principal
// server.js
const express = require('express');
const app = express();
const port = 3000;
app.use(express.json());
const productsRouter = require('./products');
app.use('/api/products', productsRouter);
app.listen(port, () => {
console.log(`Servidor escuchando en http://localhost:${port}`);
});
- Asegurar la API
3.1 Autenticación y Autorización
Para la autenticación, utilizaremos JSON Web Tokens (JWT).
Instalación de JWT
Implementación de Autenticación
// auth.js
const jwt = require('jsonwebtoken');
const express = require('express');
const router = express.Router();
const users = [
{ id: 1, username: 'user1', password: 'password1' },
{ id: 2, username: 'user2', password: 'password2' },
];
router.post('/login', (req, res) => {
const user = users.find(u => u.username === req.body.username && u.password === req.body.password);
if (!user) return res.status(401).send('Credenciales inválidas');
const token = jwt.sign({ id: user.id }, 'secretKey', { expiresIn: '1h' });
res.status(200).json({ token });
});
module.exports = router;Middleware de Autorización
// authMiddleware.js
const jwt = require('jsonwebtoken');
function authMiddleware(req, res, next) {
const token = req.header('Authorization');
if (!token) return res.status(401).send('Acceso denegado. No se proporcionó un token.');
try {
const decoded = jwt.verify(token, 'secretKey');
req.user = decoded;
next();
} catch (ex) {
res.status(400).send('Token inválido.');
}
}
module.exports = authMiddleware;Protección de Rutas
// server.js
const express = require('express');
const app = express();
const port = 3000;
app.use(express.json());
const productsRouter = require('./products');
const authRouter = require('./auth');
const authMiddleware = require('./authMiddleware');
app.use('/api/auth', authRouter);
app.use('/api/products', authMiddleware, productsRouter);
app.listen(port, () => {
console.log(`Servidor escuchando en http://localhost:${port}`);
});
- Documentar y Probar la API
4.1 Documentación con Swagger
Instalación de Swagger
Configuración de Swagger
// swagger.js
const swaggerUi = require('swagger-ui-express');
const swaggerJsdoc = require('swagger-jsdoc');
const options = {
definition: {
openapi: '3.0.0',
info: {
title: 'API de Tienda en Línea',
version: '1.0.0',
},
},
apis: ['./products.js'], // Archivos que contienen anotaciones Swagger
};
const specs = swaggerJsdoc(options);
module.exports = (app) => {
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(specs));
};Integración de Swagger en el Servidor
// server.js
const express = require('express');
const app = express();
const port = 3000;
app.use(express.json());
const productsRouter = require('./products');
const authRouter = require('./auth');
const authMiddleware = require('./authMiddleware');
const swaggerSetup = require('./swagger');
app.use('/api/auth', authRouter);
app.use('/api/products', authMiddleware, productsRouter);
swaggerSetup(app);
app.listen(port, () => {
console.log(`Servidor escuchando en http://localhost:${port}`);
});4.2 Pruebas con Postman
- Crear una colección en Postman: Agrupa todas las peticiones relacionadas con la API de la tienda en línea.
- Añadir peticiones: Añade peticiones para cada endpoint de la API.
- Configurar autenticación: Añade el token JWT en el encabezado de las peticiones que requieren autenticación.
Conclusión
En este caso de estudio, hemos diseñado y desarrollado una API RESTful para una tienda en línea, cubriendo desde la definición de recursos y URIs hasta la implementación de autenticación y documentación. Este ejercicio práctico te ha permitido aplicar los principios y técnicas aprendidos en los módulos anteriores, proporcionando una comprensión integral del desarrollo de APIs RESTful.
Próximos Pasos
- Optimización y escalabilidad: Considera cómo optimizar y escalar la API para manejar un mayor volumen de tráfico.
- Monitoreo y mantenimiento: Implementa herramientas de monitoreo y establece un plan de mantenimiento para asegurar la disponibilidad y rendimiento de la API.
¡Felicidades por completar este caso de estudio! Ahora estás listo para abordar el siguiente caso de estudio o comenzar tu propio proyecto de API RESTful.
Curso de REST API: Principios de Diseño y Desarrollo de APIs RESTful
Módulo 1: Introducción a las APIs RESTful
Módulo 2: Diseño de APIs RESTful
- Principios de diseño de APIs RESTful
- Recursos y URIs
- Métodos HTTP
- Códigos de estado HTTP
- Versionado de APIs
- Documentación de APIs
Módulo 3: Desarrollo de APIs RESTful
- Configuración del entorno de desarrollo
- Creación de un servidor básico
- Manejo de peticiones y respuestas
- Autenticación y autorización
- Manejo de errores
- Pruebas y validación
Módulo 4: Buenas Prácticas y Seguridad
- Buenas prácticas en el diseño de APIs
- Seguridad en APIs RESTful
- Rate limiting y throttling
- CORS y políticas de seguridad
Módulo 5: Herramientas y Frameworks
- Postman para pruebas de APIs
- Swagger para documentación
- Frameworks populares para APIs RESTful
- Integración continua y despliegue
