---
title: Middleware du SDK
url: https://platform.claude.com/docs/fr/cli-sdks-libraries/middleware
description: Interceptez et modifiez les requêtes et les réponses du SDK.
---

Le SDK Claude fournit un hook de « middleware » (intergiciel), ou intercepteur, qui vous permet d'exécuter du code avant l'envoi d'une requête et après la réception de la réponse. Utilisez un middleware pour des préoccupations transversales telles que la journalisation, les nouvelles tentatives personnalisées, l'annotation des requêtes et la gestion du repli en cas de refus.

```mermaid
sequenceDiagram
    accTitle: How a request and its response pass through middleware
    accDescr: Your code sends the request to Middleware A. Middleware A calls next(request) to pass it to Middleware B, and Middleware B calls next(request) to pass it to the SDK core. The SDK core sends the HTTP request to the Claude API and receives the HTTP response. The response returns through Middleware B, then Middleware A, to your code.
    autonumber
    participant App as Your code
    participant M1 as Middleware A
    participant M2 as Middleware B
    participant Core as SDK core
    participant API as Claude API
    App->>M1: request
    M1->>M2: next(request)
    M2->>Core: next(request)
    Core->>API: HTTP request
    API-->>Core: HTTP response
    Core-->>M2: response
    M2-->>M1: response
    M1-->>App: response
```

Chaque middleware peut inspecter ou remplacer la requête avant d'appeler `next()`, et la réponse après le retour de `next()`.

## Enregistrement d'un middleware

Chaque middleware est une fonction qui reçoit la requête sortante et le gestionnaire suivant. Appelez `call_next(request)` (typescript: `next(request)`; csharp: `next(request, cancellationToken)`; go: `next(req)`; java: `nextClient.execute(request, requestOptions)`; php: `$next($request)`; ruby: `call_next.call(request)`) pour transmettre la requête au reste de la chaîne (ou directement au cœur du SDK s'il s'agit du dernier middleware), et renvoyez sa réponse. Tout ce qui précède cet appel s'exécute à l'aller ; tout ce qui le suit s'exécute au retour.

<CodeGroup exclude="shell">
  ```python Python
  def logging_middleware(request: APIRequest, call_next: CallNext) -> APIResponse[Any]:
      # Avant la requête
      print(f"-> {request.method} {request.url}")

      # Transmettre la requête au reste de la chaîne
      response = call_next(request)

      # Après la requête
      print(f"<- {response.status_code}")

      return response


  client = Anthropic(middleware=[logging_middleware])
  ```

  ```typescript TypeScript
  import type { Middleware } from "@anthropic-ai/sdk";

  const loggingMiddleware: Middleware = async (request, next, ctx) => {
    // Avant la requête
    ctx.logger.debug("->", request.method, request.url);

    // Transmettre la requête au reste de la chaîne
    const response = await next(request);

    // Après la requête
    ctx.logger.debug("<-", response.status, request.url);

    return response;
  };

  const client = new Anthropic({ middleware: [loggingMiddleware] });
  ```

  ```csharp C#
  AnthropicClient client = new()
  {
      Handlers =
      [
          Handler.Create(async (request, next, cancellationToken) =>
          {
              // Avant la requête
              Console.WriteLine($"Sending {request.Method} {request.RequestUri}");

              // Transmettre la requête au gestionnaire suivant
              var response = await next(request, cancellationToken);

              // Après la requête
              Console.WriteLine($"Received {(int)response.StatusCode}");

              return response;
          }),
      ],
  };
  ```

  ```go Go
  client := anthropic.NewClient(
  	option.WithMiddleware(func(req *http.Request, next option.MiddlewareNext) (*http.Response, error) {
  		// Avant la requête
  		start := time.Now()
  		slog.Info("sending request", "method", req.Method, "url", req.URL)

  		// Transmettre la requête au reste de la chaîne
  		res, err := next(req)
  		if err != nil {
  			return nil, err
  		}

  		// Après la requête
  		slog.Info("received response", "status", res.StatusCode, "duration", time.Since(start))

  		return res, nil
  	}),
  )
  ```

  ```java Java
  AnthropicClient client = AnthropicOkHttpClient.builder()
      .fromEnv()
      .addInterceptor(Interceptor.syncOnly((nextClient, request, requestOptions) -> {
          // Avant la requête
          IO.println(request.method() + " /" + String.join("/", request.pathSegments()));

          // Transmettre la requête au gestionnaire suivant
          HttpResponse response = nextClient.execute(request, requestOptions);

          // Après la requête
          IO.println(response.statusCode());

          return response;
      }))
      .build();
  ```

  ```php PHP
  $loggingMiddleware = function (RequestInterface $request, callable $next): ResponseInterface {
      // Avant la requête
      error_log("-> {$request->getMethod()} {$request->getUri()}");

      // Transmettre la requête au reste de la chaîne
      $response = $next($request);

      // Après la requête
      error_log("<- {$response->getStatusCode()}");

      return $response;
  };

  $client = new Client(requestOptions: ['middleware' => [$loggingMiddleware]]);
  ```

  ```ruby Ruby
  logging_middleware = lambda do |request, call_next|
    # Avant la requête
    puts "-> #{request.method.upcase} #{request.url}"

    # Transmettre la requête au reste de la chaîne
    response = call_next.call(request)

    # Après la requête
    puts "<- #{response.status}"

    response
  end

  client = Anthropic::Client.new(middleware: [logging_middleware])
  ```
</CodeGroup>

## Ordre des middlewares

Lorsque vous enregistrez plusieurs middlewares, ils s'appliquent dans l'ordre indiqué : le code « avant » du premier middleware s'exécute en premier, et son code « après » s'exécute en dernier. Les middlewares enregistrés sur le client s'exécutent avant les middlewares transmis en tant qu'option par requête.

Dans le SDK Go, les appels répétés à `option.WithMiddleware` se concatènent (d'abord ceux du client, puis ceux de la méthode). Dans les autres SDK, transmettez un tableau ; les entrées ultérieures enveloppent les entrées intérieures.

## Remplacement du client HTTP

Le SDK accepte également un client HTTP personnalisé (pour la configuration d'un proxy, un TLS personnalisé ou le regroupement de connexions). Un seul client HTTP est utilisé par client SDK ; le définir remplace celui par défaut. Le client HTTP personnalisé reçoit les requêtes après l'exécution de tous les middlewares.

## Middleware intégré

Le SDK inclut un middleware de repli en cas de refus qui relance automatiquement, sur un modèle de repli, une requête que Claude refuse (`stop_reason: "refusal"`). [Refus et repli](https://platform.claude.com/docs/fr/build-with-claude/refusals-and-fallback) répertorie les modèles dont les classificateurs de sécurité peuvent refuser des requêtes, et [Détecter et relancer sur un modèle de repli](https://platform.claude.com/docs/fr/build-with-claude/refusals-and-fallback#client-side-fallback) couvre la configuration et des exemples pour chaque langage.
