Должны ли мы вызывать Web API из приложения MVC в том же решении?

33

Я работаю над проектом в MVC, в котором есть мобильное приложение, поэтому ясно одно, что мы должны использовать веб-API, чтобы его можно было использовать в мобильном приложении.

После создания API, когда мы начали разрабатывать веб-сайт, мы растерялись и обсуждали, использовать ли API или иметь прямой доступ к объекту Business. И в итоге мы получили от более опытного разработчика мнение о том, чтобы использовать Web API вместо непосредственного использования Business object

У меня путаница в отношении этой структуры решения.

1) Почему мы должны использовать Web API и делать HTTP-запрос (который занимает много времени), чтобы получить или поместить данные вместо бизнес-объекта напрямую, который находится в том же решении.

2) После аргументов они сказали, что если клиент хочет разместить API и веб-интерфейс на другом облачном сервере и применить масштабирование только для API, или, возможно, он хочет иметь разные URL-адреса для доступа к API-интерфейсу и веб-интерфейсу (что вполне логично). Таким образом, в этом случае мы должны вызвать веб-API из приложения MVC в том же решении?

3) Если мы размещаем API и Web на разных хостингах, это означает, что наш Web будет использовать WebClient и будет иметь HTTP-вызов для каждой навигации. Это правильно?

4) Если мы создадим бизнес-объект как API, так и веб-хостинг на другом сервере, то если что-то изменится в BL, потребуется обновить сборку на обоих серверах.

5) Или мы должны создать только один проект для API и можем добавить представления или HTML-страницы для разработки веб-интерфейса, чтобы таким образом мы могли напрямую вызывать API из ajax.

Насколько мне известно, # 5 является лучшим решением или API только для стороннего доступа. Если у нас есть DB, EF, уровень данных и бизнес-уровень в одном решении, нам не следует использовать API для выполнения HTTP-вызовов и прямого доступа к бизнес-объекту. (поправьте меня, если я ошибаюсь) API необходим, когда мобильное приложение или рабочий стол или кто-либо другой хочет получить доступ к приложению, чтобы у нас мог быть один и тот же уровень хранилища и данных.

В моем сценарии я должен создать API, поскольку у нас также есть мобильное приложение, а на стороне API проекта мы назвали бизнес-уровень (отдельный проект) и бизнес-уровень, связывающийся с уровнем доступа к данным (отдельный проект). Поэтому мой вопрос: если мы размещаем наш API и веб-интерфейс на разных серверах, то вызов API, который является HTTP-запросом, может занять больше времени, чем использование метода из бизнес-уровня, когда мы создаем проект, и у нас есть .dll бизнес-уровня. В контроллере API мы просто конвертируем бизнес в формат json.

Я искал в интернете, но не получил убедительного ответа. Я нашел блог http://odetocode.com/blogs/scott/archive/2013/07/01/on-the-coexistence-of-asp-net-mvc-and-webapi.aspx, в котором обсуждается тот же вопрос, но снова В этом блоге мой вопрос: почему мы должны рассмотреть сценарий № 3?

Обновление: у нас может быть другой проект API и проект MVC, и мы можем вызывать API из Интернета, используя jvascript или использовать шаблон MVVM.

Ручир Шах
источник
MVVM или MVC с представлением моделей?
Эндрю Хоффман
Мы используем MVC
Ruchir Shah
Хорошо, тогда нет правильного ответа. Есть преимущества только для вызова вашего API, когда дело доходит до улучшения их качества. (поедая свою собачью еду) Есть также преимущества в производительности для выполнения вызовов inproc вместо вызова через сервисы.
Эндрю Хоффман
Google прошел этот вопрос один раз. Их продуктами являются как сервисы, так и сайты. Я считаю, что они решили, что их сайты используют свои собственные сервисы.
Эндрю Хоффман
2
Да. programmers.stackexchange.com/questions/148556/… и stackoverflow.com/questions/3590561/… являются хорошими ресурсами. Некоторые делают, некоторые нет. Нет реального «правильного» пути.
Эндрю Хоффман

Ответы:

37

Отличный вопрос! Я всегда ищу лучший способ структурировать свои проекты. Каждый момент, который вы поднимаете, имеет свои достоинства, и, изучив различные структуры решений, я должен сказать, что я согласен с большинством комментариев здесь: не существует идеального решения. Когда вы столкнетесь с такой проблемой, задайте себе несколько вопросов: Насколько сложно это приложение? Сколько систем мне нужно интегрировать - или сколько систем нужно будет интегрировать с этой системой? Сколько тестов я планирую сделать? Есть ли отдельная команда по дизайну / интерфейсу? Нужно ли нам масштабировать? Что представляет собой сессия?

