Feedback Integracion de aplicaciones v006
Equipo 001
Buenas Prácticas de Desarrollo
- Estructura del proyecto: Organiza el código en módulos claros y separados por funcionalidad.
- Comentarios y documentación: Incluye comentarios en el código y documentación detallada para facilitar la comprensión y el mantenimiento.
Variables de Entorno
- Gestión segura: Utiliza archivos
.env
para almacenar variables de entorno sensibles, como claves de API y credenciales, y agrégalo al.gitignore
. - Configuración por entorno: Crea diferentes archivos de configuración para desarrollo, pruebas y producción.
Seguridad
- Autenticación y autorización: Implementa sistemas robustos de autenticación y autorización para proteger los recursos. Falta un nivel extra para definir el uso de roles.
- Validación de entradas: Valida todas las entradas del usuario para prevenir ataques como la inyección SQL y XSS.
- Manejo de errores: No reveles detalles del sistema en los mensajes de error. Usa un manejo centralizado de excepciones.
Diseño de Servicios Web
- APIs RESTful: Asegúrate de que las APIs sigan los principios REST para que sean consistentes y fáciles de usar.
- Documentación de APIs: Utiliza herramientas como Swagger para documentar las APIs.
Patrones de Diseño
- MVC (Model-View-Controller): Aplica este patrón para separar la lógica de negocio, la presentación y la gestión de datos. Minimal Flask Application using MVC Design Pattern
- Singleton: Utiliza el patrón Singleton para gestionar recursos compartidos, como la conexión a la base de datos. Revisar ejemplo mas abajo.
Gestión con la Base de Datos
- ORM (Object-Relational Mapping): Ver detalle mas abajo del porque no implementaron bien el ORM
- Migrations: Implementa un sistema de migraciones para gestionar los cambios en el esquema de la base de datos de manera controlada y reproducible.
Problemas Identificados
-
Conexión Directa en el Código: No encontré un archivo explícito que configure la conexión a la base de datos usando SQLAlchemy, lo cual es crucial para una buena práctica. La configuración de la conexión debería estar en un archivo de configuración separado y usar variables de entorno para proteger la información sensible como las credenciales de la base de datos.
-
Falta de Manejo de Sesiones: Es crucial manejar las sesiones correctamente cuando se trabaja con SQLAlchemy. No se debe abrir una sesión globalmente y dejarla abierta indefinidamente. Cada transacción debe manejarse en su propia sesión, y debe asegurarse de cerrarlas o revertirlas adecuadamente para evitar bloqueos de base de datos y asegurar la integridad de los datos.
-
Manejo Incorrecto de Objetos del Modelo: Es importante definir y usar los modelos de SQLAlchemy correctamente. Todos los modelos deberían heredar de
Base
, que se crea usandodeclarative_base()
. Además, cada transacción debe asegurarse de usar estos modelos en lugar de realizar operaciones directas en las tablas.
Equipo 002
Estructura del Proyecto
- Excluir el entorno virtual: (myenv) del control de versiones. Añadirlo al archivo
.gitignore
. - Asegurarse de que todos los módulos de la aplicación estén bien organizados dentro de la carpeta
flaskapp
. Referencia ejemplo: Minimal Flask Application using MVC Design Pattern requirements.txt
: Super bien que lo incluyeran.
Uso de Flask
Asumiendo que la aplicación está basada en Flask, aquí hay algunas buenas prácticas:
Buenas prácticas:
- Blueprints: Utilizar Blueprints para modularizar la aplicación.
- Configuraciones: Separar configuraciones para desarrollo, pruebas y producción.
- Validación de datos: Utilizar bibliotecas como Flask-WTF o Marshmallow para validar y serializar datos.
- Gestión de errores: Implementar un manejo centralizado de errores y respuestas JSON consistentes. Ejemplos: Manejar posibles errores como duplicados de email o datos faltantes.
Diseño de Servicios Web
El diseño sigue principios RESTful con métodos HTTP adecuados. Se recomienda implementar paginación, filtros, y versionado de API, así como mejorar la validación de datos y el manejo centralizado de errores.
- Es crucial manejar los errores de manera adecuada y devolver códigos de estado HTTP significativos (404, 500, etc.). El proyecto debería asegurarse de tener un manejo de errores robusto.
- El diseño del servicio parece seguir principios RESTful, utilizando métodos HTTP apropiados (GET, POST, PUT, DELETE) para interactuar con los recursos. Esto es esencial para la interoperabilidad y la escalabilidad del servicio.
- Implementar el versionado de API (por ejemplo, /api/v1/) es una buena práctica para manejar actualizaciones y cambios en la API sin afectar a los clientes existentes.
- Utilizar bibliotecas como Marshmallow o Flask-WTF para validar datos de entrada y evitar errores.
Base de Datos
Utiliza SQLAlchemy como ORM, lo cual es adecuado. Debería enfocarse en la normalización, creación de índices, y manejo de transacciones. La seguridad de datos es crucial, con validación y sanitización de entradas.
- Utiliza migraciones para gestionar cambios en la estructura de la base de datos. Herramientas como Flask-Migrate pueden ser útiles para este propósito.
- Utiliza SQLAlchemy como ORM, lo cual es una buena práctica para abstraer la lógica de la base de datos y facilitar el trabajo con objetos Python.
- Crear índices en columnas que se utilicen frecuentemente en consultas para mejorar el rendimiento.
- Utilizar transacciones para operaciones que modifiquen múltiples registros, asegurando así que las operaciones sean atómicas.
- Asegurarse de que todos los datos recibidos sean validados y sanitizados para prevenir inyecciones SQL.
- Implementar controles de acceso adecuados para proteger los datos sensibles y asegurar que solo usuarios autorizados puedan realizar modificaciones.
Seguridad y Dependencias
Buenas prácticas de seguridad:
- Variables de entorno: No almacenar configuraciones sensibles (como claves secretas) directamente en el código, sino en variables de entorno.
- CORS: Configurar adecuadamente CORS si la API será consumida desde diferentes dominios.
- Autenticación y Autorización: Utilizar métodos seguros para la autenticación y autorización (JWT, OAuth).
Revisión de código
- Variables y Funciones: Usar nombres descriptivos y seguir la convención de nombres de PEP 8.
- Documentación: Asegurarse de que todas las funciones y módulos tengan docstrings explicativos.
- Manejo de Excepciones: Usar bloques
try-except
adecuadamente para manejar excepciones.
Archivos adicionales
- README.md: Proveer una documentación clara sobre cómo configurar y ejecutar el proyecto.
- .gitignore: Asegurarse de que los archivos y directorios que no deben ser versionados estén incluidos aquí.
Equipo 003
1. Diseño de Servicios Web
Antipatrón: Servicio Monolítico
- Descripción: Todos los servicios están agrupados en un solo módulo, lo que dificulta la escalabilidad y mantenimiento.
- Ejemplo: En lugar de tener servicios separados para
Carrito
,Ferretera
, yLogin
, están integrados en un solo módulo. - Solución: Adoptar una arquitectura de microservicios donde cada funcionalidad esté separada en diferentes servicios independientes.
# Monolithic approach
class FerreteriaService:
def __init__(self):
self.carrito = CarritoService()
self.login = LoginService()
# Microservices approach
class CarritoService:
pass
class LoginService:
pass
2. Buenas Prácticas de Código
Antipatrón: Código Repetido
- Descripción: Múltiples secciones del código realizan la misma lógica, aumentando el riesgo de errores y dificultando el mantenimiento.
- Ejemplo: Funciones de validación de usuarios duplicadas en
Login
yFerretera
. - Solución: Crear funciones reutilizables y centralizar la lógica común.
3. Manejo de Errores
Antipatrón: Errores Silenciosos
- Descripción: Errores son capturados y suprimidos sin informar al usuario o registrar los detalles para análisis futuro.
- Ejemplo: Uso de
try
/except
sin un manejo adecuado del error. - Solución: Implementar un sistema de logging y manejo de excepciones informativo.
4. Seguridad
Antipatrón: Credenciales en el Código
- Descripción: Las credenciales de base de datos o API keys están hardcodeadas en el código fuente.
- Ejemplo: Usuario y contraseña de la base de datos están visibles en el archivo
api_ferreteria.sql
. - Solución: Utilizar variables de entorno para manejar credenciales sensibles.
5. Base de datos
- ORM: SQL en duro. Deben utilizar las soluciones disponibles para manejar correctamente la conexion e interaccion con la DB.
6. Patrones de Diseño
- MVC (Model-View-Controller): Aplica este patrón para separar la lógica de negocio, la presentación y la gestión de datos. Minimal Flask Application using MVC Design Pattern
- Singleton: Utiliza el patrón Singleton para gestionar recursos compartidos, como la conexión a la base de datos. Revisar ejemplo mas abajo.
Equipo 004
1. Diseño de Servicios Web
Antipatrones:
- Acoplamiento excesivo: El código muestra un fuerte acoplamiento entre las capas, lo que dificulta la separación de responsabilidades y la escalabilidad. Un mejor diseño implicaría una arquitectura más modular y desacoplada.
- Falta de RESTful: Los endpoints podrían no seguir las convenciones REST, lo que complica la comprensión y el uso de la API. Es importante usar verbos HTTP correctamente y estructurar las URLs de manera intuitiva.
2. Buenas Prácticas de Código
Antipatrones:
- Código repetido: Se puede observar código duplicado en varias partes del proyecto. La refactorización para crear funciones reutilizables mejoraría la mantenibilidad.
- Nombres de variables y funciones no descriptivos: Usar nombres que no describen claramente su propósito dificulta la lectura y el mantenimiento del código.
3. Patrones de Diseño
Antipatrones:
- God Object: Algunas clases parecen tener demasiadas responsabilidades, centralizando mucha lógica. Esto va en contra del principio de responsabilidad única. Dividir estas clases en componentes más pequeños y específicos ayudaría a mejorar la estructura.
- Singleton abusivo: El uso excesivo del patrón Singleton puede llevar a un estado global no controlado y dificultar las pruebas unitarias. Solucion es Inyeccion de dependencia.
Lista de archivos con instancias new Conexiones() ./WSIntegracionPlataformas.DAL/Implementacion/ProductosImpl.cs: using (var db = new Conexiones()) ./WSIntegracionPlataformas.DAL/Implementacion/ProductosImpl.cs: using (var db = new Conexiones()) ./WSIntegracionPlataformas.DAL/Implementacion/ProductosImpl.cs: using (var db = new Conexiones()) ./WSIntegracionPlataformas.DAL/Implementacion/ProductosImpl.cs: using (var db = new Conexiones()) ./WSIntegracionPlataformas.DAL/Implementacion/ProductosImpl.cs: using (var db = new Conexiones()) ./WSIntegracionPlataformas.DAL/Implementacion/ProductosImpl.cs: using (var db = new Conexiones()) ./WSIntegracionPlataformas.DAL/Implementacion/ProductosImpl.cs: using (var db = new Conexiones()) ./WSIntegracionPlataformas.DAL/Implementacion/ProductosImpl.cs: using (var db = new Conexiones()) ./WSIntegracionPlataformas.DAL/Implementacion/ProductosImpl.cs: using (var db = new Conexiones()) ./WSIntegracionPlataformas.DAL/Implementacion/ProductosImpl.cs: using (var db = new Conexiones()) ./WSIntegracionPlataformas.DAL/Implementacion/ProductosImpl.cs: using (var db = new Conexiones()) ./WSIntegracionPlataformas.DAL/Implementacion/ProductosImpl.cs: using (var db = new Conexiones()) ./WSIntegracionPlataformas.DAL/Implementacion/UserImpl.cs: using (var db = new Conexiones())
4. Seguridad
Antipatrones:
- Configuraciones sensibles en el código: Información sensible como credenciales de base de datos o claves API deben manejarse a través de variables de entorno y no estar hardcodeadas en el repositorio.
- Falta de validación de entrada: No validar adecuadamente la entrada del usuario puede llevar a vulnerabilidades como SQL Injection o XSS. Es crucial implementar validaciones y sanitización de inputs.
5. Manejo de Errores
Antipatrones:
- Captura genérica de excepciones: Usar bloques catch genéricos (
catch (Exception ex)
) sin diferenciar el tipo de excepción puede esconder errores críticos y dificultar el debugging. Es mejor capturar excepciones específicas y manejar cada caso adecuadamente. - Mensajes de error poco informativos: Proveer mensajes de error claros y específicos es vital para el diagnóstico y la resolución de problemas.
6. Base de Datos
Antipatrones:
- Consultas SQL en el código: Incluir consultas SQL directamente en el código de la lógica de negocio es una mala práctica. Es preferible usar ORM (Object-Relational Mapping) para abstraer las interacciones con la base de datos. En su caso es la referencia directa a los procedimientos de almacenado.
- Falta de transacciones: No manejar transacciones en operaciones críticas puede llevar a inconsistencias en la base de datos. Es importante asegurarse de que todas las operaciones relacionadas se completen exitosamente o ninguna se aplique.
Equipo 005
1. Diseño de Servicios Web
Antipatrones Identificados:
- API sin versionar: No se observa una estructura de versionamiento en las rutas de las APIs.
- Endpoints monolíticos: Algunos endpoints manejan múltiples responsabilidades.
- Falta de documentación: No hay documentación clara sobre los endpoints y sus usos.
2. Buenas Prácticas de Código
Antipatrones Identificados:
- Nombres de variables no descriptivos: Variables con nombres poco descriptivos.
- Código comentado en exceso: Comentarios excesivos y redundantes.
- Funciones largas y complejas: Algunas funciones superan las 50 líneas de código.
3. Patrones de Diseño
Antipatrones Identificados:
- Uso inapropiado del Singleton: Uso incorrecto del patrón Singleton.
- Falta de patrones MVC: No se observa una clara separación entre lógica de negocios, presentación y acceso a datos.
- Acoplamiento excesivo: Clases y módulos demasiado acoplados.
4. Seguridad
Antipatrones Identificados:
- Manejo inseguro de contraseñas: No se implementa hashing para las contraseñas.
- Validación insuficiente de entradas: Falta de sanitización y validación adecuada de entradas del usuario.
- Exposición de información sensible: Información sensible expuesta en el código fuente.
5. Manejo de Errores
Antipatrones Identificados:
- Errores silenciados: Bloques
try-except
que silencian los errores sin loguearlos. - Mensajes de error genéricos: Mensajes de error que no proporcionan suficiente información.
- Falta de manejo de excepciones específicas: Uso de
except Exception
sin capturar excepciones específicas.
6. Base de Datos
Antipatrones Identificados:
- Consultas SQL en el código: Consultas SQL incrustadas directamente en el código. Implementacion de ORM
- Falta de índices: No se mencionan índices en las tablas de base de datos.
- Conexiones no gestionadas: Conexiones a la base de datos no gestionadas adecuadamente.
Equipo 006
1. Diseño de Servicios Web
- Acoplamiento Fuerte: Componentes altamente acoplados dificultan mantenimiento y escalabilidad.
2. Buenas Prácticas de Código
- Código Repetido: Lógica duplicada puede llevar a inconsistencias.
- Falta de Documentación: Ausencia de comentarios y documentación clara.
3. Seguridad
- Inyección de SQL: Consultas SQL no parametrizadas son vulnerables.
- Exposición de Credenciales: Información sensible en
settings.py
sin protección adecuada.
4. Manejo de Errores
- Captura General de Excepciones: Cláusulas
try-except
generales ocultan errores. - Falta de Logueo: Sin logueo adecuado, difícil rastrear errores.
Equipo 007
1. Diseño de Servicios Web
Antipatrones:
- Endpoint Bloat: Exceso de endpoints para operaciones específicas, complicando la mantenibilidad y escalabilidad.
- Falta de versionado: Ausencia de versionado en los endpoints, dificultando actualizaciones y compatibilidad.
- Uso incorrecto de verbos HTTP: Métodos HTTP inapropiados (GET, POST, PUT, DELETE) para las acciones realizadas.
2. Buenas Prácticas de Código
Antipatrones:
- Código duplicado: Repetición de lógica en diferentes partes en lugar de funciones reutilizables.
- Falta de comentarios: Ausencia de comentarios explicativos en el código.
- Funciones largas: Funciones que realizan demasiadas acciones, dificultando su entendimiento y mantenimiento.
3. Patrones de Diseño
Antipatrones:
- No usar patrones de diseño: Falta de uso de patrones como Singleton, Factory o Decorator.
- God Object: Clases con demasiadas responsabilidades, violando el principio de responsabilidad única. Ej Fn:
ObtainTokenView
- Spaghetti Code: Lógica entrelazada y difícil de seguir, sin separación clara de responsabilidades.
4. Seguridad
Antipatrones:
- Falta de validación de entrada: Datos de entrada no validados adecuadamente, susceptible a inyecciones SQL o XSS.
- Manejo de contraseñas inseguro: Contraseñas en texto plano en lugar de usar técnicas de hash seguro.
- No uso de HTTPS: Tráfico no cifrado, vulnerable a ataques de interceptación.
5. Manejo de Errores
Antipatrones:
- Errores silenciosos: Capturar excepciones sin realizar ninguna acción o registro.
- Falta de manejo de errores específicos: Excepciones genéricas que no brindan información útil.
- Mensajes de error ambiguos: Mensajes de error poco informativos.
6. Base de Datos
Antipatrones:
- Consultas N+1: Múltiples consultas en lugar de optimización con joins. Ejemplo funcion
PedidoDetailView
con:
# Linea original
detalles_pedido = DetallePedido.objects.filter(pedido=instance)
# propuesta
detalles_pedido = DetallePedido.objects.filter(pedido=instance).select_related('producto')
- Falta de índices: No uso de índices en columnas frecuentemente consultadas.
- Dependencia fuerte de la base de datos: Lógica de negocio en procedimientos almacenados en lugar de en la aplicación.
Equipo 008
SIN PROYECTO
Ejemplos FLASK
Como se deberia ver SQLAclvhemy como ORM
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Usuario(db.Model):
id = db.Column(db.Integer, primary_key=True)
nombre = db.Column(db.String(80), nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
# Suponiendo que ya tienes una instancia de Flask y SQLAlchemy configurada
from your_application import db, Usuario
# Realizando una consulta para obtener todos los usuarios
usuarios = Usuario.query.all()
# Imprimiendo los usuarios obtenidos
for usuario in usuarios:
print(f"ID: {usuario.id}, Nombre: {usuario.nombre}, Email: {usuario.email}")
Ejemplos Buenas practicas de codigo
Antipatrón: Credenciales en el Código
- Descripción: Las credenciales de base de datos o API keys están hardcodeadas en el código fuente.
- Ejemplo: Variables en duro en codigo
*.py
. - Solución: Utilizar variables de entorno para manejar credenciales sensibles.
# Inseguro
DB_USER = "user"
DB_PASSWORD = "password"
# Seguro
import os
DB_USER = os.getenv("DB_USER")
DB_PASSWORD = os.getenv("DB_PASSWORD")
Antipatrón: Errores Silenciosos
- Descripción: Errores son capturados y suprimidos sin informar al usuario o registrar los detalles para análisis futuro.
- Ejemplo: Uso de
try
/except
sin un manejo adecuado del error. - Solución: Implementar un sistema de logging y manejo de excepciones informativo.
# Manejo de errores incorrecto
try:
# código
except Exception:
pass
# Correcto
import logging
try:
# código
except Exception as e:
logging.error(f"Error occurred: {e}")
raise
Antipatrón: DB multi-instanciacion
- Descripción: Uso incorrecto de la instancia de conexion
- Ejemplo: Instanciacion en cada metodo que requiere conexion a la db
- Solución: Implementar un patron singleton para la conexion. Este debe ir acompañado de un patron de diseño: Inyeccion de dependencia.
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
import os
DATABASE_URL = os.getenv('DATABASE_URL')
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
# Uso de la sesión en una función
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()