Devemos chamar a API da Web do aplicativo MVC na mesma solução?

33

Como estou trabalhando em um projeto no MVC que possui aplicativos móveis, é óbvio que precisamos usar a API da Web para que possa ser usada em aplicativos móveis.

Depois de criar a API, quando começamos a desenvolver o site, estamos confusos e discutimos se devemos usar a API ou acessar diretamente o objeto de negócios. E acabamos depois de ter uma opinião de um desenvolvedor mais experiente para consumir a API da Web em vez de usar o objeto de Negócios diretamente.

Estou tendo confusão com relação a essa estrutura de solução.

1) Por que devemos usar a API da Web e fazer uma solicitação HTTP (que consome tempo) para obter ou colocar dados em vez do objeto de negócios diretamente, que está na mesma solução.

2) Após ter argumentado, eles disseram o que se o cliente quiser hospedar API e Web em servidor de nuvem diferente e aplicar o dimensionamento apenas na API ou pode ser que ele queira ter um URL diferente para acessar API e Web (o que é lógico). Então, nesse caso, devemos chamar a API da Web do aplicativo MVC na mesma solução?

3) Se estivermos hospedando API e Web em hospedagem diferente, significa que nossa Web usará o WebClient e terá uma chamada HTTP em cada navegação. Está certo?

4) Se o objeto de negócios formar tanto a API quanto a hospedagem na Web em um servidor diferente, se algo mudar no BL precisará atualizar a compilação no servidor.

5) Ou devemos criar apenas um projeto para a API e podemos adicionar visualizações ou páginas html para desenvolver a interface da Web, para que possamos chamar diretamente a API do ajax.

De acordo com o meu conhecimento # 5 é a melhor solução ou a API é apenas para acesso de terceiros. Se tivermos DB, EF, camada de dados e camada de negócios na mesma solução, não devemos usar a API para fazer chamadas HTTP e acessar diretamente o objeto de negócios. (corrija-me se estiver errado) É necessária API quando um aplicativo móvel ou desktop ou qualquer um quiser acessar o aplicativo para que possamos ter a mesma camada de repositório e dados.

No meu cenário, eu tenho que criar API, pois também temos aplicativos móveis e, no lado da API do projeto, chamamos camada de negócios (projeto separado) e camada de negócios se comunicam com a camada de acesso a dados (projeto separado). Portanto, minha pergunta é: se hospedarmos nossa API e web em servidores diferentes, chamar a API, que é uma solicitação HTTP, pode demorar mais do que usar o método da camada de negócios à medida que criamos o projeto e temos a camada de negócios .dll. No controlador de API, acabamos de converter nossos negócios para o formato json.

Eu pesquisei na internet, mas não obtive resposta convincente. Eu encontrei um blog http://odetocode.com/blogs/scott/archive/2013/07/01/on-the-coexistence-of-asp-net-mvc-and-webapi.aspx discutindo o mesmo ponto, mas novamente Nesse blog, minha pergunta é por que precisamos considerar o cenário 3?

Atualização: podemos ter projetos de API e MVC diferentes e podemos chamar API da Web usando jvascript ou usar o padrão MVVM.

Ruchir Shah
fonte
MVVM ou MVC com modelos de exibição?
Andrew Hoffman
Estamos usando MVC
Ruchir Shah
Ok, então, então não há resposta correta realmente. Há benefícios em chamar sua API apenas quando se trata de melhorar sua qualidade. (comendo seu próprio alimento para cães) Também há benefícios de desempenho ao fazer chamadas inproc em vez de ligar através de serviços.
Andrew Hoffman
O Google passou por essa pergunta uma vez. Seus produtos são serviços e sites. Acredito que eles decidiram que seus sites consumissem seus próprios serviços.
Andrew Hoffman
2
Sim. programmers.stackexchange.com/questions/148556/… e stackoverflow.com/questions/3590561/… são bons recursos. Alguns fazem, outros não. Nenhuma maneira 'correta' real.
Andrew Hoffman

Respostas:

37

Ótima pergunta! Estou sempre procurando uma maneira melhor de estruturar meus projetos. Cada ponto que você menciona tem mérito e, tendo explorado uma variedade de estruturas de soluções, devo dizer que concordo com a maioria dos comentários aqui: não há solução perfeita. Algumas coisas a se perguntar quando se depara com esse tipo de problema: Qual é a complexidade dessa aplicação? Com quantos sistemas eu precisarei integrar - ou quantos sistemas precisarão integrar com este sistema? Quantos testes planejo fazer? Existe uma equipe de design / interface do usuário separada? Precisamos escalar? O que constitui uma sessão?

