Должны ли вы писать свой back-end как API?

Сегодня у меня была горячая дискуссия о нашем приложении MVC. У нас есть веб-сайт, написанный в MVC ( ASP.NET ), и он обычно следует шаблону сделать что-то в view -> нажмите на контроллер -> контроллер создает модель (вызывает диспетчера, который получает данные, строит модель в самом методе контроллера) -> модель отображает -> промывка & повторить.

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

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

Мне кажется, что это плохая идея по разным причинам.

Во всяком случае, я не могу найти что-либо по googling, который мог бы обсудить эту практику. Кто-нибудь имеет информацию о плюсах, минусах, почему вы должны, почему вы не должны или не читаете?

По некоторым причинам я думаю, что это плохая идея:

  • Это слишком абстрактно, чтобы запустить бэкэнд с API. Вы пытаетесь сделать его слишком гибким, что сделает его неуправляемым беспорядком.

  • Все материалы, встроенные в MVC, кажутся бесполезными, такими как роли и аутентификация. Например, атрибуты [Авторизация] и безопасность; вам придется сворачивать самостоятельно.

  • Все ваши вызовы API потребуют информации о безопасности, и вам придется разработать систему токенов и многое другое.

  • Вам нужно будет написать полные API-вызовы для каждой отдельной функции, которую ваша программа когда-либо сделает. Практически каждый метод, который вы хотите реализовать, должен быть запущен API. Получить /обновить /удалить для каждого пользователя, а также вариант для каждой другой операции, например, обновить имя пользователя, добавить пользователя в группу и т. Д. И т. Д., И каждый из них будет отличным вызовом API.

  • Вы теряете всевозможные инструменты, такие как интерфейсы и абстрактные классы, когда речь идет о API. Например, WCF имеет очень незначительную поддержку интерфейсов.

  • У вас есть метод, который создает пользователя или выполняет некоторую задачу. Если вы хотите создать 50 пользователей, вы можете просто называть их 50 раз. Когда вы решите использовать этот метод в качестве API, ваш локальный веб-сервер может с ним подключаться named-pipes, и никаких проблем - ваш настольный клиент тоже может его поразить, но внезапно ваше массовое создание пользователей будет забивать API через Интернет в 50 раз, что не является Нехорошо. Поэтому вам нужно создать массовый метод, но на самом деле вы просто создаете его для настольных клиентов. Таким образом, вы в конечном итоге должны: a) изменить свой API на основе того, что интегрируется с ним, и вы не можете просто напрямую интегрироваться с ним, б) сделать гораздо больше работы для создания дополнительной функции.

  • YAGNI . Если вы специально не планируете писать два одинаково функционирующих приложения, например, один веб-сайт и одно приложение Windows, это огромное количество дополнительных разработок.

  • Отладка намного сложнее, если вы не можете пройти через сквозной интерфейс.

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

  • Наверное, еще несколько причин, которые находятся у меня на голове.

Мне просто кажется, что, если вам действительно не нужны два одинаковых приложения, тогда это действительно не стоит. Я никогда не видел приложение ASP.NET, построенное таким же образом: вам придется писать два отдельных приложения (API и ваш код), а также управлять ими обоими версиями (если ваша пользовательская страница получает новое поле, d необходимо обновлять API и ваш код потребления одновременно, чтобы не было никаких негативных эффектов или лишних усилий, чтобы сохранить его надежным).


Изменить: некоторые отличные ответы, действительно начинающие хорошо понимать, что все это значит сейчас. Итак, чтобы расширить мой вопрос, как бы вы структурировали приложение MVC для выполнения этой структуры API?

Например, у вас есть веб-сайт, на котором отображается информация о пользователе. В разделе MVC у вас есть:

View - (CS) HTML-страница, отображающая UserViewModel Контроллер - вызывает GetUser () и создает UserViewModel, который он передает в представление Класс менеджера (ваш API), который имеет метод GetUser.

Контроллер делает GetUser (), но вы также хотите использовать настольное приложение. Это означает, что ваш GetUser должен быть открыт через какой-то API. Возможно, вам понадобится TCP-соединение, либо WCF, либо, возможно, Remoting. Вы также хотите, чтобы мобильное приложение было RESTful, так как постоянные соединения являются flaky.

Так было бывы затем пишете API для каждого из них, веб-службу WCF, которая имеет метод GetUser (), и код просто возвращает return new UserManager().GetUser()? И метод mvc 4 web api, который делает то же самое? Продолжая ссылаться на GetUser непосредственно в вашем методе контроллера MVC?

