Совместная разработка интерфейсов и серверов с использованием правильной позиции GraphQL.

задняя часть внешний интерфейс API GraphQL
Совместная разработка интерфейсов и серверов с использованием правильной позиции GraphQL.

Источник контента:9 июня 2018 г. Чжоу Вэньюй, соучредитель Youshupai, выступил с речью «Использование GraphQL Stratup» на «Первой вечеринке GraphQL в Ханчжоу — синергетическая ценность, обеспечиваемая GraphQL и драйверами домена». IT big coffee сообщил, что как эксклюзивный видео-партнер, он был выпущен с разрешения организатора и спикера.

Количество слов для чтения:6109 | 16 минут чтения

Посмотрите полное видео с речью гостя и PPT,Пожалуйста, нажмите:t.cn/EAwb3Jg.

Резюме

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

Зачем использовать GraphQL

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

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

Проблемы с устаревшими интерфейсами (бэкенд)

Вот краткое введение в некоторые проблемы, возникающие при применении традиционных интерфейсов в нашей области.

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

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

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

Выше приведен анализ этих проблем с точки зрения серверной части. Далее наш ответственный за фронтенд представит некоторые из наших практик в направлении фронтенда.

Проблемы с традиционными интерфейсами (front-end)

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

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

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

Рассмотрим проблему низкой эффективности разработки. UnderFetching и OverFetching всегда были неизбежны во фронтенд-разработке.

UnderFetching означает, что данные, получаемые от интерфейса, намного меньше, чем данные для отображения, что приводит к проблеме N+1, то есть необходимо запрашивать соответствующий интерфейс по идентификатору или подробной информации в полученном интерфейсе. , что приводит к тому, что внешний запрос изменился с асинхронного на синхронный.

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

Средний уровень узла против GraphQL (интерфейс)

Столкнувшись с этими проблемами, вызванными традиционными интерфейсами, общие команды выберут NodeJ в качестве решения среднего уровня. Итак, каковы преимущества и недостатки Node и GraphQL? Давайте посмотрим ниже.

Node.js в определенной степени облегчает проблемы недостаточной и чрезмерной выборки, особенно решает проблему N + 1. Серверная часть может интегрировать ресурсы данных через средний уровень Node.Js, но в настоящее время он может возвращать только фиксированные данные. структура.

Очевидны и недостатки Node.js, например, требуется дополнительная адаптация под несколько терминалов, сложно адаптироваться к быстрой итерации фронтенда, требуется много времени на сопровождение, что также приведет к ошибки в интерфейсной документации.

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

Как поменять колеса (передок) скоростной машины

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

Прежде чем менять колесо, я сначала сравнил внешний фреймворк для кеширования данных.Сейчас наиболее распространенными являются Relay и Apolloo. Официально запущенный Facebook, Relay поддерживает React и React Native, а Apolloo поддерживает большинство основных фреймворков.

Что касается маршрутизатора, Relay официально поддерживает React Route, и в новой версии также поддерживается новый маршрут Found. Apollo может поддерживать любой маршрут, потому что его собственный режим работы и жизненный цикл полностью отделены от маршрутизации.

Кэширование данных Relay осуществляется официальным RelayStore, а Apollo основан на Redux. Исходя из вышеперечисленных соображений, я в итоге выбрал Apollo.

Когда мы раньше использовали Redux и Redux-saga, мы не сталкивались с какими-либо серьезными проблемами, но в основном это было хлопотно. Необходимо вручную управлять и хранить возвращаемые данные, а для каждого ресурса устанавливать набор Action, Reducer и Redux-saga, при этом для каждого запроса должна выполняться обработка исключений и данных, а также множественные последовательные запросы должен срабатывать для данных, требуемых страницей.

После использования GraphQL и Apollo внешнему интерфейсу нужно только определить URL-адрес глобально.Следующий шаг — определить данные, которые должен получить каждый запрос, и настроить данные интерфейса в соответствии со страницей. В то же время он также может выполнять глобальную обработку исключений и объединять запросы интерфейса.

Как установить колеса (передняя часть)

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

Для данных страницы заказа нашего приложения в сценарии Restuful информация о заказе сначала запрашивается на основе идентификатора заказа, затем подробные данные о продукте получаются на основе идентификатора продукта, полученного из информации о заказе, а затем подробные данные о клиенте. необходимо получить на основе идентификатора создателя, и, наконец, эти данные объединяются для отображения страницы.

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

Объект Employee вложен в класс Order и класс Peuduct.В этих двух классах информацию о данных сотрудника можно легко получить через поле создателя.

Класс Order и класс Peuduct находятся во взаимосвязях, и соответствующие данные объекта определяются через поле items.

На этом рисунке показаны интерфейсный фрагмент и запрос соответственно. Фрагмент внешнего интерфейса основан на объектах.Первый фрагмент кода слева — это Фрагмент сотрудника, основанный на объекте Сотрудник, из которого мы можем получить такие данные, как идентификатор, пол и имя. На объект сотрудника можно свободно ссылаться в других фрагментах.

