Swagger Codegen (Generación de código)

Swagger es un conjunto de herramientas de código abierto construidas en torno a la especificación OpenAPI (anteriormente conocida como especificación Swagger), utilizadas para diseñar, construir, documentar y utilizar servicios web RESTful.

Swagger incluye principalmente:

  • Swagger Editor: Un editor basado en navegador para escribir especificaciones OpenAPI
  • Swagger UI: Interfaz de documentación de API visual que permite a los desarrolladores explorar las API de forma interactiva
  • Swagger Codegen: Genera automáticamente código de cliente y stubs de servidor a partir de la especificación OpenAPI

La especificación OpenAPI es un formato de definición independiente del lenguaje para describir APIs RESTful.

OpenAPI permite que humanos y computadoras descubran y comprendan las funciones de un servicio sin necesidad de acceder al código fuente ni a documentación adicional.


Swagger Codegen (Generación de código)

Preparación del entorno

Antes de comenzar, asegúrate de tener instalado en tu sistema:

  • Java 8+
  • Maven (para proyectos Java)
  • Git (para obtener el código fuente)

Instalar Swagger Codegen:

# 方法1: 使用homebrew (macOS)
brew install swagger-codegen

# 方法2: 从GitHub下载JAR文件
wget https://repo1.maven.org/maven2/io/swagger/codegen/v3/swagger-codegen-cli/3.0.36/swagger-codegen-cli-3.0.36.jar -O swagger-codegen-cli.jar
java -jar swagger-codegen-cli.jar help

Generar SDK de cliente

Generación de cliente Java

Tomando como ejemplo la API Petstore, genera un cliente Java:

# 使用命令行工具
swagger-codegen generate -i https://petstore.swagger.io/v2/swagger.json -l java -o ./java-client

# 或使用JAR文件
java -jar swagger-codegen-cli.jar generate \
  -i https://petstore.swagger.io/v2/swagger.json \
  -l java \
  -o ./java-client

Estructura del SDK de cliente generado:

java-client/
├── pom.xml                  # Maven项目文件
├── README.md                # 说明文档
├── src/
│   ├── main/
│   │   ├── java/           # 生成的Java代码
│   │   └── resources/      # 配置文件
│   └── test/               # 测试代码
└── .gitignore

Usar el cliente Java generado:

Ejemplo

import io.swagger.client.*;
import io.swagger.client.auth.*;
import io.swagger.client.model.*;
import io.swagger.client.api.PetApi;

public class Example {
    public static void main(String[] args) {
        ApiClient defaultClient = Configuration.getDefaultApiClient();
       
        // Configurar autorización con clave de API
        ApiKeyAuth apiKey = (ApiKeyAuth) defaultClient.getAuthentication("api_key");
        apiKey.setApiKey("YOUR API KEY");
       
        PetApi apiInstance = new PetApi();
        try {
            Pet result = apiInstance.getPetById(789L);
            System.out.println(result);
        } catch (ApiException e) {
            System.err.println("Exception when calling PetApi#getPetById");
            e.printStackTrace();
        }
    }
}

Generación de cliente Python

Generar cliente Python:

swagger-codegen generate -i https://petstore.swagger.io/v2/swagger.json -l python -o ./python-client

Ejemplo de uso del cliente Python:

Ejemplo

import swagger_client
from swagger_client.rest import ApiException

# Crear instancia del cliente API
api_instance = swagger_client.PetApi()
api_client = api_instance.api_client

# Establecer clave de API
api_client.configuration.api_key['api_key'] = 'YOUR_API_KEY'

try:
    # Obtener la mascota con el ID especificado
    pet = api_instance.get_pet_by_id(pet_id=789)
    print(pet)
except ApiException as e:
    print("Exception when calling PetApi->get_pet_by_id: %s\n" % e)

Soporte para otros lenguajes

Swagger Codegen admite múltiples lenguajes y marcos de trabajo (frameworks), incluyendo pero no limitado a:

  • JavaScript/TypeScript (Node.js, Angular, React, etc.)
  • Ruby
  • PHP
  • C#/.NET
  • Go
  • Swift
  • Kotlin
  • Scala

Ver la lista de lenguajes admitidos:

swagger-codegen langs

Generar código stub del servidor

Generación de código de servidor Spring

Generar stub de servidor Spring Boot:

swagger-codegen generate \
  -i https://petstore.swagger.io/v2/swagger.json \
  -l spring \
  -o ./spring-server

Estructura del código de servidor Spring generado:

spring-server/
├── pom.xml                  # Maven项目文件
├── README.md                # 说明文档
├── src/
│   ├── main/
│   │   ├── java/           # 控制器接口和模型类
│   │   └── resources/      # 配置文件和静态资源
│   └── test/               # 测试代码
└── .gitignore