Или вы выберете решение, которое будет работать для всех трех (служба веб-api REST), и постройте все на этом, поэтому все три приложения совершают вызовы API (mvc-теги, на локальный компьютер).

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


Изменить 2: после прочтения большего количества материалов я добавил комментарий ниже, который, я думаю, может объяснить это. Я думаю, что вопрос - это немного сложный вопрос. Если вы напишете свой back-end, как API, я смутился, думая, что должен быть один веб-сервис, который все (приложение mvc, настольное приложение, мобильное приложение) призывает делать вещи.

Я пришел к выводу, что то, что вы действительно должны сделать, это убедиться, что ваш уровень бизнес-логики правильно развязан. Если посмотреть на мой код, я сделаю это уже - контроллер вызовет GetUser() в менеджере, а затем создаст из него модель представления для рендеринга с помощью представления. Так что, бизнес-логический уровень - это API. Если вы хотите вызвать его из настольного приложения, вам нужно написать что-то вроде службы WCF, чтобы облегчить вызов. Даже при наличии WCF-метода, называемого GetUser(), который содержит код return MyBusinessLayer.GetUser(), будет достаточно. Таким образом, API - это бизнес-логика, а WCF /web api и т. Д. - всего лишь фрагменты кода, позволяющие внешним приложениям называть его.

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

Надеюсь, эта интерпретация верна. Спасибо за все обсуждения /комментарии, которые он создал.

304 голоса | спросил SLC 25 J0000006Europe/Moscow 2015, 13:12:00

14 ответов


268

Да, вы должны.

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

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

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


Изменить: ОК. Я вижу вашу проблему. Вы рассматриваете API как удаленную библиотеку. Это не. Подумайте об услуге как об услуге предоставления данных. Вы вызываете службу для получения данных, а затем выполняете операции с этими данными локально. Чтобы определить, зарегистрирован ли пользователь, вы вызываете «GetUser», а затем смотрите, например, значение 'logged on'. ( YMMV с этим примером, конечно).

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

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

Отладка также очень проста - вы можете полностью протестировать API в отдельности, поэтому вам не нужно отлаживать его (и вы можете отлаживать сквозной интерфейс, Visual Studio может присоединяться к нескольким процессам одновременно).

Такие вещи, как дополнительная работа по обеспечению безопасности, - это хорошо. В настоящее время, если вы связываете весь код с вашим сайтом, если хакер получает доступ к нему, он также получает доступ ко всему, включая БД. Если вы разделите его на API, хакер может сделать очень мало с вашим кодом, если они также не взломают слой API тоже, что будет невероятно сложно для них (когда-либо задавались вопросом, как злоумышленники получают обширные списки всех пользователей сайта или деталей cc? они взломали ОС или веб-сервер, и у него было прямое соединение с БД, где они могли легко запускать «select * from users»).

Я скажу, что я видел много веб-сайтов (и клиент-серверных приложений), написанных так. Когда я работал в индустрии финансовых услуг, никто никогда не писал сайт «все-в-одном», отчасти потому, что это слишком большой риск для безопасности, а отчасти потому, что много разработок - это довольно графический интерфейс для стабильной (то есть старой) обработки данных на заднем плане системы. Легко разоблачить систему DP как веб-сайт, используя архитектуру стиля обслуживания.

2nd Edit: Некоторые ссылки на тему (для OP):

Обратите внимание, что, говоря об этом в контексте веб-сайта, веб-сервер следует рассматривать как уровень представления, потому что клиент вызывает другие уровни, а также потому, что он создает представления пользовательского интерфейса, которые отправляются в браузер для рендеринга. Это большой вопрос, и есть много способов разработать ваше приложение - ориентированное на данные или ориентированное на домен (я, как правило, считаю, что центр сайта «чище», но YMMV ), но все сводится к тому, чтобы придерживаться логического уровня между вашим клиентом и вашей БД. Это немного похоже на MVC, если вы считаете, что средний, API, уровень эквивалентен вашей модели, только модель не является простой оболочкой для БД, она богаче и может делать гораздо больше (например, агрегировать данные из 2 источников данных, - обрабатывать данные в соответствии с API, кэшировать данные и т. д.):

ответил gbjbaanb 25 J0000006Europe/Moscow 2015, 13:18:25
83

Вы не можете избежать создания API . Даже если вы создадите «просто веб-сайт», ему все равно нужно будет получить свои данные из вашего бэкэнда. Однако вы решили сделать это, это ваш de facto API.

Зная это, реальный вопрос заключается не в том, нужно ли создавать API, но как его создать . Вы можете сделать это «на лету» как объект ad hoc , и, действительно, многие веб-сайты построены именно таким образом, или вы можете тщательно спроектировать его для использования в других контекстах. В этом контексте становится совершенно ясно, что ваш коллега прав: сначала вы должны сделать API, а затем построить свой сайт поверх него.

