Redoc, documentación ágil libre de dependencias
Tags: redoc, javascript, node, spanish
Published: 2021-10-21 02:05:32

## Resumen
Sabemos la importancia que tiene la documentación en los sistemas de información y como desarrolladores debemos aprender a ser asertivos a la hora de hacerlo, debido a que el exceso o la falta de documentación puede llegar a ser una carga inútil para un equipo de trabajo si este no es muy maduro. 
La documentación de APIs es algo bastante poderoso y útil, que lamentablemente muy pocas veces hacemos. Si escalamos  un poco el uso de esta para analizar el impacto que tiene en los equipos de trabajo, veremos beneficios como, ayudar a los nuevos integrantes del equipo a tener una mejor transición y un mayor entendimiento de un proyecto, incluso a aquellos integrantes con más experiencia les permite recordar funcionalidades implementadas hace algún tiempo.

##Documentar Asertivamente
Documentar puede llegar a ser una tarea engorrosa y en la mayoría de los casos amerita implementar dependencias externas a nuestros proyectos. esto último tiende a evitarse por la preocupación de sumar cargas a la ejecución. Entonces, si sabemos que es importante documentar, pero no queremos agregar herramientas que afecten nuestro código, ¿Qué deberíamos usar?
Swagger ofrece una solución bastante completa, basada en la especificación de Openapi, sin embargo es necesario agregar algunas dependencias, por lo que la nueva especificación Redoc es una mejor opción para lograr una documentación ágil, sin usar dependencias de terceros en tu proyecto.

**Openapi:** es un estándar creado para describir APIs, se centra en la evolución y promoción de un formato de descripción neutral para el proveedor, basado inicialmente en la especificación de swagger.