Vejamos alguns cenários e maneiras de usar um pouco de engenharia inteligente para tornar as coisas realmente impressionantes (e alguns truques para tornar as coisas um pouco mais fáceis) ..

Hospedando API e site no mesmo projeto
Nesse caso, você pode ter uma única solução com zero ou mais projetos de camada de negócios e um único projeto híbrido MVC / WebAPI (assim como outros projetos - utilitário, etc.).

Pro's
Everything está em um só lugar. Não há necessidade de enganar mensagens complicadas (chamadas HttpClient), você pode ter o estado da sessão compartilhada (cliente e servidor via cookies, sessão InProc / OutOfProc, etc), pool de conexão, lógica compartilhada, etc. A implantação não poderia ser mais simples.

Con
tudo está em um lugar .. Esta é provavelmente a estrutura mais monolítica possível. Não há interfaces claramente definidas entre suas camadas. Você acaba com alta coesão . Desenvolvedores preguiçosos evitarão interfaces ao lidar com esse tipo de arquitetura, o que torna o teste um grande problema. Escalar / co-localizar o aplicativo será difícil.

Usos
Eu usaria essa estrutura de projeto para um aplicativo único, interno ou simples. Construindo um sistema rápido para rastrear a inscrição no acampamento de basquete no Y local? Esta é a sua arquitetura!

WebAPI e site em diferentes projetos
Eu costumo preferir este caso. Você tem uma única solução com um (ou mais) projeto (s) MVC e um projeto WebAPI.


Modularização do Pro ! Acoplamento solto! Cada projeto pode ficar sozinho, ser testado separadamente e pode ser gerenciado de maneira diferente. Isso permite implementar mais facilmente diferentes estratégias de armazenamento em cache, dependendo de suas necessidades. Ao manter limites sólidos entre seus diferentes sistemas, você pode estabelecer contratos com mais facilidade, permitindo impor padrões de uso específicos e reduzir possíveis fricções (leia-se: menos bugs com menos oportunidade de abusar da API). A escala é um pouco mais fácil, pois você só precisa dimensionar os bits que estão com alta carga. A integração também se torna um pouco mais fácil de lidar, porque você precisa ter uma idéia sobre como será a sua API desde o início.

A
manutenção da Con é um pouco mais difícil. Múltiplos projetos significa que você precisará de proprietários de projetos / recursos para acompanhar fusões, contratos (interfaces), implantações etc. Manutenção de código, dívida técnica , rastreamento de erros, gerenciamento de estado - todos se tornam preocupações, pois precisam ser implementados de forma diferente sobre suas necessidades. Esses tipos de aplicativos também exigem mais planejamento e curadoria à medida que crescem.

Usa
Construir um aplicativo que poderia ter 100 usuários hoje e 100.000 na próxima semana / mês? O aplicativo precisa enviar notificações, gerenciar fluxos de trabalho complexos e ter várias interfaces (web + aplicativo móvel + SharePoint)? Tem muito tempo em suas mãos e adora resolver mais de 5000 quebra-cabeças no final de semana? Esta é a arquitetura para você!

