OpenAPI

Hasta ahora hemos delegado en Micronaut la tarea de generar el OpenAPI a partir de nuestras anotaciones (Code-First). Pero en Api-First somos nosotros quienes definimos la API para que, por un lado, el framework genere el código y por otro, los clientes puedan consumirlo.

OpenAPI es el estándar abierto de facto en la industria para describir APIs RESTful de forma independiente del lenguaje de programación. Mantenido por la OpenAPI Initiative (bajo el paraguas de la Linux Foundation), permite definir endpoints, formatos de entrada/salida, mecanismos de autenticación y esquemas de datos en un documento estructurado en formato YAML o JSON.

An icon of a key

En este capítulo se presenta el formato OpenAPI brevemente, pero puedes consultar toda la especificación en OpenAPI

Estructura básica

A continuación se presenta un extracto de cómo sería un OpenAPi en formato YAML:

 1 openapi: 3.0.3
 2 info:
 3   title: Petstore Lite API
 4   version: 1.0.0
 5   description: Contrato oficial para el servicio de gestión de mascotas.
 6 
 7 servers:
 8   - url: http://localhost:8080/api/v1
 9     description: Servidor local de desarrollo
10 
11 paths:
12   # Definición de rutas y operaciones HTTP
13   /pets/{id}:
14     get:
15       summary: Obtener mascota por ID
16       operationId: getPetById
17       parameters:
18         - name: id
19           in: path
20           required: true
21           schema:
22             type: integer
23             format: int64
24       responses:
25         '200':
26           description: Mascota encontrada
27           content:
28             application/json:
29               schema:
30                 $ref: '#/components/schemas/Pet'
31       ...
32 
33 components:
34   # Elementos reutilizables (Schemas, Respuestas, Parámetros)
35   schemas:
36     Pet:
37       type: object
38       ...
An icon of a key

En el ejemplo anterior se ha utilizado el formato YAML, escrito a “mano” pero existen editores o plugins que facilitan la definición del OpenAPI de forma visual. Por ejemplo Swagger Editor Online es el editor online de referencia.

  • openapi: Especifica la versión del estándar utilizada. La serie 3.0.x y 3.1.x son las normas actuales en producción.

  • info: Metadatos de la API (título, versión semántica, términos de servicio, contacto, licencia).

  • servers: Array con las URLs base donde la API está desplegada o estará disponible.

  • paths: La espina dorsal del documento. Define los endpoints disponibles, los métodos HTTP admitidos (get, post, delete, etc.), parámetros de entrada y respuestas esperadas.

  • components: El almacén de componentes reutilizables. Aquí se definen los Schemas (los DTOs), respuestas comunes o esquemas de seguridad para evitar duplicar código YAML.

Paths

En paths asociamos rutas HTTP con parámetros de entradas y las respuestas esperadas

En cada path indicamos el verbo HTTP (get, post, delete, etc.) así como los parámetros que pueden venir en la ruta y/o en el body

Así mismo definimos las respuestas esperadas por el endpoint (cuantas más definamos mejor explicado quedará la API)

An icon indicating this blurb contains a warning

El campo operationId es fundamental al trabajar con herramientas de generación de código como las de Micronaut. Determinará directamente el nombre del método Java que se creará en la interfaz resultante, lo cual nos ayudará en la implementación.

Schemas

Mediante los schemas definimos la estructura de los DTOS que se van a utilizar en la API.

En Api-First definiremos los campos y formatos que se van a utilizar en la API pensando en la integración con los clientes, no en la implementación. Es decir, prestaremos cuidado en no definir campos que serían propios de la capa de persistencia por ejemplo

Micronaut (y otras herramientas orientadas a la generación del código) usarán los schemas para generar las clases Java que corresponden junto con los métodos de acceso a sus propiedades.

En esta fase podremos indicar si un campo es obligatorio o no, su tipo y su formato, si es un enumerado, etc. Por ejemplo:

 1 components:
 2   schemas:
 3     Pet:
 4       type: object
 5       required:
 6         - id
 7         - name
 8       properties:
 9         id:
10           type: integer
11           format: int64
12           example: 1
13         name:
14           type: string
15           example: "Tiramisu"
16         age:
17           type: integer
18           example: 10          
19         status:
20           type: string
21           enum: [AVAILABLE, ADOPTED]

Atributos como required, enum, minimum o pattern son leídos por Micronaut durante la fase de compilación para aplicar automáticamente las anotaciones de Jakarta Validation (@NotNull, @Pattern, @Min) sobre las clases Java generadas.