**Redoc:** es un software para la documentación de APIs. Conformado por una interfaz interactiva y ordenada con objetos anidados basado en un marco responsive de 3 paneles ([ejemplo](http://redocly.github.io/redoc/)).

En este artículo no se abordarán conceptos a profundidad, por lo que recomendamos leer antes [este artículo](https://medium.com/condorlabs-engineering/automating-api-documentation-c8f48f2bc30e) bastante completo acerca del tema. Abordaremos las funcionalidades más importantes de Redoc para documentar sus APIs de manera asertiva y organizada.

##Configuración redoc-cli
Para usar **Redoc** utilizaremos una dependencia de desarrollo llamada **redoc-cli.** estas la agregamos a nuestro proyecto de la siguiente forma:
```
npm install --save-dev redoc-cli
```
Importante observar que usamos el flag `--save-dev` para incluirla en las dependencias de desarrollo. Además, para su configuración explicaremos los sientes flags, que nos permitirán usar redoc-cli para generar nuestra documentación.

- **bundler:** permite crear un archivo html con la documentación para su posterior renderización desde el servidor, sin necesidad de dependencias.
- **serve:** permite ejecutar un servidor local que te permita visualizar los cambios locales en tu documentación.
- **--watch:** permite reiniciar automáticamente la aplicación cuando se detectan cambios de archivo en el yml.

> Para conocer más flags que puede utilizar en **redoc-cli** mirar esta [doc](https://github.com/Redocly/redoc/blob/master/cli/README.md).

Para iniciar con nuestro ejemplo este [repositorio](https://github.com/WilliamDeLaEspriella/redoc-todo-list/tree/template!) se ha preparado para ti. En él tendremos un template para trabajar todo el ejemplo. Ahora, para poder empezar necesitamos agregar los scripts que nos permitirán ejecutar nuestra documentación en local y también crear un bundler para producción. Usando los flags que ya se explicaron arriba a la parte de script de su package.json. Agregamos a este las siguientes instrucciones:
![redoc cofiguration in package json](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pln2em2t9it96q0uflna.png)

Usamos **concurrently** para ejecutar dos instrucciones importantes de forma simultanea; la primera nos permite ejecutar nuestra documentación y visualizar los cambios de manera local, la segunda nos ayuda a actualizar nuestro bundler localizado en index.html de esta manera podremos visualizar nuestra documentación usando el comando `npm start`.

##Configuración inicial
Para agregar las configuraciones y datos de nuestra documentación usaremos **un archivo openapi.yml que colocaremos en una carpeta llamada docs**, el cual podemos visualizar en las ejecuciones de los comandos mostrados en la parte de arriba. Dentro este archivo colocamos una configuración básica de openapi que explicaremos posteriormente.

![redoc basic configuration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jknago5nd83iwd9gp145.png)

Ejecute **npm run docs** en su consola situada en la raíz de tu proyecto. Luego entre a su navegador en la ruta `http://localhost:8080`.  deberías ver una pantalla como esta:
 
![redoc pages](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g6oa0hd12k6fapi55wdm.png)
 
>Si usted no tiene el mismo resultado puede usar el código mostrado [aquí](https://github.com/WilliamDeLaEspriella/redoc-todo-list/tree/basic-configuration).

##Documentando nuestra API
Cualquier configuración de openapi consta de ciertos  ítems que nos permitirán agregar un tipo de información especifica a nuestra documentación.
Primero empezamos explicando cada uno de los  ítems que nos ofrece la especificación de openapi para construir paso a paso la documentación de nuestra API.
**Open api version:** Aquí colocaremos la versión de openapi con la que se va a trabajar. Como pudimos ver en el ejemplo, usaremos la versión 3.
**[Info](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#infoObject): Esta etiqueta sirve par colocar un objeto con toda la información relevante de la documentación** como título, logo, descripción, etc. En nuestro archivo la configuraremos de la siguiente forma.

![info configuration redoc](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x82b7nd6nco10ei4ocus.png)

**Servers: Aquí agruparemos los dominios que posea nuestra API.** es bien sabido que dentro de algunos equipos de trabajo la construcción de una API puede ser manipulada desde diferentes entornos como test, staging, demo o producción. En esta sección colocaremos todos esos puntos de acceso a nuestro servidor.
 
![servers configuration redoc](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ggeiac0sef6s6qzyhtbu.png)
 
**Security:** Lista de valores que incluyen objetos con requisitos de seguridad alternativos. Solo se debe satisfacer uno de los objetos de requisito de seguridad para autorizar una solicitud. 
Para el ejemplo usaremos 3 tipos de autenticación: basic, Jwt y api key. **Para más información de como implementar autenticación visite este [enlace](https://swagger.io/docs/specification/authentication/)**. Nuestro ejemplo quedaría de esta manera:

![Authentication define for redoc and openapi](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7jactxyp1c5r828o3mol.png)

**Tags: Con ayuda de los tags podremos agrupar endpoints de una manera más visual en su documentación.** para nuestro ejemplo usaremos dos,  tag1 y tag2, solo para lograr una mayor visualización de su funcionamiento. se colocan de esta manera:

 ![Tags Configuration for openapi and redoc](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t9ni97mq2v5kjshnexjw.png)

**[Components](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#componentsObject):** Esta sección nos sirve para hacer una abstracción de los schemas, responses, parameters, etc. que se usan principalmente en la sección de **path.**

Usando este enfoque podemos lograr un código más organizado y reutilizable. Para nuestro ejemplo crearemos las especificaciones para los componentes de seguridad mencionados en la anterior sección utilizando la etiqueta securitySchemes, además crearemos unos schemas y responses que se usarán en el path de la siguiente sección.

>Consulte [aquí](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#schema-object) para más validaciones en los schemas

![Example configuration components in redoc](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h25ryw4cmsjqnkl4gqbk.png)
  
**[Paths](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#pathsObject): En esta sección documentaremos los endpoint de nuestra API y los tipos de consultas que se harán en estos**, incluyendo todos los datos internos que posee un endpoint como las diferentes respuestas o cuántos y dónde se reciben los parámetros.
Debido a que esta sección define las características del endpoint es bastante importante llamar a estos desde la etiqueta components y **no declarar los schemas y parámetros en el mismo path.** de esta manera logrará tener un archivo de documentación más organizado.
Para nuestro ejemplo definimos una ruta /todo_list, con dos tipos de consulta, un get y un post. Usando los componentes que definimos en la anterior sección podemos crear la definición de la siguiente manera:
![configuration path in redoc](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/41e18f7qeygocnbakz6l.png)

Llegado este punto podemos ejecutar el servidor y visualizar todas las configuraciones, ya sea ejecutando el `npm run docs` para lanzar **redoc-cli** o de la misma manera ya ejecutar el servidor con `npm start`. Debería ver una imagen como esta:

![dashboard redoc](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ikab0s4iah2fnfytyztz.png)

Si por alguna razón no puede visualizar los cambios, ejecute nuevamente **npm run docs** o verifique que tenga todo de la manera correcta en este [link](https://github.com/WilliamDeLaEspriella/redoc-todo-list/tree/avanzada-configuration).

##Refactorizando sus yml
Para este ejemplo se definió una sola ruta para documentar con dos tipos de consulta, pero **debe tener en cuenta que las APIs o servidores pueden contar con decenas de rutas y estas tener diferentes tipos de consulta.** La etiqueta **components** le puede ayudar a agrupar configuraciones en común, pero aún le puede quedar una archivo bastante extenso y difícil de actualizar muchas veces. Una solución a esto es dividir el código en archivos más pequeños y luego referenciarlos en el archivo principal. La forma en la que referenciarmos en yml es:
```
$ref: [ruta]#/[components]
```
Ejemplo:
```
$ref: ../componets/schemas.yml#/tolistResponse
```
**[Aquí](https://github.com/WilliamDeLaEspriella/redoc-todo-list/tree/refactor-code)** puede visualizar todo el proyecto ya refactorizado y organizado en módulos, de manera que todo el código es más legible y organizado.

##Conclusiones
Para el contexto del ejemplo usamos una app básica en node que permite renderizar un único archivo html para visualizar los beneficios de documentar APIs con **Redoc**.

En este post pudimos visualizar:
- Lo fácil que es documentar las especificaciones de nuestra API usando un lenguaje clave-valor como yaml.
- Los beneficios que nos trae usar las características definidas por openapi.
- El poder que nos da redoc-cli al permitirnos ejecutar y crear un bundler de nuestra documentación de manera ágil.
- La facilidad de poder tener las especificaciones de su documentación en un solo html y libre de dependencias extra para su proyecto.
- Los beneficios de que el resultado del bundler sea un html, es que se puede visualizar en casi cualquier entorno o framework que soporte este formato.

Es importante otorgar el tiempo y la importancia que necesita el proceso de documentación de APIs en nuestro equipo. Debemos apropiarnos del impacto que este posee para un proceso de desarrollo de software mas saludable.