Onde devo colocar uma solicitação de API no MVC?

25

Estou construindo um aplicativo Web usando um padrão MVC. Seguindo esse tipo de arquitetura, podemos ver que todos os métodos usados ​​para interagir com o banco de dados são implementados no modelo .

Mas o que acontece se eu precisar chamar um serviço exposto por outras pessoas na web? Por exemplo, eu gostaria de acessar a API do Facebook para obter todos os seguidores da minha página, então, onde coloco esses métodos?

Obviamente, a visualização não é uma boa ideia, porque este módulo é dedicado à apresentação, o controlador não deve ser usado para recuperar dados, mas o modelo geralmente é dedicado apenas à interação com o banco de dados.

Então, você pode me dar uma dica sobre isso? E por favor, você pode me dizer se estou cometendo alguns erros sobre a arquitetura MVC?

Ema.jar
fonte
2
Acho que as pessoas poderiam fornecer melhores respostas se você listasse algumas das bibliotecas e estruturas que você está usando para dar suporte ao seu aplicativo MVC. Embora o padrão MVC seja independente da tecnologia, nem todas as estruturas o seguem explicitamente. Além disso, a maioria das estruturas maduras já possui documentação excelente e saber qual delas você está usando facilitaria direcioná-lo para uma explicação preexistente que segue sua linha de pensamento.
CLW
2
Base de dados? Fonte de dados? São apenas dados.
2
Existem tantas opiniões sobre o que "MVC" deveria ser, que essa pergunta é abstrata demais para responder.
RemcoGerlich
2
Além disso, considere chamar a API a partir do seu código Javascript de front-end e não fazer com que ela toque seu material de "MVC" de back-end.
RemcoGerlich
@Remcogerlich, é por isso que propus uma adição à implementação real que ele está olhando. Ele poderia estar lidando com um back-end e uma implementação de front-end do mvc. Também poderíamos ter outro padrão que explique melhor essas diferenças.
CLW

Respostas:

37

O modelo não se limita à interação com o banco de dados, ele é responsável por obter e manipular dados.

Portanto, para sua visão e controle, não deve fazer diferença, se os dados vierem de um banco de dados ou de um serviço da web ou forem totalmente aleatórios, portanto, você deve fazê-lo no modelo.

MVC é um padrão de apresentação que separa apenas as diferentes camadas de representação.

Isso não significa que esse modelo deva ser uma bagunça uniforme do código do espaguete. Seu próprio modelo também pode ser em camadas, mas o controlador não deve saber de onde vêm os dados.

Um método público em seu modelo pode ser estruturado desta forma (pseudo-código), que pode ser chamado pelo seu controlador:

public MyDataClass getData(int id) {
    WebServiceData wsData = WebService->getData(id);
    DatabaseData dbData = ORM->getData(id);
    return new MyDataClass(wsData, dbData);
}

WebServicee ORMpode haver instâncias de interfaces que podem ser substituídas por zombarias por injeção de dependência, mas seus controladores e visualizações não precisam ser alterados para fins de teste.

Resíduo
fonte
8
O modelo não deve ter lógica e, portanto, não deve interagir diretamente com nada. O padrão MVC exige claramente que toda a lógica seja colocada nos controladores. Esses controladores devem entrar em contato com o banco de dados, API, etc ... e atualizar o modelo conforme necessário. Isso mantém a tecnologia do seu modelo independente e garante que ela sirva apenas como um mecanismo de armazenamento que pode ser passado para várias visualizações para apresentação e controladores para manipulação adicional.
CLW
3
@CLW: Model! = Modelo de dados. Mais detalhes podem ser encontrados em outro lugar, por exemplo, stackoverflow.com/a/14045514/124983
Residuum
2
@CLW: a lógica de negócios não deve estar em M, V ou C. Os modelos são uma abstração de um armazenamento de dados, as visualizações e os controladores são sua interface de usuário. Eles são a periferia do aplicativo que você está criando, que deve ser "apenas código", que não precisa saber sobre coisas como bancos de dados e a web.
RemcoGerlich
2
A parte "modelo" é interpretada de várias centenas de maneiras diferentes. Sempre fui ensinado que um modelo é uma representação. Um modelo de trem é uma representação de um trem real, com pequenas partes móveis que se movem exatamente como o real. Da mesma forma, o modelo no seu aplicativo é uma representação dos sistemas e processos que você está construindo para substituir seu software. Como tal, os modelos têm comportamento . Esse comportamento incorpora sua "lógica de negócios". Assim, quando você ignorar acesso pura dados CRUD, UI, e de interoperabilidade, o que é esquerda é, provavelmente, o seu "modelo" - classes de domínio, regras de negócio, etc.
Anaximandro
11
@RemcoGerlich Eu não disse nada sobre lógica de negócios. Simplesmente afirmei que, como a maioria das interpretações do MVC exige que o modelo nada mais seja do que uma estrutura simples que representa o estado do seu aplicativo, que a responsabilidade de entrar em contato com o banco de dados, API, etc ... não deve ser colocada dentro do modelo, pois deve ser livre de lógica. O dever de comunicação com o banco de dados deve recair sobre o controlador ou outro objeto gerenciado pelo controlador.
CLW
12

Existe um mal-entendido comum (intencional?) Sobre o que M, V e C são. Não sobre os papéis que eles assumem, mas quais são eles.

Na definição original de MVC da GUI da área de trabalho, eles eram módulos . Normalmente, um aplicativo tinha vários deles, às vezes trabalhando em trigêmeos, às vezes tendo uma variedade de visualizações e modelos que alguns controladores podiam misturar e combinar.