Тем не менее, это приводит к некоторым проблемам, как вы указываете. Чтобы обратиться к ним:

  

Это слишком абстрактно, чтобы запускать бэкэнд с API. Вы пытаетесь сделать его слишком гибким, что сделает его неуправляемым беспорядком.

Это зависит от того, как вы это делаете. Поскольку Джордж Пюля указывает в своем превосходном тексте Как решить его , часто" более общая проблема может быть проще решить ". Это называется Парадокс изобретателя . В случае программирования он часто работает путем разделения проблем: ваш бэкэнд больше не должен заботиться о формате данных, которые он вставляет и вынимает, и поэтому его код может быть намного проще. Ваши анализаторы данных и средства визуализации больше не должны беспокоиться о том, что происходит с создаваемыми ими данными, поэтому они также могут быть проще. Все это работает, разбивая код на более управляемые куски.

  

Все материалы, встроенные в MVC, кажутся бесполезными, такими как роли и аутентификация. Например, атрибуты [Авторизация] и безопасность; вам придется сворачивать самостоятельно.

Я признаюсь, что мне очень трудно сочувствовать людям, которые отказываются изучать свои инструменты. Просто потому, что вы не понимаете, что их использование не означает, что они бесполезны, и это, конечно же, не означает, что вы должны катить свой собственный . Наоборот; вы не должны запускать свои собственные инструменты до , вы понимаете альтернативы, так что вы можете быть уверены в том, что будете решать те же проблемы, что и они (даже если только по-своему).

Рассмотрим Линус Торвальдс , который наиболее известен тем, что пишет Linux , но также написал git : теперь одна из самых популярных систем управления версиями в мире. Одним из движущих факторов в его дизайне было глубокое противостояние Subversion (еще один чрезвычайно популярный VCS и, возможно, самый популярный в то время git был написан); он решил взять все, что мог сделать Subversion, и в какой бы то ни было мере это могло решить эти проблемы по-разному. Чтобы сделать это, он должен был стать экспертом по Subversion в своем собственном праве , чтобы он мог понять одни и те же области проблем и принять другой подход.

Или, в процессе изучения ваших инструментов, вы можете обнаружить, что они полезны как есть, и их не нужно заменять.

  

Все ваши вызовы API потребуют информации о безопасности, и вам придется разработать систему токенов и многое другое.

Да. Вот как это должно быть.

  

Вам нужно будет написать полные API-вызовы для каждой отдельной функции, которую ваша программа когда-либо будет делать. Практически каждый метод, который вы хотите реализовать, должен быть запущен API. A Получить /Обновить /Удалить для каждого пользователя, а также вариант для каждой другой операции, например, обновить имя пользователя, добавить пользователя в группу и т. Д. И т. Д., И каждый из них будет отдельным вызовом API.

Не обязательно. Здесь используются архитектуры, такие как REST . Вы определяете ресурсы, с которыми работает ваше приложение, и те операции, которые имеют смысл применять к этим ресурсам, а затем вы их реализуете, не беспокоясь о других .

  

Вы теряете все виды инструментов, таких как интерфейсы и абстрактные классы, когда речь заходит о API. Такие вещи, как WCF, имеют очень слабую поддержку интерфейсов.

Наоборот, интерфейсы становятся намного важнее, когда вы используете API, а не менее . Они выходят в представлениях, в которые вы их воплощаете. Большинство людей в настоящее время определяют формат JSON дляэто, но вы можете использовать любой формат, который вы хотите, до тех пор, как вы его хорошо укажете. Вы передаете результаты своих вызовов в этот формат на бэкэнд и анализируете его во все, что хотите (вероятно, такой же тип объекта) на интерфейсе. Накладные расходы небольшие, а гибкость огромна.

  

У вас есть метод, который создает пользователя или выполняет некоторую задачу. Если вы хотите создать 50 пользователей, вы можете просто называть их 50 раз. Когда вы решите использовать этот метод в качестве API, ваш локальный веб-сервер может с ним подключаться named-pipes, и никаких проблем - ваш настольный клиент тоже может его поразить, но внезапно ваше массовое создание пользователей будет забивать API через Интернет в 50 раз, что не является Нехорошо. Поэтому вам нужно создать массовый метод, но на самом деле вы просто создаете его для настольных клиентов. Таким образом, вы в конечном итоге должны: а) изменить свой API на основе того, что интегрируется с ним, и вы не можете просто напрямую интегрироваться с ним, б) сделать гораздо больше работы для создания дополнительной функции.

