Cuestiones comunes a todos los proyectos
- Todo el código debe ser revisado y validado para que no existan warnings del compilador ni problemas reportados por herramientas de análisis estático como SonarLint (dentro de Eclipse) o SonarQube (al ejecutarse el análisis tras subir los cambios al repositorio). Estas herramientas ayudan a detectar problemas de seguridad, errores potenciales, complejidad innecesaria y malas prácticas en el desarrollo.
- En SonarQube se deberá revisar la pestaña de Overall Code y no tendrá que haber ningún Bug, Vulnerability o Security Hotspot. Además, en los proyectos FundewebJS tendrá que haber un Coverage de tests de un 80% aproximadamente, salvo que no sea posible alcanzarlo por motivos justificados.
- Correcto nombrado en Java: mejora la legibilidad, mantenibilidad y comprensión del código.
Paquetes: deben escribirse en minúsculas y reflejar la estructura lógica del proyecto (es.um.atica.proyecto.XXX).
Clases, Enumerados e Interfaces: deben usar notación CamelCase comenzando por mayúscula (ClienteService, TipoDocumento). Las clases que implementen una interfaz deberán tener un sufijo que las identifique (XxxxImpl.java).
Constantes: deben ser estáticas, finales, y en mayúsculas con guiones bajos (MAX_RETRIES, DEFAULT_TIMEOUT).
Variables y métodos: deben seguir la notación CamelCase comenzando con minúscula (obtenerCliente(), totalItems).
- Para los beans con interfaz e implementación, se declarará la constante NAME en la interfaz, para que al hacer la inyección de dependencias de ese bean no se tenga que importar la interfaz y la implementación (si se declarase en la implementación), consiguiendo así abstraerse de las implementaciones en el resto de la aplicación.
- No se deben crear métodos vacíos o clases vacías salvo que sean autocompletadas por Spring u otra librería. Esto aumenta la complejidad del código y del proyecto. En caso de que sea imprescindible se debería añadir un comentario que lo justifique.
Comentarios
- NO debe existir ningún TODO o FIXME en el código que se suba al entorno de producción ya que esto denota un código incompleto o con fallos. En su lugar, se anotará en Jira o Confluence las cuestiones pendientes de abordar.
- El código comentado que no se utiliza genera ruido y puede inducir errores en el futuro. Se debe eliminar, ya que cualquier código antiguo podrá ser recuperado desde la herramienta de control de versiones (Git). Los comentarios deben emplearse solo para documentar lógica compleja, realizar justificaciones o aclaraciones.
- No se deben poner comentarios con contraseñas, datos sensibles o personales.
Entidades
- Deberán contar con sus correspondientes anotaciones con las restricciones necesarias para mapearlas a las tablas de base de datos.
- Las entidades no deben tener ninguna lógica de negocio asociada a ellas.
- En los métodos equals de entidades se deberá referenciar a los atributos del parámetro other a través de sus métodos getter, ya que si se accede de manera directa se pueden producir problemas con JPA e Hibernate y que se reciba una respuesta errónea.
DTOs
- Los DTOs no deben tener lógica de negocio, a excepción de que pueden tener funciones de mapeo para convertir de entidad a DTO y viceversa.
Uso de entidades y DTOs en las aplicaciones
- Las entidades se utilizarán en los DAS y serán recibidas por los servicios.
- Los DTOs se utilizarán en los servicios (convirtiendo las entidades a DTOs) y en los controladores (sean controladores para vistas del Front en Fundeweb o controladores REST en FundewebJS).
Enumerados
- No se debe tener una clase maestra o comodín para almacenar todos los enumerados del proyecto. Los enumerados se crearán en ficheros individuales o contenidos en otros ficheros cuya lógica esté relacionada y se usen especialmente en ellos.
- Tienen que tener un correcto nombrado en mayúsculas y con guiones bajos, como las constantes.
Uso de excepciones
- No se debe capturar la excepción genérica "Exception" en un try-catch. En su lugar hay dos opciones:
- Capturar las excepciones específicas que sean lanzadas por el código contenido en el try.
- Si no se lanza ninguna excepción y el código compila sin el try-catch, se puede eliminar el try-catch y dejar el código sin él. No se debe producir ninguna excepción más allá de una RuntimeException, que no debe ser controlada ya que se trata de una mala práctica.
- No se debe capturar "Throwable" en un bloque try-catch.
- No se debe lanzar la excepción genérica "Exception" ni que las funciones indiquen que se lanza. En todo caso se lanzará una excepción específica que puede ser una excepción personalizada que extienda de Exception.
- Las excepciones personalizadas no deben extender de "RuntimeException", deberán extender de "Exception" o de alguna clase hija de la misma.
Proyectos Fundeweb
- Para proyectos Fundeweb, se deberá seguir la siguiente guía para mantener una correcta organización del proyecto: Estructura de proyectos FundeWeb 2.x.
Entidades
- Se pueden generar a partir de las tablas de base de datos mediante la siguiente guía: Generar Entidades a partir de la BBDD.
Controladores o Manejadores
- No se deben hacer referencias a elementos del frontend (XHTML) por id, widgetVar o class para ejecutar acciones sobre ellos. En su lugar, se deben gestionar todos los componentes del frontend desde el mismo, con el objetivo de evitar acoplamientos.
Java Beans
- Los beans deben inyectarse con la anotación @In, y solamente se recuperarán con Component.getInstance cuando sea para un uso puntual o se quiera utilizar un bean de la misma capa aunque no sea lo más recomendado (por ejemplo: recuperar un controlador en otro controlador, o un servicio en otro servicio).
Uso de excepciones
- Si se desea redirigir al usuario a otra pantalla cuando se produce una excepción, en lugar de hacerlo con la anotación @Redirect, se configurará el comportamiento en el fichero pages.xml de la aplicación Fundeweb tal y como otros ejemplos que ya hay en ese fichero.
Proyectos FundewebJS
- Se puede configurar la autorización por scope a todos los endpoints de un proyecto o un conjunto en concreto desde la clase SecurityConfig tal y como se explica en la guía: Autorización por Scopes.
Entidades
- Validar longitud de los atributos que sean de tipo String.
- Acotar tamaño mínimo y máximo de valores de tipo numéricos.
DTO's
- Añadir anotaciones para validar el tamaño y formato de los atributos de los DTOs. Especialmente los DTOs que se reciben como parámetro en los controladores REST. Para ello se deberán utilizar anotaciones como @Size, @NotNull o @Min entre otros.
- Si un atributo sigue un patrón en concreto, se puede validar con una expresión regular con @Pattern.
Controladores REST
- Un queryParam en la URL de un endpoint está más pensado para filtrado o búsqueda de datos.
- Un pathParam está más pensado para indicar identificadores de recursos en operaciones de lectura, modificación o eliminación.
- Los endpoints privados deberán validar el token JWT recibido y garantizar que el cliente que envía el token tiene los permisos necesarios para poder llamar a ese endpoint.
- Se deben validar todas las entradas que se reciban en un endpoint, sean DTOs o parámetros de tipo primitivo. Para ello se usarán anotaciones como @Valid, @Length o @Pattern entre otros.
- Nunca se podrá devolver un código 200 con cuerpo null en un endpoint. En todo caso se devolverá un 404 Not Found o incluso una lista vacía si se tratase de una operación de búsqueda y no se ha encontrado ningún elemento.
TIPOS DE OPERACIONES HTTP
Se debe seleccionar el tipo de operación adecuado para la acción que se quiera ejecutar en cada endpoint de la API:
- GET: se utiliza para la obtención de datos de un recurso y no implica modificación o inserción de datos alguna, por lo que es idempotente.
- POST: sirve para la creación de un nuevo recurso o inserción de nuevos datos.
- PUT: se utiliza en peticiones en las que se busca reemplazar de manera completa los datos de un recurso existente.
- PATCH: se emplea en casos en los que se quiera actualizar el contenido de un recurso de manera parcial.
- DELETE: se usa cuando se va a eliminar un recurso.
TIPOS DE CÓDIGOS DE RESPUESTA
Cuando se crea un endpoint, además de seleccionar el tipo de operación adecuada, se deberá seleccionar el código de respuesta más conveniente para la respuesta que devuelva el endpoint.
CÓDIGOS 200
Son códigos de respuesta correcta o exitosa.
CÓDIGO | NOMBRE | DESCRIPCIÓN |
---|---|---|
200 | OK | Petición procesada correctamente. Se suele emplear en las operaciones GET, PUT y PATCH. |
201 | Created | Recurso creado exitosamente. Se emplea con operaciones POST. |
202 | Accepted | Petición aceptada pero aún no procesada. Se suele emplear en procedimientos asíncronos. |
204 | No Content | Petición exitosa, pero no lleva contenido en el cuerpo de la respuesta. Se suele utilizar en DELETE, o PUT. |
206 | Partial Content | Respuesta parcial, se suele utilizar cuando sólo se solicita una parte del recurso. No se suele utilizar tan a menudo en una API REST. |
CÓDIGOS 400
Son códigos de error del lado del cliente, es decir, errores en la solicitud realizada.
CÓDIGO | NOMBRE | DESCRIPCIÓN |
---|---|---|
400 | Bad Request | La petición está mal formada o contiene datos inválidos. |
401 | Unauthorized | Falta autenticación o es incorrecta. |
403 | Forbidden | Autenticado pero sin permisos. |
404 | Not Found | Recurso no encontrado. |
406 | Not Acceptable | El recurso no puede representarse en el formato solicitado (por ejemplo: "Accept: application/xml"). |
415 | Unsupported Media Type | El tipo de contenido no es compatible con el recurso (Content-Type). |
CÓDIGOS 500
Son códigos de error del lado del servidor, que impiden que la solicitud del cliente sea procesada correctamente.
CÓDIGO | NOMBRE | DESCRIPCIÓN |
---|---|---|
500 | Internal Server Error | Error genérico del servidor. |
501 | Not Implemented | El servidor no reconoce o no soporta la funcionalidad requerida. |
502 | Bad Gateway | El servidor actúa como proxy/pasarela y recibió una respuesta inválida de un servidor intermedio. |
503 | Service Unavailable | El servicio no está disponible. |
504 | Gateway Timeout | El servidor actuó como proxy y no recibió respuesta a tiempo del otro servidor. |
505 | HTTP Version Not Supported | El servidor no soporta la versión del protocolo HTTP usada en la solicitud. |
SWAGGER/OPEN API
- Es obligatorio documentar los endpoints con Swagger/OpenAPI, y que la documentación refleje fielmente la información del código implementado.
- No es necesario documentar las respuestas 500 ya que son errores del servidor que no pueden ser manejadas ni son predecibles.
- Se puede asignar un tag a nivel de controlador para agrupar y clasificar cada endpoint en la documentación. Esto se hará con la anotación @Tag( name="xxx" ) sobre la clase del controlador.
- Si se trata de un endpoint autenticado con Token JWT, el endpoint podrá devolver las respuestas HTTP 401 y 403.
Uso de excepciones
- Se deben gestionar las excepciones de una API REST con un manejador global de excepciones que intercepte las excepciones lanzadas y las procese para dar una respuesta adecuada al cliente.