ADR: Action-Domain-Responder, l'MVC ripensato per il web

Pillar article su Action-Domain-Responder: come l'evoluzione di MVC proposta da Paul M. Jones risolve i problemi dei controller troppo grandi.

3 min di letturaArchitettura

Luigi Iadicola, Programmatore - Napoli

In questo articolo

Il problema dell'MVC nel contesto HTTP

MVC è stato progettato per interfacce desktop con interazione continua. Nel web, il ciclo è diverso: una request arriva, viene elaborata, una response parte. Non c'è interazione continua — è un singolo scambio. Eppure forziamo la logica in Controller con molti metodi (index, show, store, update, destroy) che fanno cose completamente diverse. Un UserController con 7 metodi e 7 responsabilità: non è coeso.

ADR (Action-Domain-Responder), proposto da Paul M. Jones nel 2014, è una reinterpretazione di MVC specifica per il web HTTP. L'idea: ogni endpoint è una singola Action (classe) che chiama il Domain e passa il risultato a un Responder.

I tre componenti

Action

L'Action è una classe con un singolo metodo (__invoke()) che gestisce un singolo endpoint. Non UserController con 7 metodi, ma CreateUserAction, ListUsersAction, DeleteUserAction — ognuna con una sola responsabilità. L'Action estrae i dati dalla request, chiama il Domain, e passa il risultato al Responder.

Domain

Il Domain è identico al Model/Service Layer: contiene la business logic, indipendente da HTTP. Riceve dati primitivi, esegue la logica, restituisce risultati o lancia eccezioni. L'Action non contiene logica di business — delega tutto al Domain.

Responder

Il Responder traduce il risultato del Domain in una HTTP response. Se il Domain restituisce un utente, il Responder decide se renderizzare HTML, JSON, XML, o un redirect. La logica di presentazione — quale status code, quali header, quale formato — è nel Responder, non nell'Action.

ADR vs MVC: confronto diretto

  • Controller (MVC): classe con molti metodi. UserController::store(), UserController::index(). Responsabilità multiple.
  • Action (ADR): classe con un metodo. CreateUserAction::__invoke(). Singola responsabilità.
  • View (MVC): template passivo che riceve dati. Non decide il formato della response.
  • Responder (ADR): attivo. Decide status code, header, content-type, e quale template usare in base al risultato.

Esempio pratico in PHP

Un endpoint per creare un utente:

  • CreateUserAction: estrae name ed email dalla request, chiama $this->domain->createUser($name, $email), passa il risultato a $this->responder->created($user) o $this->responder->validationError($errors).
  • UserDomain: valida i dati, crea l'utente nel database, dispara l'evento UserCreated. Nessuna dipendenza da HTTP.
  • UserResponder: se il risultato è un utente, restituisce 201 con JSON o redirect. Se sono errori, restituisce 422 con il form e i messaggi.

Vantaggi concreti

  • Single Responsibility: ogni Action fa una cosa. Niente controller con 500 righe.
  • Testabilità: l'Action è una classe piccola con dipendenze iniettabili. Il test è diretto.
  • Content negotiation: il Responder gestisce i formati (HTML, JSON, XML) senza if nel controller.
  • Navigabilità: cerchi "crea utente"? Apri CreateUserAction. Non devi cercare quale metodo di quale controller.

Quando usare ADR

  • Usa ADR quando i controller crescono troppo e diventano ingestibili
  • Usa ADR per API che devono supportare multipli formati di response
  • Usa ADR quando vuoi massima coesione: una classe per endpoint
  • Non usare ADR se i controller sono piccoli e gestibili: il overhead di una classe per endpoint non si giustifica
  • Non usare ADR se il team è abituato a MVC e il cambio di paradigma creerebbe confusione

ADR non è un sostituto di MVC: è un'evoluzione per il contesto HTTP. Quando i controller crescono e la coesione diminuisce, ADR riporta ordine con una regola semplice: una classe, un endpoint, una responsabilità.

Hai lo stesso problema in azienda?

Raccontami cosa non va e da quando. Guardo la situazione con te prima di proporre qualsiasi intervento.

RaccontameloRispondo entro un giorno lavorativo.
Argomenti:
Condividi:LinkedIn

Ricevi il prossimo articolo

Una mail per ogni articolo nuovo, nient'altro. Ti disiscrivi con un clic dal link in fondo a ogni email.