Advanced

Concevoir et implementer des strategies de versionnage d'API avec Claude Code

Apprenez la conception et l'implementation de strategies de versionnage d'API avec Claude Code. Conseils pratiques et exemples de code inclus.

Importance du versionnage d’API

Les changements disruptifs d’une API ont un impact important sur les applications clientes. Avec Claude Code, vous pouvez realiser de maniere integrale la conception et l’implementation de la strategie de versionnage.

3 methodes de versionnage

MethodeExempleAvantageInconvenient
Chemin URL/api/v1/usersClair et facile a comprendreL’URL change
HeaderAPI-Version: 1URL propreDifficile a decouvrir
AcceptAccept: application/vnd.app.v1+jsonConforme au standard HTTPPeut devenir complexe

Implementation de la methode par chemin URL

C’est la methode la plus courante et la plus facile a comprendre.

import express from "express";

const app = express();

// Routeur par 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();
  // Format de reponse 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 },
  });
  // Format de reponse v2 (avec pagination ajoutee)
  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,
    },
  });
});

Implementation de la methode par 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);

  // Verifier si c'est une version supportee
  const supportedVersions = [1, 2, 3];
  if (!supportedVersions.includes(req.apiVersion)) {
    return res.status(400).json({
      error: `Version d'API non supportee : ${version}`,
      supportedVersions,
    });
  }

  // Header d'avertissement pour les versions obsoletes
  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);
  }
});

Pattern de transformation de reponse

Une conception qui absorbe les differences entre versions via une couche de transformation.

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) });
  };
}

Depreciation et support de migration

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 obsolete v${req.apiVersion} accedee : ${req.path}`
    );

    next();
  };
}

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

Prompts d’implementation avec Claude Code

Voici un exemple de prompt pour demander a Claude Code d’introduire le versionnage d’API. Pour les bases de la conception d’API, consultez le guide d’introduction a Claude Code ; pour la gestion des erreurs, consultez la conception d’error boundary.

Introduis le versionnage dans la REST API existante.
- Methode par chemin URL (/api/v1, /api/v2)
- v1 conserve l'API actuelle telle quelle
- v2 unifie le format de reponse (ajout de la pagination)
- Configure egalement les headers de depreciation pour v1
- Cree aussi la documentation du guide de migration

Pour les meilleures pratiques de versionnage d’API, Microsoft REST API Guidelines est egalement une reference utile. Pour les methodes d’utilisation de Claude Code, consultez la documentation officielle.

Summary

Le versionnage d’API est une conception essentielle pour l’exploitation a long terme. Si vous introduisez le versionnage avec Claude Code en comprenant la structure du code existant, vous pouvez faire evoluer l’API en minimisant l’impact sur les clients existants.

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