Dicas
Tendo descrito o exposto acima, entendo como o seu próximo projeto pode parecer um pouco assustador. Não se preocupe, aqui estão alguns truques que aprendi ao longo dos anos.

  1. Tente usar sessões sem estado. Em sistemas menores, isso pode significar armazenar um cookie criptografado contendo pelo menos o ID interno do usuário atual e um tempo limite. Sistemas maiores podem significar armazenar um cookie criptografado com um ID de sessão simples que pode ser buscado em um armazenamento de dados (redis, armazenamento de tabela, DHT etc.). Se você pode armazenar informações suficientes para não precisar acessar o banco de dados principal em cada solicitação, você estará em um bom lugar - mas tente manter os cookies abaixo de 1k.
  2. Esteja ciente de que provavelmente haverá mais de um modelo. Tente pensar em termos de modelos e projeções (os links que encontrei aqui não eram bons ... pense: o item de estoque de um homem é o item de linha de pedido de outro homem - a mesma estrutura básica básica, mas visões diferentes). Alguns projetos têm um modelo diferente para cada limite lógico / conceitual (ou seja, usando um modelo específico para comunicação com uma API específica.
  3. API em todos os lugares! Sempre que um objeto / classe / estrutura expõe dados ou comportamento, você está estabelecendo uma API. Lembre-se de como outras entidades ou dependências usarão essa API. Pense em como você pode testar esta API. Considere o que pode estar falando com essa API (outros objetos via código? Outros sistemas através de um protocolo?) E como esses dados são expostos (fortemente tipado? JSON? * Tosse * XML?).
  4. Construa para o que você tem, não para o que você imagina que terá daqui a dois anos. Outra resposta faz referência ao YAGNI - eles estão absolutamente corretos! Resolver problemas imaginários torna seu prazo imaginário. Defina metas sólidas para suas iterações e cumpra-as. Implantar! Um projeto em desenvolvimento é um projeto com apenas um usuário - você!
  5. YMMV (sua milhagem pode variar). Existe apenas um absoluto aqui: há um problema, você está construindo uma solução. Tudo o resto está completamente no ar. As duas soluções acima podem ser um grande sucesso - e uma falha de sucção. Tudo depende de você, suas ferramentas e como você as utiliza. Pise levemente, desenvolvedor companheiro!
Bobby D
fonte
2
Ótima resposta! Eu gostaria de poder conceder-lhe algo por sua escrita, mas como não consigo pensar em nada, seguirei seu Twitter. : P
Dan
"fortemente digitado? JSON? * tosse * XML" o que estou perdendo?
Alexander Derck # 24/17
1
@AlexanderDerck Estou mencionando três opções de formatação diferentes (embora existam mais) .. a "piada" é que o XML pode ser difícil de trabalhar e geralmente pode adicionar uma boa sobrecarga (serialização / desserialização). Isso não quer dizer que, por vezes, não há uma necessidade (especialmente quando se trabalha com grupos externos) ..
Bobby D
6

Acessar diretamente seus objetos de negócios diretamente (presumo que você queira dizer em seu controlador) será mais rápido e fácil.

e se o cliente quiser hospedar a API e a Web em um servidor de nuvem diferente e aplicar o dimensionamento apenas na API ou se desejar ter um URL diferente para acessar a API e a Web (o que é lógico)

Então você precisará hospedá-los separadamente ... mas isso não me parece muito lógico, certamente você desejaria escalar os dois. Tem certeza de que precisa atender a esse requisito? Isso parece exagero. Lembre-se do YAGNI - se você não precisar, não o construa. Quando você precisar, construa-o.

Se fosse eu, eu construiria o site usando a tecnologia que melhor se adequa ao site, quando (se) você precisar de um serviço que outras pessoas possam chamar, crie separadamente.

Rocklan
fonte
Eu concordo totalmente com você, porque no final dos dias a escala é importante e a separação de preocupações importa para mim. É sempre bom pensar em construir uma arquitetura de n camadas, pois as mudanças na tecnologia podem ser atualizadas ou mantidas facilmente. Por exemplo, embrulhar com contêiner de docker é outra coisa a considerar no futuro.
Ishwor Khanal
4

Eu diria; prefira o MVC chamando a WebAPI através do HTTPClient. É impressionante a lógica da "core dll", mas a principal vantagem é que o sistema geral terá um único ponto de acesso aos objetos de domínio no HTTP ... De qualquer forma, na linha ... com a captura da Micro Service Architecture E os aplicativos já mudando para Estruturas do lado do cliente (AngularJS etc.) .... melhor tratar o MVC como outro cliente ... e discipular sua equipe para gerenciar bem as APIs ...

MANTENHA SIMPE. Espero que esta ajuda. Obrigado..

Manoj Kumar Bisht
fonte
Não sei por que essa votação foi
recusada,
Eu estava pensando na minha situação em que achava uma boa ideia chamar a API do próprio aplicativo MVC - mas acho que é diferente disso e talvez de muitas outras perguntas que se referem a essa chamada pela lógica do servidor. No meu caso, eu vou chamá-lo de minhas visualizações, onde o Vue formará UIs complexas e passará os dados para essa API. Então percebi que é legítimo, porque no meu caso, na verdade, é chamado de uma exibição em relação aos itens do lado do servidor e qualquer chamada http teria sido feita de qualquer maneira ao considerar qualquer tipo de interface do usuário - talvez ainda mais se as exibições feitas por ASP. Mas, apenas funciona em ambientes JS.
Vasily Hall
A API de chamada de exibição diretamente é uma boa ideia ... mas as MVC Views são geradas a partir do servidor, para que você também possa processar dados do servidor, especialmente os que são mais relevantes para o processamento do servidor) antes de renderizar visualizações parciais (Views) ... Estrutura RESS (RESS : Web design responsivo + componentes do lado do servidor) ... MAS MELHOR USE PURE Client Frameworks (Angular / ReactJS) se você puder evitar o MVC totalmente ...
Manoj Kumar Bisht