Запрос на самом деле является определением GraphQL традиционного интерфейсного фрагмента, который может использовать официальный метод, предоставляемый GraphQL, для привязки связанных полей данных к компоненту.

Решение для аутентификации и продления аренды (внешний интерфейс)

В случае объединения GraphQL и Apollo наша схема аутентификации в основном опирается на AppAsyncStorage и веб-localStorage, две схемы сохранения данных.

Токен, созданный в процессе входа в систему, кэшируется в App AsyncStorage или веб-localStorage.При регистрации GraphQL Server setContext устанавливается через outLink.Метод setContext в основном используется для перезаписи заголовка и добавления полей ресурсов в заголовок. Это поле ресурса обычно определяется после переговоров с серверной частью, но официальная рекомендация Apollo реализует всю схему аутентификации путем передачи токена.

Как использовать колесо

Промышленное контрольное оборудование (внешняя часть)

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

Мы реализуем связь между сервером и Raspberry Pi через Alibaba Cloud IoT Suite, Устройство может публиковать и подписываться на некоторые данные в MQTT, и время от времени с устройства в MQTT будет загружаться пакет сердцебиения для его обновления. , данные страницы. После этого MQTT доставит пакет пульса в очередь сообщений, а затем синхронизирует сообщение на прикладном уровне через API.

Наконец, приложение или веб-конец считывает информацию об устройстве, такую ​​как номер устройства, версия прошивки, IP-адрес общедоступной сети и т. д., через предоставляемый им API GraphQL.

Когда пользователь обнаруживает, что существует разница между версией устройства и версией сервера, и выполнение необходимо обновить, динамическая операция по существу отправляется на уровень API GraphQL, а затем уровень API GraphQL отправляет сообщение на устройство. , а затем сообщение достигает MQTT через API SDK, а затем публикует серию запросов на устройство. Наконец, после перезагрузки устройства оно повторно опубликует пакет пульса в MQTT, чтобы обновить серию операций.

Меры предосторожности при использовании колес

Проблемы с новыми колесами (передок)

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

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

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

Существует также проблема перезаписи данных ресурсов из-за дублирования объектов ресурсов и идентификаторов, что вызвано характеристиками хранилища данных Аполлона.Тип и идентификатор каждого объекта ресурса Аполлона являются уникальными идентификаторами, которые определяют поля данных.

Изменения в дизайнерских идеях Компонента (front-end)

Ранее разработанный компонент имеет две концепции: компонент-контейнер и компонент отображения.Существует взаимодействие между компонентом-контейнером и хранилищем Redux для обновления данных, в то время как компонент отображения просто отображает данные. Теперь, используя GraphQL, мы нашли лучшее решение.

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

Проблемы с производительностью, вызванные слишком большой зависимостью от Fragment (интерфейс)

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

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

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

Вышеупомянутое, вероятно, все содержимое передней части. Пожалуйста, продолжайте читать о внутренней стороне.

Проблемы с новыми колесами (бэкэнд)

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

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

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

Проблемы с производительностью (бэкенд)

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

Во-первых, это сценарий N+1 GraphQL, то есть интерфейс может сначала найти массив IDS при запросе данных, а затем сопоставить массив IDS, чтобы снова инициировать запрос к серверу. -end может быть получен через несколько SQL-запросов Список данных.

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

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

Контрольный вопрос

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

Авторизация может быть специфичной для операций или полей. Ограничение частоты запросов должно не только предотвращать вредоносные запросы кистей, но и реализовывать ограничения на основе IP и UserID.

Опыт монтажников

Заголовок здесь — это опыт монтажников, который на самом деле относится к моим личным наблюдениям и обобщениям процесса использования GraphQL.

Давайте сначала рассмотрим недостатки GraphQL.

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

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

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

В-четвертых, поскольку в Китае не так много команд, использующих GraphQL, опытных инженеров набрать сложно, и приходится накапливать с нуля.

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

Лично я считаю, что повышение эффективности работы фронтенда, бэкенда или DevOps с помощью самих инструментов разработки — это будущая тенденция развития.Я также считаю, что GraphQL в будущем будет поддерживать больше фреймворков, решать больше проблем и улучшать производительность. и безопасность.

о нас

Youshupai — это профессиональный текстильный SaaS-продукт с такими функциями, как промышленный (аппаратный) контроль, управление образцами, складское хранение, управление продажами и помощь в проектировании.Сценарии применения охватывают десятки сценариев в отрасли и почти десять терминалов.

При выборе стека технологий мы используем React для Интернета и React Native для приложения. Основной исходный код API серверной части написан на Ruby, а для анализа данных используется немного Python. В настоящее время все API имеют был перенесен на GraphQL. В аппаратной части используется C++, в управлении серверным контейнером — Docker, а в БД — PostgreSQL.

В настоящее время у нас есть raspberry pi, tv, pad, web, app, wechat terminal, ipad на терминале.

Выше все делится, спасибо!

Редактор: IT big coffee сказал, пожалуйста, указывайте авторские права и источник при перепечатке