OpenAPI es un estándar para crear, administrar y consumir API REST. Conocido previamente como Swagger, en el último año ha sido adoptado por la Linux Foundation y obtuvo el apoyo de compañías como Google, Microsoft, IBM, Paypal, etc. para convertirse en un estándar para las API REST.
Cuando creamos un API Rest, tenemos varias opciones durante el desarrollo para comprobar que ésta funciona. Quizás la más ocurrente es utilizar directamente el navegador e ir cambiando la url de cada uno de nuestros servicios u operaciones. El principal problema con esto es que en un equipo de trabajo, no nos acordaremos de las urls, por lo que se comparten o anotan en alguna wiki o se contemplan otras opciones muy similares.
Dentro de estas otras opciones nos encontramos con: Fiddler, Avadced REST Client (extensión de Chrome), o Postman entre otras herramientas, que nos facilitan esta labor en alguna u otra medida. Por supuesto, y al margen de los Test Integrados, que veremos en algún otro post (con xUnit), Postman es realmente la que mas me gusta y, en mi opinión, la más útil de todas. Además de hacer estas pruebas de las que comentamos, nos permite: diseñar APIs, crear Mocks, test automáticos, documentarlas y mucho más.
De igual forma, Open API, como estándar es la opción que estamos buscando, tanto para el “testeo” del que hablamos, como para ayudarnos con la documentación, para la exploración de APIs, e incluso para la auto-generación de SDKs.
Tanto Postman como OpenAPI, son herramientas complementarias, si bien, al crear nuestras propias API, el hecho de utilizar OpenAPI nos va a proporcionar:
- Definición y documentación
- Cumplimiento del standard
- Auto-generar SDKs para que terceros puedan comunicarse
- Personalización
- Visualización
- Ejecución y pruebas
- Gratis para su uso
- Y además, muy fácil de implementar en .NET
Al hablar de diseño de API y refiriéndonos a OpenAPI, implícitamente estamos hablando de JSON o YAML, dos formatos de ficheros también estándares, que van a permitirnos definir y diseñar las mimas. La versión actual de la especificación es la 3.0.1 y orientada a YAML y la versión previa la 2.0, que es idéntica a la especificación 2.0 de Swagger antes de ser renombrada a “Open API Specification”.
En el momento de escribir el post, el tooling para trabajar con la versión 3.0, aún es limitado.
Diseñando un API
Veamos como diseñar un API :
- Acceder al editor online (Editor de Swagger) para la versión 2.0 o bien al editor https://app.swaggerhub.com, tanto para la versión 2.0 o la 3.0.
- Crear o modificar el YAML, que es la definición del API, adaptándola a nuestros requisitos en base a esta especificación: https://github.com/OAI/OpenAPI-Specification.
- Realizar pruebas (“Try it out”), para conocer tanto los requests como los responses de cada operación.
- Una vez concluido el diseño, estamos en el momento de auto-generar, para diferentes lenguajes, el servidor: haskell, rails5, rust-server, spring, asp.net core, etc., y el cliente: eiffel, java, html, groovy, go, jmeter, scala, javascript, typescript-jquery, angular, C#, etc.
- Con el código resultante tras la auto-generación, tendríamos prácticamente, desde el día 1 de desarrollo, un API desplegada a modo de Mock. Importante, principalmente para desarrolladores Front, que necesitan un API, que probablemente no será desarrollada hasta una fase posterior. ¡IMPORTANTE Evitemos bloqueos entre equipos y tareas. Diseñemos APIs!
Nota: En esta URL: https://app.swaggerhub.com/apis/juanluelguerre/Taskin/v1, he publicado la versión 1.0 (muy sencilla) de Taskin, sobre la que podremos probar.
Creando APIs con NET Core y OpenAPI
Otra de las opciones, también importante es que si comenzamos un desarrollo desde cero, en base a una arquitectura propia y dependiente de cada proyecto, necesitaremos que el código auto-generado, se adecúe a la misma. Para ello, tendremos dos alternativas:
- Trabajar con el SDK de OpenAPI y modificar las plantillas de auto-generación.
- Integrar OpenApi directamente en nuestro código .NET.
De acuerdo al objetivo de este Post, optaremos por la alternativa 2, donde para ellos seguiremos los siguientes pasos:
- Crear un proyecto “ASP.NET Core Web Application”
- Seleccionar el tipo de aplicación: API. Por el momento, no marcaremos la opción de Docker.
- Para .NET Core 2.1, por defecto usamos HTTS, por lo que incluimos una nueva variable de entorno ASPNETCORE_HTTPS_PORT con el valor del puerto HTTS (ej: 5003) o bien la instrucción services.AddHttpsRedirection(options => options.HttpsPort = 5003);
- Añadir la referencia al paquete NuGet: Swashbuckle.AspNetCore
- Añadir el siguiente código al final del método “ConfigureServices(IServiceCollection services)” del fichero Startup.cs
- Añadir el siguiente código al final del método “Configure(IApplicationBuilder app, IHostingEnvironment env)” del fichero Startup.cs.
- Ejecutar la aplicación añadiendo el sufijo “swagger” a la url base de nuestra aplicación, es decir: https://localhost:5003/swagger
- En este punto podremos probar nuestra aplicación, sin necesidad de recordar la url de cada operación. Comprobaremos que de un simple string “[“value1”, “value2”]” como resultado, pasamos a visualizar, navegar, ejecutar y depurar fácilmente.
Nota: Si navegamos al json “/swagger/v1/swagger.json”, es decir, a la url: https://localhost:5003/swagger/v1/swagger.json, obtenemos el “.JSON” correspondiente a la especificación OpenAPI, y, al utilizarlo en el editor Online de Swagger, como vimos al principio del post, verificaremos, que nuestra API REST es correcta y por tanto cumple con el estándar.
Otra alternativa para la generación de Servidor y/o Cliente es “NSwag Studio”, que ya comentamos brevemente en un post anterior, se trata de una aplicación de escritorio, con ciertas opciones de personalización. Así mismo, también podemos utilizarla al igual que “Swashbuckle”, para integrarla en nuestra API REST .NET Core.
Y, para finalizar, si estas pensando en migrar tu especificación OpenAPI 2.0 a la versión 3.0, puedes utilizar esta herramienta: https://openapi-converter.herokuapp.com/
Espero que haya sido de utilidad
Saludos & Happy Coding!
Juanlu