# Guía de Estilo para la API ## Introducción Esta guía de estilo establece las normas para el desarrollo y mantenimiento de la API. Está diseñada para asegurar la coherencia, optimización y eficiencia en las interfaces de programación de aplicaciones (APIs) del grupo. ## Nomenclatura y Convenciones de Nombrado Se presentan algunas directrices generales y mejores prácticas para el nombrado en la API: ### Generalidades - Todos los nombres deben estar en inglés. - Evitar el uso de abreviaturas, a menos que sean ampliamente reconocidas. ### Endpoints - Usar sustantivos en lugar de verbos. Por ejemplo, `/user` para un recurso que maneja usuarios. - Usar sustantivos en singular para representar recursos - `/user` (en lugar de `/users`) - `/product` (en lugar de `/products`) - Para operaciones específicas sobre un recurso, se recomienda el uso de verbos. Por ejemplo, `/user/{id}/activate` para una operación que cambie el estado de un usuario a activo. ### Parámetros y Cuerpos de Solicitudes - Los nombres de los parámetros deben ser descriptivos y seguir el estilo camelCase, por ejemplo, `startDate` o `numberOfItems`. - Evitar nombres genéricos y optar por descripciones específicas, como `productId` en lugar de simplemente `id`. - En el cuerpo de una solicitud, especialmente en métodos POST o PUT, incluir sólo la información necesaria para la operación. Debe nombrarse de manera que describan claramente su propósito, sin abreviaturas ambiguas. ## Métodos HTTP La API sigue los principios REST, utilizando los métodos HTTP estándar para realizar operaciones en los recursos. A continuación, se especifica cuándo utilizar cada método: ### GET - Utilizado para recuperar datos. - No debe alterar ningún estado en el servidor. - Debe ser seguro y consistente en sus resultados. - Los parámetros deben enviarse en la URL (query strings). ### POST - Utilizado para enviar datos al servidor y crear un nuevo recurso. - Los datos deben incluirse en el cuerpo de la solicitud (request body). ### PUT - Utilizado para actualizar un recurso en su totalidad. - El cliente debe enviar toda la entidad, no solo los cambios. - Si se envía la misma solicitud varias veces, el resultado debe ser el mismo. ### DELETE - Utilizado para eliminar recursos. ### GET para Búsqueda Avanzada o Listados Aparte de las operaciones GET estándar, utilizamos solicitudes GET más complejas para funcionalidades como búsquedas, listados con paginación, y filtrado. Estas solicitudes pueden incluir algunos parámetros obligatorios en la cadena de consulta (query strings). #### Parámetros de Query - `limit` (integer): Define el número máximo de elementos a retornar en una sola respuesta. - Ejemplo: `100`. - Para devolver todos los resultados, usar `-1`. - `start` (integer): Indica el índice inicial de los elementos, usado para la paginación. - Ejemplo: `0`. - `sort` (string): Establece el criterio de ordenación de los elementos. Se utiliza el formato `campo:dirección`, donde la dirección puede ser `asc` (ascendente) o `desc` (descendente). Si no se especifica dirección, se asume ascendente. - Ejemplos: - `sort: expectedDateEnd` (devuelve ascendente) - `sort: expectedDateEnd:desc` (devuelve descendente) - `searchText` (string, opcional): Permite filtrar los resultados por búsqueda de texto. - También se pueden aplicar filtros adicionales con una estructura específica, siempre utilizando camelCase para los nombres y empezando por "filter". Por ejemplo: - `filterByNonActivePreventionService` (boolean) - `filterByRealizationDepartments` (string) - Para incluir información adicional en los resultados, utilizamos parámetros que comienzan con `include` utilizando camelCase, seguidos del nombre del campo relevante, utilizando un valor booleano para indicar si queremos la inclusión. - Ejemplo: `includeResponsibleDepartments` (boolean) ## Estructura de Respuestas Independientemente del método HTTP utilizado, las respuestas deben ser consistentes. Los clientes deben saber qué esperar de cualquier respuesta proporcionada por la API. ### Respuestas GET - Deben devolver `200 OK` si la solicitud fue exitosa. - Las respuestas deben incluir siempre los campos `code` y `data`. El campo `code` es un identificador numérico del resultado de la operación. Un `code` igual a 0 indica que la operación fue exitosa. Mientras tanto, `data` contiene los datos solicitados, que pueden variar en estructura y contenido dependiendo del recurso accedido. #### Ejemplo de respuesta: ``` { "code": 0, // Un 'code' de 0 indica una operación exitosa. "data": [ { "typeId": 1, "order": 1, "name": "Plan de acción", "type": "PAC" } ] } ``` #### Ejemplo de respuesta para Búsqueda Avanzada o Listados Las respuestas de estas solicitudes GET seguirán una estructura similar con un data enriquecido. Aquí un ejemplo y detalles de la estructura de respuesta: ``` { "code": 0, "data": { "total": 45, // Número total de elementos que coinciden con los criterios de búsqueda. "limit": 20, // Número de elementos solicitados en la consulta (límite). "start": 5, // Índice inicial del primer elemento de esta página. "items": [] // Array de elementos, que pueden ser de cualquier estructura, dependiendo de la solicitud. } } ``` ### Respuestas POST - Deben devolver `200 OK` si el recurso se ha creado satisfactoriamente. - La respuesta debe seguir una estructura coherente, que incluya un 'code' y un objeto 'data'. - Un 'code' de `0` indica una operación exitosa. #### Estructura de Respuesta Estándar La estructura básica de una respuesta exitosa a una solicitud POST debe ser la siguiente: ``` { "code": 0, "data": { } } ``` Esta estructura indica que la solicitud fue exitosa. #### Inclusión del ID del Recurso Creado En ciertas ocasiones, es particularmente útil para el cliente recibir el ID del recurso que se acaba de crear: ``` { "code": 0, "data": { "id": 23 } } ``` ### Respuestas PUT - Si el recurso se actualiza satisfactoriamente, retornar `200 OK`. - Un 'code' de `0` indica una operación exitosa. ``` { "code": 0 } ``` ### Respuestas DELETE - Si el recurso se actualiza satisfactoriamente, retornar `200 OK`. - Un 'code' de `0` indica una operación exitosa. ``` { "code": 0 } ``` ### Respuestas DELETE (Bulk - Eliminación en masa) - Si el recurso se actualiza satisfactoriamente, retornar `200 OK`. - Un 'code' de `0` indica una operación exitosa. - Además de 'code', la respuesta debe proporcionar detalles adicionales en un objeto 'data'. Esto incluye una lista de los IDs que se vieron afectados (eliminados) y el total de recursos afectados. Estructura de respuesta esperada: ``` { "code": 0, "data": { "affectedIds": [ // lista de IDs ], "total": // número total de registros afectados } } ``` Ejemplo de una respuesta exitosa: ``` { "code": 0, "data": { "affectedIds": [ 1, 2, 3, 4 ], "total": 4 } } ``` ## Manejo de Errores - Utilizar códigos de estado HTTP para indicar la naturaleza del error. - Incluir un cuerpo de respuesta que proporcione detalles específicos y pueda ser fácilmente interpretado por el cliente. Posibles respuestas de error: 1. **Sin autorización:** Cuando una solicitud carece de las credenciales necesarias o las credenciales son incorrectas. ``` { "code": 401, "message": "Unauthorized" } ``` 2. **Recurso no encontrado:** Utilizado cuando el recurso solicitado no existe. ``` { "code": 404, "message": "Resource not found" } ``` 3. **Errores específicos del endpoint:** Para situaciones que requieren un mensaje de error más específico, utilizamos un código único por endpoint. Este código es especialmente útil para el manejo de errores en el front-end, incluyendo situaciones como la traducción de mensajes. El código de estado HTTP en el header de la respuesta en estos casos es 400. Ejemplo de respuesta: ``` { "code": 39024, // Este es un código de error único para un caso específico en este endpoint. "message": "Error get company report logo" } ``` ## Versionado La API debe versionarse. Por ejemplo: `https://api.company.com/v1/resource` ## Seguridad - Todos los puntos de acceso deben estar asegurados con protocolos de seguridad estándar (por ejemplo, HTTPS/SSL). - Implementar autenticación y autorización adecuadas (por ejemplo, token de acceso). ## Filtrado Cuando la API permite recuperar colecciones de recursos, es fundamental ofrecer mecanismos para filtrar estos datos y permitir que los consumidores de la API obtengan solo los recursos que necesitan. Para lograr una experiencia coherente y fácil de entender, seguimos las siguientes convenciones para pasar información de filtrado a través de query strings. ### Filtrado por Fechas Para los filtros que involucran fechas, ya sea un rango de fechas o una sola fecha, adoptamos el siguiente estilo: - Las fechas deben estar en formato `YYYY-MM-DD` (por ejemplo, `2023-10-17`). - Para especificar un rango de fechas, separamos las fechas de inicio y fin con un carácter de barra vertical (`|`), sin espacios. Esto se utiliza tanto para rangos cerrados como para una fecha única. Ejemplo: `filterByEndExpectedDateRange=2023-10-17|2023-10-18` Este parámetro indicaría un filtro que busca recursos con una fecha de finalización esperada que caiga en el rango específico del `17 de octubre de 2023` al `18 de octubre de 2023` ### Filtrado por Valores Múltiples En casos donde se filtra por múltiples valores, como identificadores, seguimos estas pautas: - Los valores se separan con una barra vertical (`|`), sin espacios. - Si el conjunto de valores comienza con un signo de exclamación (`!`), esto indica una operación de filtrado "NOT IN", es decir, excluir todos los recursos que tengan un valor dentro de este conjunto. Ejemplo: `filterByResponsibleUserIds=1|2` El ejemplo anterior filtraría los recursos buscando aquellos donde el usuario responsable tenga identificadores `1` o `2`. En el caso de querer excluir valores específicos, se usaría: `filterByResponsibleUserIds=!1|2` Esto devolvería los recursos que no estén asignados a los usuarios con identificadores `1` o `2`. ### Notas Adicionales - Todos los parámetros de filtrado deben seguir la convención camelCase en sus nombres. ## Conclusión Este documento representa nuestras normas internas para garantizar una API consistente, eficiente y segura.