Создание массовой версии существующего метода вряд ли я бы назвал «намного больше работы». Если вас не волнуют такие вещи, как атомарность, метод массовых вычислений может оказаться не более чем тонким интерфейсом для оригинала.

  

YAGNI . Если вы специально не планируете писать два одинаково функционирующих приложения, например, один веб-сайт и одно приложение Windows, это огромное количество дополнительных разработок.

Нет, Яни (тебе это уже нужно). Я изложил это, как указано выше. Вопрос только в том, сколько проектных работ нужно вложить в него.

  

Отладка намного сложнее, если вы не можете пройти через сквозной интерфейс.

Почему бы вам не перешагнуть через конец?

Но, к тому же, возможность анализировать данные, идущие взад-вперед в легко узнаваемом формате, который отсекает весь дисплей, имеет тенденцию делать отладку проще , а не сложнее.

  

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

REST разрешает это, работая над полными объектами ( resources , чтобы использовать термины теории REST), а не отдельные свойства объектов . Чтобы обновить имя пользователя, вы ПОЛУЧИТЕ пользовательский объект, измените его имя и отпустите пользователя. Вы можете внести другие изменения одновременно с изменением имени пользователя. Более общая проблема становится легче решить, потому что вы можете устранить все эти индивидуальные вызовы для обновления отдельных свойств объекта: вы просто загружаете его и сохраняете.

В некотором роде это не похоже на архитектуры RISC на аппаратной стороне. Одним из ключевых различий между RISC и CISC (его предшественником) является то, что архитектуры CISC, как правило, включают в себя многие инструкции, которые работают непосредственно в памяти, в то время как архитектуры RISC имеют тенденцию работать главным образом в регистрах: в чисто RISC-архитектуре единственными операциями в памяти являются LOAD (копирование чего-то из памяти в регистр) и STORE (берут значение из регистра и помещают это в память).

Вы подумали бы, что это означало бы еще много поездок из регистров в память, что замедлит работу машины. Но на практике часто происходит обратное: процессор (клиент) делает больше работы между поездками в память (сервер) , и именно здесь происходит ускорение.

Короче говоря: ваш коллега прав. Это путь. В обмен на небольшую авансовую работу он значительно упростит код для вашего веб-сайта и , обеспечивающий лучшую интеграцию с другими веб-сайтами и приложениями. Это цена, которую стоит заплатить.

Дальнейшее чтение:

  1. REST API Design - Моделирование ресурсов
ответил The Spooniest 26 J0000006Europe/Moscow 2015, 15:39:49
61

Я знаю, что микросервисы - это все ярость прямо сейчас, но они не всегда стоят того. Да, слабосвязанный код - цель. Но это не должно происходить за счет более болезненного цикла разработки.

Хорошей серединой было бы создание отдельного проекта данных в вашем решении. Проект данных будет библиотекой классов .NET. Ваш проект ASP.NET MVC затем добавит ссылку на библиотеку данных, и все модели будут извлечены из проекта данных. Затем, когда пришло время создать настольное или мобильное приложение, вы можете ссылаться на тот же код. Так что это не официальный API, но он будет функционировать как один. Если вы хотите сделать его доступным как API, вы можете создать простой веб-проект, который будет действовать как обертка в проекте данных.

Microsoft продвигает эту концепцию, которую они называют переносимыми библиотеками классов .

ответил fotijr 25 J0000006Europe/Moscow 2015, 19:10:54
34

Нет, вы не должны . Если у вас нет немедленных планов по созданию альтернативных интерфейсов (например, мобильных или настольных приложений или отдельного веб-приложения), которые обращаются к одному и тому же серверу, то вам не следует вводить уровень веб-сервиса. YAGNI .

Свободная связь всегда желательна (наряду с высокой степенью сцепления), но это принцип проектирования и не означает, что вам нужно физически разделять объекты на разных серверах! И плохо спроектированный API сервисов может создавать жесткую связь между границами сервера, поэтому наличие API не гарантирует свободную связь.

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


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

ответил JacquesB 25 J0000006Europe/Moscow 2015, 19:04:26
29

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

Чтобы нарисовать цифру, я бы оценил, что проект, о котором я упоминал выше, стоит на 20% больше из-за этого подхода. Вы не описываете, какой тип проекта вы работаете над какой компанией вы работаете, но если вы начинаете строить свой продукт, что дополнительная стоимость может быть разницей между доставкой нескольких дополнительных функций, которые делают ваш продукт успех.