Implementar las interfaces de controlador generadas:

Ejemplo

@Controller
public class PetApiController implements PetApi {
    @Override
    public ResponseEntity<Pet> getPetById(Long petId) {
        // Implementar lógica de API
        Pet pet = new Pet();
        pet.setId(petId);
        pet.setName("Mascota de ejemplo");
        pet.setStatus(Pet.StatusEnum.AVAILABLE);
        return ResponseEntity.ok(pet);
    }
}

Generación de código de servidor Node.js

Generar código de servidor Node.js:

swagger-codegen generate \
  -i https://petstore.swagger.io/v2/swagger.json \
  -l nodejs-server \
  -o ./nodejs-server

Ejemplo de uso del servidor Node.js:

Ejemplo

// Implementar la lógica de negocio en el archivo de servicio generado
module.exports.getPetById = function(petId) {
  return new Promise(function(resolve, reject) {
    var examples = {};
    examples['application/json'] = {
      "id": petId,
      "name": "Mascota de ejemplo",
      "status": "available"
    };
    resolve(examples[Object.keys(examples)[0]]);
  });
}

OpenAPI Generator avanzado

OpenAPI Generator vs Swagger Codegen

OpenAPI Generator es una bifurcación (fork) de Swagger Codegen, que comenzó a desarrollarse de forma independiente en 2018. Sus principales ventajas incluyen:

  • Mantenimiento por una comunidad más activa
  • Soporte más amplio de plantillas
  • Mejor soporte para OpenAPI 3.0
  • Más opciones de configuración y capacidad de personalización

Instalar OpenAPI Generator:

# 使用npm安装
npm install @openapitools/openapi-generator-cli -g

# 使用Homebrew安装
brew install openapi-generator

# 下载JAR文件
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.1/openapi-generator-cli-6.0.1.jar -O openapi-generator-cli.jar

Instalación y uso básico

Método de uso básico:

# 显示帮助信息
openapi-generator help

# 生成Java客户端
openapi-generator generate \
  -i https://petstore.swagger.io/v2/swagger.json \
  -g java \
  -o ./java-client

# 列出支持的生成器
openapi-generator list

Plantillas personalizadas

Fundamentos de plantillas

OpenAPI Generator utiliza el motor de plantillas Mustache. Para personalizar el código generado, necesitas:

  1. Obtener las plantillas predeterminadas
  2. Modificar las plantillas para satisfacer tus necesidades
  3. Generar código con plantillas personalizadas

Crear plantillas personalizadas<
# 使用JAR文件获取特定语言的模板
java -jar openapi-generator-cli.jar author template \
  -g java \
  -o ./custom-templates/java

Ejemplo de archivo de plantilla (api.mustache de Java):

{{>licenseInfo}}
package {{package}};

