Eu estava lendo a documentação do Spring Cloud Netflix quando descobri uma maneira de compartilhar uma interface entre um servidor HTTP e seu cliente. Eles usam este exemplo para microsserviços, embora não haja motivo para que ele não possa se estender à comunicação HTTP genérica:
// 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 {
}
Isso define uma interface que é usada como servidor (o Spring o @RestController
transforma em servidor HTTP) e como cliente (o Feign o @FeignClient
configura para uso do cliente HTTP). As implementações de classe de servidor e cliente podem ser usadas em projetos separados, mas ainda usam a mesma interface para garantir que os tipos correspondam.
No entanto, abaixo do exemplo, eles colocam a seguinte ressalva:
Nota: geralmente não é aconselhável compartilhar uma interface entre um servidor e um cliente. Ele apresenta acoplamento rígido e, na verdade, também não funciona com o Spring MVC em sua forma atual (o mapeamento de parâmetros do método não é herdado).
OK, então não está bem integrado no momento ... mas essa parte vem após o aviso contra o compartilhamento de código e a introdução do acoplamento entre o servidor e o cliente, o que eles acham mais importante. Por que eles acham que é uma má idéia compartilhar uma interface dessa maneira?
Sem ele, você perde a capacidade de garantir que o servidor e o cliente enviem dados uns aos outros que eles possam entender. Você pode adicionar um campo a um, mas não ao outro, e descobrir apenas a incompatibilidade até o tempo de execução. Na minha opinião, não está introduzindo acoplamento, mas apenas revelando o acoplamento que já existe. A necessidade de tornar os servidores completamente independentes é maior do que a necessidade de informar quais tipos de dados eles receberão?
fonte
Respostas:
O motivo, conforme declarado nos comentários, é que isso resulta no acoplamento rígido da plataforma do cliente à plataforma do servidor. Aqui, isso significa que seu cliente é obrigado a usar o idioma / plataforma que você está usando no servidor para entender o contrato esperado do seu servidor. Observe que há uma diferença entre compartilhar o mesmo código (um artefato de um idioma / plataforma específico) e concordar com um contrato específico.
Muitos projetos usam documentação para seus contratos. Solicitações e respostas de exemplo em um formato neutro (por exemplo, JSON) sobre protocolos padrão (por exemplo, REST). (Veja os documentos da Stripe API , por exemplo). Como é impraticável escrever um contrato baseado em código para todas as plataformas possíveis de clientes que você queira usar ou permitir. Outros ainda usam ferramentas de gerenciamento de API para definir contratos neutros .
Seu exemplo de adição de um campo é uma preocupação separada - um exemplo de por que é importante a versão dos contratos da API. Permita que os clientes usem a versão para a qual foram projetados. Existe uma nova versão da API incompatível com versões anteriores ao lado da antiga. O cliente da versão antiga continua trabalhando até que sua equipe consiga atualizá-la ou até você desativar a versão antiga (após um período de descontinuação / migração). Consulte Mudança Paralela .
Seguir o aviso (implícito no aviso) ajuda o cliente e o servidor a evoluir de maneiras e ritmos que fazem sentido para cada um. Se você puder razoavelmente garantir que seu servidor e cliente sempre compartilhem o mesmo idioma / plataforma E evoluam no mesmo ritmo, use um artefato de código específico do idioma e da plataforma, pois seu contrato provavelmente será válido. No entanto, isso provavelmente não é uma expectativa razoável, especialmente para projetos direcionados ao Netflix OSS (algo especificamente voltado para escalabilidade e desempenho da nuvem, com toda essa complexidade necessária).
fonte