Другая причина не в том, чтобы, по крайней мере, не универсально, в том, что если или когда вы решите создать этот второй интерфейс, редко существует один к одному сопоставление функций. Например, если вы создаете мобильное приложение, у них меньше возможностей. Это означает, что некоторые из ваших методов API никогда не будут использоваться повторно. Поэтому компромисс с вашим коллегой может заключаться в том, чтобы решить между вами наиболее важные /критические вызовы и добавить их в API и использовать более традиционные методы для всего остального.

Еще один момент, который следует учитывать, заключается в том, что ваш коллега говорит, что вы не сможете повторно использовать существующий код, что неверно, если у вас есть разделение вашей бизнес-логики. Вам просто нужно создать оболочку тонких веб-сервисов вокруг ваших внутренних API-интерфейсов, что не является особенно важной задачей. Было бы наивно думать, что вы могли бы повторно использовать уровень веб-сервиса для другого внешнего интерфейса в любом случае без каких-либо изменений.

ответил Ian Newson 25 J0000006Europe/Moscow 2015, 18:13:13
21

Это зависит от типа приложения и типа рынка, в котором вы находитесь.

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

Я расскажу из личного опыта. Я был тем, кто решил взять кодовую базу, в которой я работаю в этом направлении еще в 2007 году. Эта кодовая база находится где-то порядка миллиона строк кода, половина из которых является кодом сервера, скрытым за огромным количеством веб-службы API, другая половина - это флотилия клиентов, настольные родные, настольные, мобильные, серверные и т. Д. Это решение не было без его недостатков, но с 20/20 задним числом я могу сказать, что я сделаю это снова , Позвольте мне указать на некоторые из компромиссов.

Преимущества

  • Гибкость . Будь то запрос на создание мобильного приложения для увеличения рабочего стола или запрос на интеграцию с внутренним интерфейсом SAP, все становится проще, если у вас уже есть API для вызова. Когда вы получите достаточное количество этих запросов, вы органично перейдете к API, и единственный вопрос заключается в том, есть ли у него стандартная веб-служба или он является внутренним API, в котором веб-службы настроены индивидуально.
  • Масштабируемость (команды). В нашем случае у нас есть много разных групп разработчиков, которые строятся поверх этого API. У нас даже есть специальные команды API, которые разговаривают с разными группами, суммируют потребности и строят из него универсальный API. Это дошло до того, что нам даже не сказали, что люди строят вещи поверх API, и не все, кто это делает, работают для нашей компании.

  • Безопасность. Четкое разделение между небезопасными и безопасными частями вашей кодовой базы полезно для обоснования безопасности. Смешение пользовательского интерфейса и внутреннего кода, как правило, путают вопросы.

Компромиссы

  • Гибкость . Вы должны выполнить работу, чтобы «правильно» создать что-то в API. Невозможно быстро запустить запрос БД изнутри пользовательского интерфейса, чтобы решить определенную проблему. Кроме того, API, которые на самом деле могут повторно использоваться, должны учитывать так много случаев использования, что быстрое решение обычно является неправильным решением. API становится менее гибким для развития, тем более, что там так много клиентского кода (мы по этой причине переходим к API с версиями).
  • Начальная скорость разработки. Менее медленнее разрабатывать API-интерфейс, без каких-либо сомнений. Вы только выиграете его, когда у вас будет достаточно клиентов, построенных поверх API. Но тогда вы обнаружите, что вам нужны 3 разных клиентских реализации, прежде чем ваш API превратится в достаточно общий. Мы обнаружили, что большинство наших первоначальных проектов API были неправильными, и нам пришлось решительно пересмотреть наши рекомендации по созданию веб-сервисов.

Красные сельди

Вы упомянули о них. На практике они практически не имеют значения.

  • Абстракция . Ваш API становится достаточно абстрактным, чтобы охватить все варианты использования, которые ваш продукт должен обслуживать, и не более того. Даже без веб-служб вы либо будете иметь внутренний API, который делает это, либо имеет много дубликатов кода. Я предпочитаю абстракцию над дублированием.
  • Отказ от стека MVC на стороне сервера. В эти дни почти каждая система через некоторое время нуждается в мобильном приложении. Когда вы затем создаете веб-службы для обслуживания этого мобильного приложения, вам все равно придется выяснить, как делать аутентификацию и авторизацию в контексте API. На самом деле это меньше работает, когда у вас есть только один способ сделать это, как вы это делаете в своих веб-сервисах.

  • Массовые операции. Обычно решается путем создания массового API, который запускает фоновое задание и возвращает идентификатор задания для запроса статуса. Это не большая сделка.

  • Debugging. Я обнаружил, что в целом стало немного легче устранить неисправность системы. Вы по-прежнему можете установить точки останова как в интерфейсе, так и на внутреннем коде, поэтому на практике это не так сложно сделать, и вы получаете возможность создавать автоматические тесты api и настраивать api для мониторинга производственных систем.

  • Множество независимых операций. Это вопрос того, как вы разрабатываете вещи. Если вы настаиваете на наличии чистого CRUD API, то да, вы будете страдать от этой проблемы. Но наличие некоторых API CQRS для дополнения, как правило, является хорошей идеей, и если вы удостоверились, что у вас есть внутренний API, для которого эти услуги являются интерфейсом, то вы можете легко повторно использовать этот внутренний API для создания служб для этих конкретных сценарий х.