Nos frameworks web, OTOH, eles tendem a ser vistos como camadas , onde são apenas um de cada um e lida principalmente com a cobertura de algum nível de abstração subyacent: "a camada de modelo abstrai o banco de dados", "a camada de visualização implementa a apresentação", "o controlador camada processa a entrada do usuário ".

Então, eu diria que você já tem um modelo, dedicado à interação com o banco de dados, e agora apenas precisa criar outro modelo para lidar com sua API de origem. Se você os tornar o mais semelhante possível, a maior parte do controlador e do código de exibição poderá funcionar perfeitamente com qualquer um dos modelos.

Javier
fonte
11
Concordado: os modelos sempre deveriam ser o domínio do problema inteiro. Em aplicativos complicados, sempre era para ser a maior parte do código. Eles consistiam em todo o código que não seria alterado se você alterar a interface do usuário (por exemplo, do site para a GUI ou mesmo para o aplicativo de linha de comando). Pense em um compilador. Apenas uma parte muito pequena do código seria alterada se você passasse de uma interface de usuário da linha de comando para uma GUI ou mesmo da Web. Todos os ângulos dessa aplicação são os modelos.
Kevin Cathcart
11
No uso original do termo Smalltalk, todos os controles de interface do usuário na interface tinham seu próprio modelo, visualização e controlador.
RemcoGerlich
5

Parte da dificuldade de qualquer discussão sobre o MVC é que diferentes grupos o cooptaram para significar coisas diferentes. A implementação do MVC usada em, por exemplo, um aplicativo Rails, seria quase irreconhecível para alguém que escreve um aplicativo Swing. Na medida em que o MVC ainda é uma coisa bem definida, é mais um conjunto de princípios orientadores (separar o aplicativo principal da sua representação visual, fornecer mecanismos flexíveis para permitir que os dois sejam executados juntos), que podem ser implementados em vários maneiras.

De fato, há uma tendência a atribuir nomes diferentes a diferentes designs derivados do MVC (consulte este artigo de Martin Fowler para uma discussão sobre isso), ou mesmo a desistir de nomes precisos - por exemplo, o AngularJS se descreve como um Model-View-Whatever estrutura.

Portanto, é difícil responder sem saber com qual versão do "MVC" você está trabalhando. No entanto, uma solicitação de API normalmente faria parte do aplicativo principal (a parte que não deve ser alterada se você decidir usar uma representação visual diferente), que em muitas implementações estaria totalmente contida no modelo.

James_pic
fonte
2

Aqui , o modelo é descrito assim:

Um modelo armazena dados que são recuperados no controlador e exibidos na visualização. Sempre que houver uma alteração nos dados, eles são atualizados pelo controlador.

Eu diria que o controlador inclui a lógica de chamar o serviço ou chama um Serviceobjeto separado . Se o serviço for separado, você poderá criar testes com mais facilidade, por exemplo, se nenhuma conexão com um serviço pela rede for possível, alguns TestServicepoderão fornecer respostas do Servicelocal.

Verifique também esta resposta que sugere que o Controlador chama o serviço.

nulo
fonte
2

Seu modelo nunca deve conter nenhum código real e deve ser visto como mais uma mensagem ou uma estrutura usada para gerenciar o conteúdo manipulado pelo controlador e exibido pela visualização.

Seu controlador deve ser responsável por entrar em contato com quaisquer APIs, bancos de dados, serviços, etc ... solicitando uma alteração e gerenciando as atualizações necessárias para o modelo.

Toda a força do padrão MVC é que ele desacopla a lógica (o controlador) da visualização e do estado (o modelo). Ao fazer isso, agora você tem a garantia de que apenas o código no controlador pode criar efeitos colaterais, pois a visualização e o modelo simplesmente não têm permissão para fazer alterações.

Ele também permite uma melhor reutilização de código, pois um modelo pode ser compartilhado entre vários controladores e visualizações.

CLW
fonte
4
Eu acho que quando você diz "modelo" aqui, você está se referindo a "modelo de exibição", que IMO é uma coisa separada. Um viewmodel obtém dados do controlador para a visualização e, como tal, é um detalhe de implementação da View ou um aspecto das comunicações entre o View e o Controller que realmente não se encaixa (depende de como você o vê). O "Modelo" no MVC refere-se a um modelo de sistema - uma representação do sistema que incorpora seus dados, estrutura e comportamento. O modelo é estado e lógica; o controlador é o que faz com que a lógica seja executada e o estado seja alterado quando a visualização é manipulada.
Anaximander
@anaximander Não, estou me referindo ao modelo em uma interpretação bastante rigorosa do MVC (consulte Wikipedia, Microsoft MVC, padrões de design do Head First, etc ...) Nesses casos, o modelo nada mais é do que uma estrutura simples para transmitir dados ao redor e não existe um modelo de visualização. Embora a implementação do Microsoft MVC adicione vários atributos ao modelo, isso é mais por conveniência do que qualquer coisa. No final, o objetivo do padrão MVC era facilitar as boas práticas de separação de código e limitar os efeitos colaterais.
CLW
1

Pode estar longe daqui, mas é assim que me sinto em relação aos WebApps e ao trabalhar com APIs remotas [complexas] em muitos casos:

Eu o tornaria uma classe (ou seja, uma biblioteca de métodos de mitigação de dados) em vez de modelo (ou seja, pilha de funções de mitigação de dados). Parece que agiria de maneira mais transparente, mais independente de lógica / esquema, e você poderia usá-lo em qualquer lugar sem carregar-> chamando um modelo / controlador sempre que quiser usá-lo. A lógica ainda está separada, o ponto de dados ainda é flexível e parece mais aberto à interoperabilidade em casos estranhos, como empilhar clientAJAX-> appJSON-> appJSON-> appLIB-> remoteAPI-> remoteJSON etc. para pesquisar indiretamente o endpoint.

dhaupin
fonte