{{#imports}}import {{import}};
{{/imports}}

{{#operations}}
public interface {{classname}} {
    {{#operation}}
    {{#summary}}
    /**
     * {{summary}}
     * {{/summary}}
     {{#notes}}
     * {{notes}}
     {{/notes}}
     */
    {{#returnType}}{{returnType}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{dataType}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
    
    {{/operation}}
}
{{/operations}}

Aplicar la plantilla para generar código

Generar código usando plantillas personalizadas:

openapi-generator generate \
  -i https://petstore.swagger.io/v2/swagger.json \
  -g java \
  -o ./java-client-custom \
  -t ./custom-templates/java

Configuración personalizada

Opciones de configuración global

OpenAPI Generator admite varias opciones de configuración global:

openapi-generator generate \
  -i spec.yaml \
  -g java \
  -o output \
  --api-package com.example.api \
  --model-package com.example.model \
  --package-name com.example \
  --git-repo-id my-repo \
  --git-user-id my-username

Configuración específica del lenguaje

Los diferentes generadores tienen sus propias opciones de configuración específicas:

# Java客户端生成器的特定选项
openapi-generator generate \
  -i spec.yaml \
  -g java \
  -o output \
  --library retrofit2 \
  --java8 true \
  --use-rx-java true

Uso de archivos de configuración

Puedes crear archivos de configuración para guardar ajustes comunes:

Archivo config.json

{
  "artifactId": "petstore-client",
  "groupId": "com.example",
  "library": "retrofit2",
  "apiPackage": "com.example.api",
  "modelPackage": "com.example.model",
  "invokerPackage": "com.example.client",
  "dateLibrary": "java8",
  "java8": true
}

Usar archivo de configuración:

openapi-generator generate \
  -i spec.yaml \
  -g java \
  -o output \
  -c config.json

Casos prácticos de proyectos reales

Diseño de API desde cero

Diseñar la API usando Swagger Editor:

  1. Visitahttps://editor.swagger.io/
  2. Crear archivo de especificación OpenAPI:

Ejemplo

openapi: 3.0.0
info:
  title:API de gestión de productos
  version: 1.0.0
  description:API RESTful para gestionar productos
servers:
  - url: https://api.example.com/v1
paths:
  /products:
    get:
      summary:Obtener lista de productos
      responses:
        '200':
          description:Éxito
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Product'
    post:
      summary:Crear nuevo producto
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProductInput'
      responses:
        '201':
          description:Creación exitosa
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Product'
  /products/{productId}:
    get:
      summary:Obtener un solo producto
      parameters:
        - name: productId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description:Éxito
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Product'
components:
  schemas:
    Product:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        price:
          type: number
        category:
          type: string
        createdAt:
          type: string
          format: date-time
    ProductInput:
      type: object
      required:
        - name
        - price
      properties:
        name:
          type: string
        price:
          type: number
        category:
          type: string

Generación de código de proyecto completo

Generar proyecto completo a partir de la especificación de API diseñada:

  1. Guardar la especificación de API comoproduct-api.yaml
  2. Generar código de frontend y backend:
# 生成Spring Boot服务端
openapi-generator generate \
  -i product-api.yaml \
  -g spring \
  -o ./product-service \
  --additional-properties=java8=true,dateLibrary=java8

# 生成React前端
openapi-generator generate \
  -i product-api.yaml \
  -g typescript-fetch \
  -o ./product-frontend \
  --additional-properties=supportsES6=true,npmName=product-api-client

Problemas comunes y soluciones

  1. El código generado no compila

    • Asegúrate de que la especificación OpenAPI cumpla con el estándar
    • Revisa errores de sintaxis en las plantillas personalizadas
    • Actualiza a la versión más reciente del generador
  2. Las plantillas personalizadas no tienen efecto

    • Asegúrate de que la ruta de la plantilla sea correcta
    • Verifica que el nombre del archivo de plantilla coincida con la plantilla original
    • Usa rutas absolutas en lugar de relativas
  3. El código generado carece de ciertas funcionalidades

    • Revisa si la especificación OpenAPI define completamente las funcionalidades necesarias
    • Confirma que se utilizó el generador y las opciones de configuración correctas
    • Considera usar plantillas personalizadas para agregar funcionalidades adicionales
  4. El código generado es incompatible con el proyecto existente

    • Usa opciones de configuración para ajustar el nombre del paquete y las convenciones de nomenclatura
    • Ajusta el estilo del código mediante plantillas personalizadas
    • Considera generar solo las interfaces de API e implementar manualmente la lógica específica

Funciones avanzadas y mejores prácticas

Gestión de versiones

Mejores prácticas para gestionar versiones de API:

  1. Especifica claramente el número de versión en la especificación OpenAPI
  2. Usa control de versiones semántico (SemVer)
  3. Usa diferentes rutas base para distintas versiones de la API
  4. Guarda los archivos de especificación de todas las versiones

Integración CI/CD

Integrar la generación de código en el flujo de CI/CD:

Ejemplo

# Ejemplo de flujo de trabajo de GitHub Actions
name: Generate API Client

on:
  push:
    paths:
      - 'api-specs/**'

jobs:
  generate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
     
      - name: Set up JDK
        uses: actions/setup-java@v2
        with:
          java-version: '11'
         
      - name: Install OpenAPI Generator
        run: npm install @openapitools/openapi-generator-cli -g
       
      - name: Generate Client
        run: |
          openapi-generator generate \
            -i api-specs/product-api.yaml \
            -g typescript-fetch \
            -o ./generated-client
           
      - name: Commit and Push
        run: |
          git config --global user.name 'GitHub Actions'
          git config --global user.email '[email protected]'
          git add ./generated-client
          git commit -m "Auto-generate API client"
          git push

Recomendaciones para aplicaciones empresariales

Para proyectos empresariales:

  1. Gestionar las especificaciones de API de forma centralizada

    • Usar repositorios Git dedicados para gestionar las especificaciones de API
    • Implementar procesos de revisión de código para garantizar la calidad
  2. Establecer guías de estilo para el código generado

    • Crear convenciones de nomenclatura coherentes
    • Definir estándares de manejo de errores
    • Diseñar un enfoque unificado de autenticación
  3. Combinar código generado y código escrito manualmente

    • Generar el marco base y los modelos de datos
    • Implementar manualmente la lógica de negocio compleja
    • Usar el patrón adaptador para aislar el código generado y el código manual
  4. Considerar la arquitectura de microservicios

    • Mantener especificaciones de API independientes para cada microservicio
    • Usar una puerta de enlace de API (API Gateway) para unificar las interfaces externas
    • Generar clientes entre servicios mediante la generación de código
Otras extensiones