В резюме

В системе, которая используется в достаточно разных контекстах, API будет естественно развиваться, поскольку это самый простой способ удовлетворить все потребности. Но, безусловно, есть случай с YAGNI. Есть компромиссы, и это не имеет смысла, пока это не имеет смысла. Ключевым моментом является не догматичность и неприятиек различным подходам в архитектуре для удовлетворения меняющихся потребностей продукта.

ответил Joeri Sebrechts 26 J0000006Europe/Moscow 2015, 11:59:03
10

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

В SOA есть некоторые существенные преимущества, которые я попытаюсь подсчитать:

Масштабируемость

Поскольку ваш задний конец развязан, ваш передний конец становится просто набором шаблонов, даже плоских файлов. Плоские файлы чрезвычайно быстры и дешевы для обслуживания любого CDN. Они могут быть минимизированы и предварительно скомпилированы в статический HTML, а затем заполнены клиентскими данными.

Ваш API должен оставаться последовательным, но его можно поменять на более быструю технологию, не разбирая ваш стек, если вы перерасти свою существующую технологию. Например, вы можете переделать его в Go. Вы можете перестроить его по частям и распределить нагрузку на серверы. Пока интерфейс остается тем же, технология абстрагируется.

Тестируемость

MVC обычно начинается чисто, но на практике контроллеры редко остаются сосредоточенными на одном ресурсе. Чем больше вещей, которые ваши методы контроллера делают, тем менее подвержены тестированию.

API обходит эту проблему. Каждый вызов API вытягивает ресурс и обслуживает его. Очистить и проверить.

Гарантированное разделение проблем

Ваш передний и задний концы полностью разведены. Вы можете предоставить интерфейс другому разработчику или дизайнеру. Это MVC, переведенный на другой уровень. Я уверен, что вы не захотите отказаться от MVC. SOA - это MVC, но более того.

Downsides

Есть, конечно, некоторые недостатки. Монолит часто быстрее подходит. Возможно, это то, к чему вы привыкли. Он может лучше вписаться в ваш стек. Ваши инструменты могут быть оптимизированы для создания монолита.

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

ответил superluminary 26 J0000006Europe/Moscow 2015, 19:23:06
7

Здесь есть много хороших ответов, поэтому я просто добавлю опыт внедрения.

Это как я делаю:

  • Создайте уровень доступа к базе данных, который обрабатывает взаимодействие всех и только с БД (обычно используется ручная SQL для скорости и управления, без ORM) . Вставка, обновление, удаление, выбор ...
  • Создайте interface (virtual class), который предоставляет /выполняет функции API, которые мне нужны. Они будут, когда они будут реализованы, использовать высокоспециализированные функции DBAL для достижения результатов. Это также помогает мне внедрять API на уровне компилятора, поэтому я уверен, что реализация Server + API имеет все встроенные функции.
  • Создайте второй слой, который реализует интерфейс (это фактический API) и устанавливает ограничения безопасности. Вы также взаимодействуете с внешними API.
  • Веб-сайт будет использовать второй слой непосредственно (для производительности) , не выходя из удаленного API (например, SOAP, JSON) .
  • Создается автономный сервер, который реализует интерфейс и предоставляет второй слой как фактический API с открытым доступом для внешних клиентов рабочего стола /мобильных клиентов (доступ без доступа к веб-сайтам) . Все, что он делает, это декодировать запросы и кодировать ответы и управлять /отключать клиентов. Он также поддерживает возможности pushback для массового уведомления клиентов о событиях, генерируемых другими подключенными одноранговыми узлами (функциональность, которую обычно не требуется веб-сайту)
  • .

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

Вы никогда не подключаете веб-сайт к серверу API для настольных компьютеров /мобильных устройств (если ваш сайт не является AJAX и работает на JSON) . Но если сайт отображает динамический контент в разметке, переход через промежуточный API позволит вам повысить производительность. Веб-сайт должен быть быстрым! Доступ к удаленному клиенту может быть немного медленнее.

