Разделение фронтенда и бэкенда не является чем-то новым, и практика разделения фронтенда есть везде. Тем не менее, некоторые исторические проекты по-прежнему неизбежно сталкиваются с различными проблемами при переходе от интегрированного веб-дизайна к раздельной архитектуре внешнего и внутреннего интерфейса. Из-за бесконечных проблем возникают даже командные вопросы.Интеграция хорошая, зачем разделять фронт и бэкенд?
Ведь дело не в том, что разделение на перед и зад нехорошо, просто оно может не подойти, или... дизайн-мышление не трансформировалось...
Универсальная веб-архитектура
Схематическая диаграмма архитектуры переднего и заднего разделительного полотна
Зачем разделять перед и зад?
Более реалистичный вопрос, чем зачем разделять фронтенд и бэкенд, это когда нужно разделять фронтенд и бэкенд, то есть сценарий применения разделения фронтенда и бэкенда.
Говоря об этой проблеме, я думаю о 2011 году, компания расширила команду Java на основе команды разработки .NET.Хотя две команды работают над разными продуктами, все еще существует много повторяющихся разработок, таких как я написал страницы, связанные с организацией, с помощью веб-страницы ASP.NET, и мне нужно снова написать ее с помощью JSP. В этом случае команда начала думать над решением: если фронтенд-реализация не имеет ничего общего с бэкенд-технологией, то часть рендеринга страницы может быть общей, а разные бэкенд-технологии должны реализовывать только бэкенд-технологию. -конечная бизнес-логика.
Фундаментальная проблема, которую должно решить решение, заключается в разделении данных и страниц. Технологии, отвечающие этому требованию, легко доступны: внешний интерфейс использует технологии, связанные со статическими веб-страницами, HTML + CSS + JavaScript, и вызывает бизнес-интерфейс, предоставляемый серверной частью, с помощью технологии AJAX. Внешний и внутренний интерфейс согласовывают метод интерфейса и предоставляют его через HTTP, а также единообразно используют глагол POST. Структура данных интерфейса реализована в XML, фронтенд jQuery очень удобен для парсинга XML, а бэкенд имеет больше инструментов для обработки XML... Позднее, в связи с появлением серверных библиотек JSON (таких как Newtonsoft JSON.NET, jackson, Gson и т. д.), интерфейсная обработка JSON также проще (JSON.parse()
а такжеJSON.stringify()
), замените структуру данных реализацией JSON.
Эта архитектура по существу является SOA (сервисно-ориентированной архитектурой). Когда серверная часть не предоставляет страницы, а только предоставляет данные и возможности бизнес-взаимодействия через веб-API, веб-интерфейс становится чисто клиентской ролью, которая принадлежит той же роли, что и приложения WinForm и мобильного терминала, и может быть объединена вместе. упоминается каквнешний интерфейс.以前的一体化架构需要定制页面来实现 Web 应用,同时又定义一套 WebService/WSDL 来对 WinForm 和移动终端提供服务。转换为新的架构之后,可以统一使用 Web API 形式为所有类型的前端提供服务。至于某些类型的前端对这个 Web API 进行的 RPC 封装,那又是另外一回事了。
Благодаря такой архитектурной трансформации передняя и задняя части фактически были разделены. Помимо других типов интерфейсов, здесь обсуждаются только веб-интерфейсы и серверные части. Из-за разделения веб-интерфейсу не нужно знать, какую технологию использует серверная часть при разработке, просто какой интерфейс предоставляет серверная часть, можно использовать для выполнения таких действий, как C#/ASP. .NET, Java/JEE, база данных... Все эти технологии можно игнорировать. Команда бэкенда .NET и команда Java также отделены от эстетического мышления, которое не имеет ничего общего с логикой, им не нужно сталкиваться с тонкими ограничениями дизайна интерфейса художника, а также им не нужно учитывать макет макета. страницу, думая о реализации логики. Просто займитесь логикой и данными, в которых вы разбираетесь.
После того, как интерфейс и сервер разделены, разработчики на обоих концах становятся более расслабленными.Поскольку технологии и бизнес более сфокусированы, эффективность разработки также повышается. Преимущества разделения постепенно стали очевидны:
1. Разделение обязанностей до и после
Внешний интерфейс, как правило, представлен с упором на вопросы, связанные с пользовательским интерфейсом, а внутренний — на бизнес-логику, обработку данных и постоянство. В случае четкого дизайна серверная часть должна отвечать только за алгоритмы бизнес-обработки, ориентированные на данные, и предоставлять API-интерфейсы для клиентской части по согласованию; а клиентская часть использует эти интерфейсы, чтобы нести ответственность. для пользовательского опыта.
2. Разделение передних и задних технологий
Фронтенду не нужно разбираться в технологии бэкенда, и ему все равно, какая технология используется для реализации бэкенда — для начала нужно знать только HTML/CSS/JavaScript, а бэкенду — только необходимо заботиться о внутренней технологии разработки, в дополнение к избавлению от проблем с изучением технологии внешнего интерфейса, даже изучение и исследование веб-инфраструктуры должны быть сосредоточены только на веб-API, а не на технологии MVC, основанной на просмотре страницы ( не сказать, что MVC не нужен, представление структуры данных интерфейсной части Web API тоже View), не нужно рассматривать особую сложную организацию и представление данных.
3. Разделение передней и задней части приводит к разъединению пользовательского опыта и бизнес-процессов.
Внешний интерфейс можно быстро пересмотреть в соответствии с потребностями пользователей в опыте в разные периоды, и серверная часть не оказывает на это никакого давления. Точно так же обновление бизнес-логики, выполняемое серверной частью, и изменение схемы сохранения данных, если интерфейс не затрагивается, интерфейс может не знать. Конечно, если изменения в требованиях вызывают изменения в интерфейсе, передняя и задняя части должны работать вместе для синхронизации информации.
4. Передняя и задняя части разделены, и дизайн на обоих концах можно уменьшить отдельно.
Серверная часть предоставляет только услуги API и не рассматривает вопрос рендеринга страницы. API, реализующий архитектуру SOA, может обслуживать различные внешние интерфейсы, а не только внешний веб-интерфейс, и может предоставлять набор сервисов, которые могут использоваться всеми сторонами; не зависит от серверной технологии, может быть развернут независимо, а может быть В ответ на гибридную архитектуру встраиваются различные «оболочки» (такие как Electron, Codorva и т. д.) для быстрой реализации многотерминальности.
Передняя и задняя архитектура разделения
Никакое техническое решение не является серебряной пулей.Разделение передней и задней части не только приносит пользу, но и приносит противоречия. На начальном этапе нашей практики, из-за относительно слабой силы фронтенд-команды и по соглашению, почти все бизнес-процессы разрабатываются и определяются бэкендом (первоначальной технической основой). обработки, часто обнаруживается, что определение интерфейса не соответствует процессу работы пользователя, слишком много асинхронных запросов AJAX и т. д. Ведь бэкенд-мышление и фронтенд-мышление все же разные — фронтенд-мышление больше склоняется к пользовательскому опыту, а бэкенд-мышление — к технической реализации бизнеса.
Кроме того, требования безопасности переднего и заднего разделения также немного различаются. Поскольку разделение передней и задней части по сути является архитектурой SOA, авторизацию также необходимо рассматривать в соответствии с архитектурой SOA. Метод Cookie/Session хоть и доступен, но он не особо подходит, условно говоря, больше подходит аутентификация на основе токена. Использование аутентификации на основе токенов означает, что аутентификационная часть серверной части должна быть переписана... Конечно, серверная часть не хочет переписываться, поэтому она пинает мяч во внешний интерфейс, чтобы передняя часть -end найти способ реализовать аутентификацию на основе Cookie/Session... Итак, интерфейс начинает жаловаться (трагедия)……
кто будет вести
Возникновение этих противоречий, в конечном счете, заключается в том, что конструкция недостаточно ясна. Нет сомнения, что в процессе разработки лидером должен быть архитектор или дизайнер. Однако в реальных сценариях архитекторы или дизайнеры часто являются разработчиками, поэтому их основной технологический стек будет сильно влиять на основную и второстепенную роли интерфейсной и серверной части во всем проекте. Где находится этот костяк, в какую сторону будет склоняться удобство разработки. Это плохое явление, но нам приходится иметь дело с этим статус-кво, и я считаю, что многие не слишком большие команды сталкиваются с подобными проблемами.
Если нет хорошей спецификации процесса, обычно передняя часть будет подвергаться большему количеству ролей, чем внутренняя (большинство прикладных проектов/продуктов, но не все случаи).
- Front-end разработчики будут находиться под непосредственным влиянием менеджера проекта/продукта или клиента: в этом месте должна быть кнопка, действие должно происходить так...;
- Передний конец также должен быть связан с художником - такой дизайн не прост в реализации, можно ли его изменить на это? Клиент требует, чтобы эта операция должна быть сделана, но этот дизайн не может этого сделать;
- Передняя часть также должна быть подключена к задней части, а для некоторых приложений даже несколько внутренних частей.
Другими словами, фронтенд может стать центром коммуникации проекта, поэтому ему больше подходит ведущая роль, чем бэкенду.
дизайн интерфейса
Интерфейс разделен на две части: реализация серверной службы и вызов внешнего интерфейса.Технология зрелая и не сложная, но сложность заключается в дизайне интерфейса. Как упоминалось ранее, между передней и задней частью будут некоторые противоречия. С точки зрения внешнего интерфейса основное внимание уделяется пользовательскому опыту, включая направление потока и соответствующую обработку пользователей во время бизнес-операций, а с точки зрения внутреннего интерфейса основное внимание уделяется целостности, эффективности и безопасности данных. . Противоречие заключается в том, что у обеих сторон разные заботы, информационная асимметрия и собственные интересы. В центре внимания решения этих противоречий находится дизайн интерфейса.
При проектировании интерфейса размер его детализации часто представляет размер внешних и внутренних рабочих нагрузок (не абсолютный, связанный с общей архитектурой). Если степень детализации интерфейса слишком мала, интерфейсу приходится иметь дело со многими вещами, особенно для различных асинхронных обработок.Если степень детализации слишком велика, возникнет высокая связанность, снижающая гибкость и масштабируемость.Работа непростая. На уровне бизнеса речь идет о конкретных продуктах, поэтому я не буду их здесь обсуждать. Здесь мы в основном обсуждаем немного технических вещей.
Формально веб-API можно определить как REST или RPC, если внешний и внутренний интерфейс согласованы и определены. Что еще более важно, с точки зрения входных параметров и выходных результатов лучше всего иметь относительно фиксированное определение с самого начала, что часто зависит от архитектуры внешнего интерфейса или используемой среды пользовательского интерфейса.
Формы данных общих параметров запроса следующие:
- Пара ключ-значение, используемая для QueryString в URL-адресе или полезной нагрузке POST и других методах.
- XML/JSON/..., обычно используемые для полезных данных, таких как POST, также могут передаваться с помощью multipart.
- ROUTE, полученный с помощью внутреннего URL-адреса анализа маршрутизации, обычно используемого в RESTful.
Формы данных ответа сервера разнообразны.Обычно полный ответ должен содержать как минимум три части: код состояния, сообщение и данные.
- Коды состояния, коды состояния HTTP или определенные атрибуты состояния в данных ответа
- Сообщение, обычно помещаемое в содержание ответа, как часть данных
- Данные, в зависимости от протокола интерфейса, могут быть в различных форматах, в настоящее время наиболее популярным является JSON.
Используем форму JSON на практике, изначально определяя такую форму
{
"code": "number",
"message": "string",
"data": "any"
}
code
Он в основном используется для направления передней части для выполнения некоторых специальных операций, таких как0
Указывает, что вызов API был успешным,非0
Указывает, что вызов не удался, где1
Указывает, что требуется вход в систему,2
Указывает, что авторизация не получена... Для этого определения после того, как внешний интерфейс получит ответ, он может выполнить некоторую рутинную обработку на уровне структуры приложения, например, когдаcode
для1
Когда всплывает окно входа в систему, чтобы попросить пользователя войти на текущую страницу, и когдаcode
для2
, появится всплывающее сообщение и ссылка, которая поможет пользователю получить авторизацию.
Видеть:Инкапсулированные вызовы API для моделей переднего и заднего разделения
Сначала это было нормально, пока интерфейсная среда не переключилась на jQuery EasyUI. Многие библиотеки пользовательского интерфейса, такие как EasyUI, поддерживают настройку URL-адресов данных для компонентов. Он будет автоматически получать данные через AJAX, но у него есть требования к структуре данных. Если вы все еще используете ранее разработанную структуру ответа, вам необходимо определить фильтр данных для компонента для обработки результата ответа.Таким образом, рабочая нагрузка по написанию фильтра и объявлению фильтра для компонента не мала. Чтобы уменьшить нагрузку на эту часть, мы решили изменить интерфейс.
Новый интерфейс представляет собой изменяемую структуру. Обычно он возвращает структуру данных, требуемую пользовательским интерфейсом. В случае ошибки он отвечает на структуру данных исходного типа:
{
"error": {
"identity": "special identity string",
"code": "number",
"message": "string",
"data": "any"
}
}
Для новой структуры данных ответа интерфейсной платформе нужно только определить, существует ли она.error
атрибут, если он существует, проверьте егоidentity
назначено ли свойству специальное значение (например, конкретный GUID), а затем использовать егоcode
а такжеmessage
Ошибка обработки свойства. Этот процесс оценки ошибок немного сложнее, но он может быть единообразно обработан интерфейсной структурой приложения.
Если используется интерфейс RESTful, некоторые коды состояния могут быть заменены кодами состояния HTTP, например, 401 означает, что требуется вход в систему, 403 означает, что авторизация невозможна, а 500 означает, что во время обработки программы произошла ошибка. Конечно, хотя коды состояния HTTP более совместимы со стилем RESTful, стили, отличные от RESTful, также могут вместо этого использовать коды состояния HTTP.error.code
.
Аутентификация пользователя
Существует много схем аутентификации. Например, Cookie / Session все еще выполнимо в некоторых средах, вы также можете использовать токен и OAUTH или JWT или даже реализовать аутентификацию на основе токена самостоятельно.
Схема аутентификации на основе cookie / сеанса
Традиционная схема аутентификации Cookie/Session невозможна, но есть некоторые ограничения. Если передняя и задняя части гомологичны, например, страница размещенаhttp://domain.name/
http://domain.name/api/
, в этом случае решение Cookie/Session, принятое исходным интегрированным веб-решением, может быть напрямую перенесено без какого-либо давления. Но если предварительная публикация и публикация API являются разными источниками, с этим методом сложно работать.
Затем в методе разработки, где интерфейс и сервер разделены, будь то этап разработки или этап выпуска, возможность использования разных источников составляет подавляющее большинство, поэтому схема аутентификации обычно использует схему, которая не имеет ничего общего с печеньем.
Схема аутентификации на основе OAuth
В настоящее время все открытые интерфейсы основных веб-сайтов представляют собой архитектуры SOA.Если эти открытые интерфейсы рассматриваются как поставщики услуг (серверы), а приложения, использующие эти открытые интерфейсы, рассматриваются как клиенты, то такое отношение, соответствующее разделению до и после:
前端 ⇌ 客户端
⇣
(基于 OAuth 的认证)
⇡
后端 ⇌ 服务端
Таким образом, схема OAuth, широко используемая в открытых интерфейсах, возможна для прямого разделения, но ее не так просто реализовать. Особенно с точки зрения безопасности, поскольку интерфейс полностью открыт, по сравнению со средой, где обычно реализуется OAuth (бэкенд⇌сервер), следует отметить, что при первой аутентификации используются не зарегистрированные AppID и AppToken, а пользователь. имя и пароль.
Схема аутентификации на основе токенов/JWT
Хотя эта программа размещена в конце, это решение в настоящее время является наиболее подходящим планом для передней и задней частей. Основываясь на программе сертификации Token, ранее проводились различные обсуждения, и JWT является относительно зрелым, и его также признает большинство людей. отjwt.ioJWT-реализации различных технологических стеков можно найти на сайте, к тому же он более удобен в применении.
Сказав это, все еще существует большая разница между решением JWT и ранее использовавшейся обработкой файлов cookie/сеансов, которая требует определенных затрат на обучение. Некоторые люди беспокоятся, что объем данных JWT слишком велик. Это действительно проблема, но железо не дорогое, да и 4G тоже начал входить в стадию безлимитного трафика.В общих приложениях особо внимания на эту проблему не нужно обращать.
Тест на переднее и заднее разделение
После того, как передняя и задняя части будут разделены, внешнее тестирование будет в основном основано на тестировании взаимодействия с пользователем и интеграционном тестировании, а внутреннее тестирование будет в основном состоять из модульного тестирования и тестирования интерфейса веб-API. По сравнению с интегрированным веб-приложением существует дополнительный уровень тестирования интерфейса, который может быть полностью автоматизирован.После завершения разработки теста можно в значительной степени контролировать бизнес-процессы и ошибки данных. Таким образом, рабочая нагрузка по интеграционному тестированию будет относительно простой и намного проще.
Работа по внешнему тестированию относительно не сильно облегчается, и передняя часть после разделения передней и задней части берет на себя первоначальную работу по интеграционному тестированию. Однако, если интеграционный тест выполняется в предположении, что веб-API правильный, рабочая нагрузка может быть значительно снижена, а вариант использования может быть сосредоточен только на экспериментальных проблемах внешнего интерфейса, таких как правильность рендеринга, правильность прыжок правильный, соответствуют ли действия пользователя требованиям, является ли точной информация о подсказке и так далее.
Для проверки достоверности пользовательского ввода эту часть работы можно даже полностью переложить на веб-API для обработки, когда время проекта ограничено. Независимо от того, разделены ли интерфейс и сервер, в веб-разработке существует консенсус: никогда не доверяйте интерфейсу! Поскольку серверная часть должна обеспечивать безопасность и достоверность данных, пропуск этого шага во внешней части не вызовет существенной угрозы для серверной части. Однако, если и фронтенду, и бэкенду необходимо проверить достоверность данных, это должно быть сделано строго в соответствии с документом, иначе легко получить несогласованную проверку данных между фронтендом и бэкендом. конец (это не проблема разделения между передней и задней частью, и у интегрированной архитектуры тоже есть эта проблема).
резюме
В целом, преимущества разделения спереди-назад очевидны. Однако при его реализации требуется новый способ мышления, а не мышление, основанное на оригинальном интегрированном методе веб-разработки. Открытый подход разделения между фронтом и бэком освобождает разработчиков от сложных комбинаций технологий, и каждый может больше сосредоточиться на своих областях знаний для разработки, но в то же время выдвигает более высокие требования к коммуникации между фронтендом и бэкендом. команды должны работать вместе, чтобы спроектировать относительно стабильный интерфейс веб-API (по сути, эта часть работы необходима независимо от того, разделены ли фронтенд и бэкенд, но фронтенд и бэкэнд Архитектура разделения концов требует для этого более высоких требований, и более четко требует, чтобы интерфейс не только существовал в памяти человека, но и документировался и сохранялся).