Давайте посмотрим на пару сценариев и способов использовать немного хитроумного инжиниринга, чтобы сделать вещи по-настоящему крутыми (и некоторые хитрости, чтобы сделать вещи немного проще) ..

Размещение как API, так и веб-сайта в
одном проекте. В этом случае у вас может быть одно решение с нулевым или большим количеством проектов бизнес-уровня и одним гибридным проектом MVC / WebAPI (а также другие проекты - утилиты и т. Д.).

Pro's
Все в одном месте. Не нужно приставать к сложным сообщениям (вызовы HttpClient), вы можете иметь общее состояние сеанса (клиент и сервер через куки, сеанс InProc / OutOfProc и т. Д.), Пул соединений, разделяемая логика и т. Д. Развертывание не может быть более простым.

Con в
Все в одном месте .. Это, вероятно , возможно , самая монолитная структура. Между вашими слоями нет четко определенных интерфейсов. Вы получаете высокую степень сцепления . Ленивые разработчики избегают интерфейсов при работе с архитектурой такого типа, что делает тестирование огромной болью. Масштабирование / совместное размещение приложения будет затруднено.

Использование
Я бы использовал эту структуру проекта для одноразового, внутреннего или простого приложения. Создание быстрой системы для отслеживания регистрации в баскетбольном лагере на местном Y? Это твоя архитектура!

WebAPI и веб-сайт в разных проектах
Я предпочитаю этот случай. У вас есть одно решение с одним (или несколькими) MVC-проектами и одним WebAPI-проектом.

Про
Модуляризация! Слабая связь! Каждый проект может работать отдельно, тестироваться отдельно и может управляться по-разному. Это позволяет вам легче реализовывать различные стратегии кэширования в зависимости от ваших потребностей. Поддерживая четкие границы между вашими различными системами, вы можете легче заключать контракты, которые позволяют вам применять конкретные модели использования и сокращать возможные трения (читай: меньше ошибок с меньшей возможностью злоупотреблять API). Масштабирование немного проще, поскольку вам нужно только масштабировать биты, которые видят высокую нагрузку. Интеграция становится немного проще в управлении, потому что вам нужно иметь представление о том, как будет выглядеть ваш API с самого начала.


Обслуживание Кона немного сложнее. Множественные проекты означают, что вам понадобятся владельцы проектов / компонентов для отслеживания слияний, контрактов (интерфейсов), развертываний и т. Д. Ведение кода, техническая задолженность , отслеживание ошибок, управление состоянием - все это становится проблемой, поскольку их может потребоваться реализовать по-разному на основе на ваши нужды. Эти виды приложений также требуют наибольшего планирования и поддержки по мере их роста.

Используете
Создание приложения, которое может иметь 100 пользователей сегодня и 100 000 на следующей неделе / ​​месяц? Должно ли приложение отправлять уведомления, управлять сложными рабочими процессами и иметь несколько интерфейсов (веб + мобильное приложение + SharePoint)? У вас есть много времени и вы любите решать более 5000 головоломок в выходные? Это архитектура для вас!

