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