PS : Да, обслуживание немного сложнее, так как больше колес работает вместе, но в конечном итоге это проще. Поэтому, если ваш проект должен жить некоторое время и немного сложный, всегда есть API. Кроме того, гораздо проще протестировать каждый слой самостоятельно.

ответил CodeAngry 29 J0000006Europe/Moscow 2015, 08:40:55
6

Точка спора не является, если вы должны использовать API, но что такое «API» на самом деле. Единственной альтернативой использованию разработанного API является использование API, который представляет собой случайный беспорядок кода. Вы пишете, что API делает вещи «слишком гибкими», что, в свою очередь, делает вещи неуправляемыми. Это указывает на полное и полное непонимание того, что такое API. Если это недоразумение не разделено между вами и вашим коллегой, вы потратили много времени, обсуждая совершенно разные вещи.

Не используя четко определенный API, вы можете делать все, что хотите. По определению это самый гибкий вариант. Кроме того, по определению «делать то, что вы хотите» по-прежнему является API. Задача только API - удалить гибкость. При удалении гибкости хороший API поощряет пользователя делать похожие вещи аналогичным образом.

Конечно, плохой API может обеспечить слишком большую или слишком небольшую гибкость или даже в то же время. Действительно плохо разработанный API может убить проект даже быстрее, чем подход «ничего». Тем не менее, лучше всего просто иметь компетентных программистов, которые разрабатывают и развивают API вместе с вашим приложением.

Пример

  

â € ¢ Множество независимых операций, для которых потребуется много   например, некоторый код может получить текущий пользователь, проверьте   пользователь входит в роль администратора, получает компанию, которой принадлежит пользователь.   чтобы получить список других участников, отправьте им все электронное письмо. Это было   требуют много вызовов API или написания индивидуального метода   задача, которую вы хотите, где единственным преимуществом метода на заказ будет скорость   но недостатком было бы негибким.

Количество вызовов API, которые потребуются для достойного API, вероятно, будет 1. Да, это негибко, но зачем вы хотите, чтобы он был гибким?

ответил Peter 26 J0000006Europe/Moscow 2015, 12:59:22
4
  

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

Ну, а? Если нет, то это довольно неуместное утверждение.

Я бы сказал, если вы планируете создать приложение new в 2015 году, то серьезно посмотрите на что-то с пользовательским интерфейсом, который включает в себя API-страницы, а не серверные HTML-страницы. Существуют очевидные затраты, но также очевидные выгоды.

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

ответил RemcoGerlich 26 J0000006Europe/Moscow 2015, 11:12:14
4

Краткая версия: Контроллер эффективно использует API независимо от того, что; хотя ASP.NET может скрывать это.

Более длинная версия:

Подумайте о базовом веб-приложении MVC, в котором содержится информация о пиве и, возможно, вам продается. Как выглядят маршруты?

/sign_in
/sign_out
/beer
/beer/{beer_name}
/order
/order/{order_number}

В обычном веб-приложении есть, вероятно, несколько вспомогательных маршрутов, например:

/beer/new
/beer/{beer_name}/edit
/beer/{beer_name}/delete
/order/new
/order/{order_number}/edit
/order/{order_number}/delete

В веб-API они не требуются, поскольку они выводятся из метода HTTP.

Учитывая указанную выше симметрию, я считаю, что это довольно убедительный случай, когда ваш API и контроллер настолько близки, что они могут быть одинаковыми.

После некоторого копания я решил, что это может быть для вас в зависимости от того, какую версию ASP.NET вы используете. Более старый MVC 5 и до этого не имеют соглашений и интерфейса для надежной унификации двух реализаций. В старых версиях Web App возвращает заполнение представления, тогда как API дает HttpResponse. В любом случае они генерируют семантически

Если вы используете MVC 6, вы получаете оба в классе унифицированного контроллера, который может быть умным в отношении того, что он возвращает. Я не нашел хорошего кода примера ASP для этой модели, но я нашел некоторый код Rails с тем же шаблоном. Рассмотрите этот контроллер для «любит» из проекта Диаспоры , Каждый метод контроллера имеет маршруты, определенные «находчивым соглашением» здесь это значение для LCRUD в API.

Если вы читаете реализации, тем не менее, каждый может ответить на HTML, Mobile HTML или JSON. Это, в сочетании с конвенцией для поиска мнений, полностью унифицирует веб-приложение и веб-API. Вы также заметите, что не все методы фактически обеспечивают каждый ответ (что имеет смысл, так как пользовательский интерфейс может требовать методов, которые API не будет, и наоборот).

Это несоответствие импеданса, потому что вид ASP.NET вычислял все это позже, в то время как Rails некоторое время воспринимает симметрию и делает ее очень понятной.

