Perché è una cattiva idea condividere un'interfaccia tra server e client?

11

Stavo leggendo il Spring Cloud Netflix documentazione quando ho scoperto un modo per condividere un'interfaccia tra un server HTTP e il suo client. Usano questo esempio per i microservizi, anche se non c'è motivo per cui non possa estendersi alla comunicazione HTTP generica:

// The shared interface, in a common library
public interface UserService {
    @RequestMapping(method = GET, value = "/users/{id}")
    User getUser(@PathVariable long id);
}

// The controller, on the server
@RestController
public class UserResource implements UserService {
}

// The same interface used for the client
@FeignClient("users")
public interface UserClient extends UserService {
}

Definisce un'interfaccia che viene utilizzata sia come server (The Spring @RestController lo trasforma in un server HTTP) sia come client (The Feign @FeignClient lo imposta per l'utilizzo del client HTTP). Le implementazioni della classe client e server possono essere utilizzate in progetti separati, ma utilizzano comunque la stessa interfaccia per garantire che i tipi corrispondano.

Tuttavia, sotto l'esempio hanno messo il seguente avvertimento:

Note: It is generally not advisable to share an interface between a server and a client. It introduces tight coupling, and also actually doesn’t work with Spring MVC in its current form (method parameter mapping is not inherited).

OK, quindi non è ben integrato in questo momento ... ma quella parte viene dopo l'avvertimento contro il codice di condivisione e l'introduzione dell'accoppiamento tra il server e il client, che pensano sia più importante. Perché pensano che sia una cattiva idea condividere un'interfaccia in questo modo?

Senza di esso, si perde la possibilità di garantire che il server e il client si scambino reciprocamente i dati che possono entrambi comprendere. È possibile aggiungere un campo a uno ma non all'altro e scoprire solo la mancata corrispondenza fino al runtime. A mio avviso, non è l'accoppiamento che introduce , ma semplicemente l'accoppiamento rivelatore che esiste già. È necessario rendere i server completamente indipendenti rispetto alla necessità di far sapere loro quali tipi di dati riceveranno?

    
posta Ben S 21.06.2016 - 17:11
fonte

1 risposta

6

Il motivo, come affermato nei commenti, è che risulta strettamente accoppiante la piattaforma client alla piattaforma del server. Qui, ciò significa che al cliente è richiesto di utilizzare la lingua / piattaforma che si sta utilizzando sul server per capire il contratto previsto del server. Tieni presente che esiste una differenza tra la condivisione dello stesso codice (un artefatto di una lingua / piattaforma specifica) e l'accettazione di un contratto specifico.

Molti progetti utilizzano invece la documentazione per i loro contratti. Richieste e risposte di esempio in un formato neutro (ad esempio JSON) su protocolli standard (ad esempio REST). Ad esempio, consulta Documenti API a strisce . Perché non è pratico scrivere un contratto basato su codice per ogni possibile piattaforma client che potresti voler utilizzare o consentire. Altri ancora utilizzano gli strumenti di gestione API per definire i contratti neutrali .

Il tuo esempio di aggiunta di un campo è una questione separata: un esempio del perché è importante per i contratti API di versione. Consenti ai clienti di utilizzare la versione per cui sono progettati. Una nuova versione dell'API incompatibile all'indietro esiste accanto al vecchio. Il client per la vecchia versione continua a funzionare fino a quando il suo team non riesce a aggiornarlo o finché non si ritira la versione precedente (dopo un periodo di deprecazione / migrazione). Vedi Modifica parallela .

Seguendo il (avvertimento implicito nell'avvertimento) il client e il server si evolvono in modi e ritmi che hanno senso per ciascuno. Se è possibile garantire ragionevolmente che il server e il client condividano sempre la stessa lingua / piattaforma E evolvono allo stesso ritmo, quindi utilizzando un artefatto di codice specifico per lingua e piattaforma, poiché il contratto sarà probabilmente ok. Tuttavia, probabilmente non è un'aspettativa ragionevole, specialmente per i progetti che hanno come obiettivo Netflix OSS (qualcosa di specificamente orientato alla scalabilità e alle prestazioni del cloud, con tutta la necessaria complessità).

    
risposta data 24.06.2016 - 20:29
fonte

Leggi altre domande sui tag