Advanced

Diseno e implementacion de estrategias de versionado de API con Claude Code

Aprende sobre el diseno e implementacion de estrategias de versionado de API con Claude Code. Consejos practicos y ejemplos de codigo incluidos.

Importancia del versionado de API

Los cambios disruptivos en una API tienen un gran impacto en las aplicaciones cliente. Con Claude Code, puedes realizar de forma integral el diseno y la implementacion de la estrategia de versionado.

3 metodos de versionado

MetodoEjemploVentajaDesventaja
Ruta URL/api/v1/usersClaro y facil de entenderLa URL cambia
HeaderAPI-Version: 1URL limpiaDificil de descubrir
AcceptAccept: application/vnd.app.v1+jsonConforme al estandar HTTPPuede volverse complejo

Implementacion del metodo de ruta URL

Es el metodo mas comun y facil de entender.

import express from "express";

const app = express();

// Router por version
import v1Router from "./routes/v1";
import v2Router from "./routes/v2";

app.use("/api/v1", v1Router);
app.use("/api/v2", v2Router);

// routes/v1/users.ts
const v1Router = express.Router();

v1Router.get("/users", async (req, res) => {
  const users = await prisma.user.findMany();
  // Formato de respuesta v1
  res.json({
    data: users.map((u) => ({
      id: u.id,
      name: u.name,
      email: u.email,
    })),
  });
});

// routes/v2/users.ts
const v2Router = express.Router();

v2Router.get("/users", async (req, res) => {
  const users = await prisma.user.findMany({
    include: { profile: true },
  });
  // Formato de respuesta v2 (con paginacion agregada)
  res.json({
    data: users.map((u) => ({
      id: u.id,
      fullName: u.name,
      email: u.email,
      profile: u.profile,
    })),
    pagination: {
      total: users.length,
      page: 1,
      perPage: 20,
    },
  });
});

Implementacion del metodo de header

function versionMiddleware(
  req: express.Request,
  res: express.Response,
  next: express.NextFunction
) {
  const version = req.headers["api-version"] || "1";
  req.apiVersion = parseInt(version as string, 10);

  // Verificar si es una version soportada
  const supportedVersions = [1, 2, 3];
  if (!supportedVersions.includes(req.apiVersion)) {
    return res.status(400).json({
      error: `Version de API no soportada: ${version}`,
      supportedVersions,
    });
  }

  // Header de advertencia para versiones obsoletas
  if (req.apiVersion < 2) {
    res.set("Deprecation", "true");
    res.set("Sunset", "2026-06-01");
    res.set(
      "Link",
      '<https://api.example.com/docs/migration>; rel="deprecation"'
    );
  }

  next();
}

app.use("/api", versionMiddleware);

app.get("/api/users", async (req, res) => {
  switch (req.apiVersion) {
    case 1:
      return handleUsersV1(req, res);
    case 2:
      return handleUsersV2(req, res);
    default:
      return handleUsersV2(req, res);
  }
});

Patron de transformacion de respuesta

Un diseno que absorbe las diferencias entre versiones mediante una capa de transformacion.

type UserV1 = {
  id: string;
  name: string;
  email: string;
};

type UserV2 = {
  id: string;
  fullName: string;
  emailAddress: string;
  createdAt: string;
};

const transformers = {
  1: (user: DBUser): UserV1 => ({
    id: user.id,
    name: user.name,
    email: user.email,
  }),
  2: (user: DBUser): UserV2 => ({
    id: user.id,
    fullName: user.name,
    emailAddress: user.email,
    createdAt: user.createdAt.toISOString(),
  }),
};

function createVersionedHandler<T>(
  fetcher: (req: express.Request) => Promise<T[]>,
  transformerMap: Record<number, (item: T) => unknown>
) {
  return async (req: express.Request, res: express.Response) => {
    const data = await fetcher(req);
    const transform = transformerMap[req.apiVersion];
    res.json({ data: data.map(transform) });
  };
}

Depreciacion y soporte de migracion

function deprecationNotice(
  sunsetDate: string,
  migrationGuide: string
) {
  return (
    req: express.Request,
    res: express.Response,
    next: express.NextFunction
  ) => {
    res.set("Deprecation", "true");
    res.set("Sunset", sunsetDate);
    res.set("Link", `<${migrationGuide}>; rel="deprecation"`);

    console.warn(
      `API obsoleta v${req.apiVersion} accedida: ${req.path}`
    );

    next();
  };
}

// v1 sera retirada en junio de 2026
app.use(
  "/api/v1",
  deprecationNotice(
    "2026-06-01",
    "https://docs.example.com/migration/v1-to-v2"
  ),
  v1Router
);

Prompts de implementacion con Claude Code

Aqui tienes un ejemplo de prompt para solicitar a Claude Code la introduccion de versionado de API. Para los fundamentos del diseno de API, consulta la guia de introduccion a Claude Code; para el manejo de errores, consulta diseno de error boundary.

Introduce versionado en la REST API existente.
- Metodo de ruta URL (/api/v1, /api/v2)
- v1 mantiene la API actual tal cual
- v2 unifica el formato de respuesta (agrega pagination)
- Configura tambien los headers de depreciacion para v1
- Crea tambien la documentacion de la guia de migracion

Para las mejores practicas de versionado de API, Microsoft REST API Guidelines tambien es una referencia util. Para los metodos de uso de Claude Code, consulta la documentacion oficial.

Summary

El versionado de API es un diseno esencial para la operacion a largo plazo. Si introduces el versionado con Claude Code, comprendiendo la estructura del codigo existente, puedes evolucionar la API minimizando el impacto en los clientes existentes.

#Claude Code #API design #versioning #REST API #TypeScript