Спекуляция:

Ваш коллега, вероятно, прав и не прав, в зависимости от того, какую версию ASP вы используете. В старой версии MVC разница между API и App, вероятно, сделала «лучшей практикой» для создания API-интерфейса, потому что модель ASP.NET действительно не позволяла использовать повторное использование кода там.

С новым, имеет смысл использовать унифицированный код, потому что стало проще повторно использовать код с базовым классом унифицированного контроллера.

В любом случае, Controller фактически является API.

ответил Jayson 30 J0000006Europe/Moscow 2015, 13:22:57
2

Когда я начал свою карьеру в 2006 году, этот тип архитектуры был в ярости в мире .NET. Я работал над тремя отдельными проектами, задуманными в середине 2000-х годов, с веб-сервисом между уровнем бизнес-логики и веб-интерфейсом. Конечно, в наши дни веб-сервисы были SOAP, но это все та же архитектура. Предполагаемые преимущества заключались в возможности переключения на передний или задний сервер и даже на разработку настольной программы. В конечном итоге YAGNI оказался правдой. Я никогда не видел ничего подобного. Все это время я видел только стоимость разделения проекта таким образом. Я даже закончил разрывать веб-сервис из одного из проектов (потребовалось полгода, чтобы удалить его шаг за шагом, делая другие вещи), и вся команда была счастлива. Я никогда не пробовал этот подход с тех пор, и я не буду, если не будет задана очень конкретная причина. 5-летний опыт использования этой архитектуры научил меня, что мне это не понадобится, и никакое количество экспертов, рассказывающих мне обо мне, не убедит меня в этом. Только проект, в котором я нуждаюсь, может это сделать.

Теперь, когда я говорю, я очень стараюсь развить слой между бизнес-логикой и контроллерами /презентаторами. Например, у меня есть сервисный уровень, я никогда не выставляю запросы, не использую интерфейсы для всех своих сервисов и не добавляю их в контроллеры с IoC. Если мне понадобится веб-сервис в моей архитектуре, я смогу представить его с разумной стоимостью. Я просто не хочу платить эту стоимость заранее.

Также мне очень нравится идея микросервисов, но я понимаю, что микросервисы означают вертикальные модули, а не горизонтальные слои. Например, если вы создаете facebook, функция чата будет отдельной службой, развернутой отдельно на своих серверах и т. Д. Это тип независимых сервисов, которые я бы рекомендовал.

ответил Stilgar 30 J0000006Europe/Moscow 2015, 15:56:22
2

Третьи стороны будут использовать его? Да, вы должны .

Вы планируете повторно использовать его в недалеком будущем? Да, вы должны.
Вы будете третьей стороной , имеющий документально подтвержденный или документируемый или API-интерфейс, пригодный для использования , предоставит вам возможность повторного использования и модульности.

Вы в спешке? Нет, не следует.
Рефакторинг впоследствии проще и быстрее, чем большинство методологий, и учителя предсказывают и рассказывают. Более важно иметь что-то, что работает (даже с плохим внутренним дизайном, поскольку оно может и будет реорганизоваться), чем вообще ничего не делать. (но с невероятным внутренним дизайном, wohoo)

Интерфейс может никогда не видеть свет дня из-за причин? Да, вы должны .
Я добавил эту причину, потому что, ну, это случилось со мной много.
И, по крайней мере, я остался с моими компонентами для повторного использования и перераспределения и т. Д.

ответил ZJR 29 PM00000070000005231 2016, 19:29:52
1

Здесь есть хорошие ответы. Я отправляю это как частичный ответ; возможно, было бы лучше в качестве комментария. Однако придерживаться того же комментария на многочисленных сообщениях не очень хорошо.

Нельзя утверждать, что YAGNI является причиной не создания API.

API - это естественная и логическая конечная точка тестирования. Таким образом, с 0-го дня существуют приложения два , которые используют API: пользовательский интерфейс и набор для тестирования. Один предназначен для людей, другой предназначен для машин. Они обязательно разные. Тестирование внешнего поведения - это совсем другая задача, чем тестирование поведения на заднем плане. Таким образом, методы и, возможно, инструменты, совершенно разные. API позволяет использовать лучший инструмент для работы. Кроме того, с разделением, предоставляемым API, передние тестеры не должны тестировать функциональные возможности.

API также помогает сохранить интерфейсные кодеры вне проблем внутреннего кодера и наоборот. Это очень разные навыки в нашей компании; API позволяет нам сосредоточиться там, где мы сильней.

ответил Tony Ennis 4 J000000Saturday15 2015, 17:29:00

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132