---
title: Middleware degli SDK
url: https://platform.claude.com/docs/it/cli-sdks-libraries/middleware
description: Intercetta e modifica le richieste e le risposte dell'SDK.
---

L'SDK di Claude fornisce un hook di "middleware" (software intermedio), o interceptor, che ti consente di eseguire codice prima che una richiesta venga inviata e dopo che la risposta è stata ricevuta. Usa il middleware per esigenze trasversali come il logging, i nuovi tentativi personalizzati, l'annotazione delle richieste e la gestione del fallback in caso di rifiuto.

```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
```

Ogni middleware può ispezionare o sostituire la richiesta prima di chiamare `next()`, e la risposta dopo che `next()` restituisce il controllo.

## Registrazione del middleware

Ogni middleware è una funzione che riceve la richiesta in uscita e il gestore successivo. Chiama `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)`) per inoltrare la richiesta al resto della catena (o direttamente al core dell'SDK se questo è l'ultimo middleware) e restituisci la sua risposta. Tutto ciò che precede quella chiamata viene eseguito all'andata; tutto ciò che la segue viene eseguito al ritorno.

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

      # Inoltra la richiesta al resto della catena
      response = call_next(request)

      # Dopo la richiesta
      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) => {
    // Prima della richiesta
    ctx.logger.debug("->", request.method, request.url);

    // Inoltra la richiesta al resto della catena
    const response = await next(request);

    // Dopo la richiesta
    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) =>
          {
              // Prima della richiesta
              Console.WriteLine($"Sending {request.Method} {request.RequestUri}");

              // Inoltra la richiesta al gestore successivo
              var response = await next(request, cancellationToken);

              // Dopo la richiesta
              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) {
  		// Prima della richiesta
  		start := time.Now()
  		slog.Info("sending request", "method", req.Method, "url", req.URL)

  		// Inoltra la richiesta al resto della catena
  		res, err := next(req)
  		if err != nil {
  			return nil, err
  		}

  		// Dopo la richiesta
  		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) -> {
          // Prima della richiesta
          IO.println(request.method() + " /" + String.join("/", request.pathSegments()));

          // Inoltra la richiesta al gestore successivo
          HttpResponse response = nextClient.execute(request, requestOptions);

          // Dopo la richiesta
          IO.println(response.statusCode());

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

  ```php PHP
  $loggingMiddleware = function (RequestInterface $request, callable $next): ResponseInterface {
      // Prima della richiesta
      error_log("-> {$request->getMethod()} {$request->getUri()}");

      // Inoltra la richiesta al resto della catena
      $response = $next($request);

      // Dopo la richiesta
      error_log("<- {$response->getStatusCode()}");

      return $response;
  };

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

  ```ruby Ruby
  logging_middleware = lambda do |request, call_next|
    # Prima della richiesta
    puts "-> #{request.method.upcase} #{request.url}"

    # Inoltra la richiesta al resto della catena
    response = call_next.call(request)

    # Dopo la richiesta
    puts "<- #{response.status}"

    response
  end

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

## Ordine dei middleware

Quando registri più middleware, questi vengono applicati nell'ordine indicato: il codice "before" (prima) del primo middleware viene eseguito per primo, e il suo codice "after" (dopo) viene eseguito per ultimo. I middleware registrati sul client vengono eseguiti prima dei middleware passati come opzione per singola richiesta.

Nell'SDK Go, le chiamate ripetute a `option.WithMiddleware` vengono concatenate (prima quelle del client, poi quelle del metodo). Negli altri SDK, passa un array; le voci successive avvolgono quelle interne.

## Sostituzione del client HTTP

L'SDK accetta anche un client HTTP personalizzato (per la configurazione del proxy, TLS personalizzato o il connection pooling). Viene utilizzato un solo client HTTP per ogni client SDK; impostarlo sostituisce quello predefinito. Il client HTTP personalizzato riceve le richieste dopo che tutti i middleware sono stati eseguiti.

## Middleware integrati

L'SDK include un middleware di fallback in caso di rifiuto che ritenta automaticamente su un modello di fallback una richiesta che Claude rifiuta (`stop_reason: "refusal"`). [Rifiuti e fallback](https://platform.claude.com/docs/it/build-with-claude/refusals-and-fallback) elenca i modelli i cui classificatori di sicurezza possono rifiutare le richieste, e [Rilevare e ritentare su un modello di fallback](https://platform.claude.com/docs/it/build-with-claude/refusals-and-fallback#client-side-fallback) illustra la configurazione e gli esempi per ciascun linguaggio.