Советы
Изложив вышесказанное, я могу понять, как ваш следующий проект может выглядеть немного устрашающе. Не беспокойтесь, вот несколько трюков, которые я выучил за эти годы.

  1. Попробуйте использовать сеансы без сохранения состояния. В небольших системах это может означать хранение зашифрованного файла cookie, содержащего как минимум внутренний идентификатор текущего пользователя и время ожидания. Большие системы могут означать хранение зашифрованных файлов cookie с простым идентификатором сеанса, который может быть выбран из хранилища данных (redis, хранилище таблиц, DHT и т. Д.). Если вы можете хранить достаточно информации, чтобы вам не приходилось обращаться к основной базе данных при каждом запросе вы будете в хорошем месте - но старайтесь хранить куки до 1к.
  2. Имейте в виду, что, вероятно, будет более одной модели. Попытайтесь думать в терминах моделей и проекций (ссылки, которые я нашел здесь, были ... не очень хорошими .. подумайте: товарная позиция одного человека - это позиция заказа другого человека - та же базовая базовая структура, но разные взгляды). Некоторые проекты имеют разные модели для каждой логической / концептуальной границы (т.е. используют конкретную модель для связи с конкретным API.
  3. API везде! Каждый раз, когда объект / класс / структура предоставляет какие-либо данные или поведение, вы устанавливаете API. Помните о том, как другие объекты или зависимости будут использовать этот API. Подумайте, как вы можете протестировать этот API. Подумайте, что может говорить с этим API (другие объекты через код? Другие системы через протокол?) И как эти данные предоставляются (строго типизированный «JSON? * Cough * XML»).
  4. Стройте то, что у вас есть, а не то, что вы себе представляете, что у вас будет через два года. Другой ответ ссылается на ЯГНИ - они абсолютно правильные! Решение мнимых проблем делает ваш срок мнимым. Ставьте твердые цели для своих итераций и достигайте их. Развертывание! Проект в разработке - это проект только с одним пользователем - вами!
  5. YMMV (ваш пробег может меняться). Здесь есть только один абсолют: есть проблема, вы строите решение. Все остальное в воздухе. Оба вышеупомянутых решения могут иметь дикий успех - и неудачу. Все зависит от вас, ваших инструментов и того, как вы их используете. Поступай легко, товарищ разработчик!
Бобби Д
источник
2
Отличный ответ! Хотел бы я поблагодарить вас за то, что вы написали, но так как я не могу думать ни о чем, я просто буду следить за вашим Twitter : P
Дан
"строго типизированный? JSON? * кашель * XML" что мне не хватает?
Александр Дерк
1
@AlexanderDerck Я упоминаю три разных варианта форматирования (хотя их и больше) ... «шутка» в том, что с XML может быть сложно работать, и он может добавить немало накладных расходов (сериализация / десериализация). Нельзя сказать, что иногда в этом нет необходимости (особенно при работе с внешними группами) ..
Бобби Д.
6

Прямой доступ к вашим бизнес-объектам напрямую (я полагаю, вы имеете в виду в своем контроллере) будет быстрее и проще.

Что делать, если клиент хочет разместить API и веб-интерфейс на другом облачном сервере и применять масштабирование только для API, или же он может захотеть использовать разные URL-адреса для доступа к API и Интернету (что несколько логично)

Тогда вам нужно будет разместить их отдельно ... но для меня это не очень логично, конечно, вы захотите масштабировать оба. Вы уверены, что вам нужно удовлетворить это требование? Это звучит как излишество. Помните ЯГНИ - если вам это не нужно, не создавайте его. Когда вам это нужно, постройте его.

Если бы это был я, я бы создал сайт, используя технологию, которая наилучшим образом соответствует сайту, тогда, когда (если) вам понадобится услуга, которую другие люди могут вызвать, создайте ее отдельно.

Rocklan
источник
Я полностью согласен с вами, потому что в конце дня масштабирование важно, и разделение интересов имеет значение для меня. Всегда полезно думать о построении n-уровневой архитектуры как о технологических изменениях, которые можно легко модернизировать или обслуживать. Например, упаковка в докер-контейнер - это еще одна вещь, которую стоит рассмотреть в будущем.
Ишвор Ханал
4

Я бы сказал; предпочитаю MVC вызывать WebAPI через HTTPClient. Логика «core dll» ошеломляет, но главное преимущество заключается в том, что ваша система будет иметь единый доступ к объектам домена по HTTP ... В любом случае по линии ... с подключением к архитектуре Micro Service и приложениями, уже переключающимися на Клиентские фреймворки (AngularJS и т. Д.) .... лучше относиться к MVC как к другому клиенту ... и научить свою команду хорошо управлять API ...

ДЕРЖИТЕ ЭТО ПРОСТО. Надеюсь, это поможет. Благодарность..

Манодж Кумар Бишт
источник
Не уверен, почему за это проголосовали, но это лучший ответ для хорошей архитектуры imo
weagle08
Я размышлял над своей ситуацией, когда я думал, что было бы неплохо вызывать API из собственного приложения MVC, но я думаю, что он отличается от этого и, возможно, многих других вопросов, которые относятся к этому вызову из серверной логики. В моем случае я буду вызывать его из своих представлений, где у меня будет Vue, формирующий сложные пользовательские интерфейсы и передающий данные в этот API. Затем я понял, что это законно, потому что в моем случае это фактически вызов из представления против серверных элементов, и любые http-вызовы были бы сделаны в любом случае при рассмотрении любого вида пользовательского интерфейса - возможно, даже больше, если бы представления, сделанные ASP. Но работает только в средах JS.
Василий Холл
Представление вызова API напрямую - хорошая мысль .... но представления MVC генерируются с сервера, поэтому вы также можете обрабатывать данные с сервера, особенно те, которые более актуальны для обработки на сервере), прежде чем рендерить частичные представления (представления) ... инфраструктура RESS (RESS) : Отзывчивый веб-дизайн + компоненты на стороне сервера) .... НО ЛУЧШЕЕ ИСПОЛЬЗОВАТЬ PURE Framework клиента (Angular / ReactJS), если вы можете полностью избежать MVC ...
Манодж Кумар Бишт