Рубрики
Без рубрики

Архитектура веб-приложения на основе redux

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

Автор оригинала: José Proença.

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

Эта архитектура зависит от некоторых библиотек и их концепций, что будет несколько объяснено на протяжении всей статьи:

  • Redux Какой «предсказуемый государственный контейнер для приложений JavaScript» поможет вам «написать приложения, которые ведут себя последовательно»;
  • “Эпографические” от Redux-наблюдаемый который является менеджером побочных эффектов для Redux, что позволяет составлять асинхронные действия в реакции на другие действия;
  • RXJS который является «библиотекой для составления асинхронных и событийных программ, используя наблюдаемые последовательности»;
  • Аполлон Graphql клиент Отказ GraphQL – это «язык запроса для API» и красивая эволюция от отдыха. На архитектуре изображена здесь, график не является обязательным вариантом. Другие поставщики данных могут использоваться на этой архитектуре.

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

В финале этой статьи я представляю некоторые функции веб-приложения и как вы можете легко увидеть Redux и Time-Travel, работающие в режиме реального времени!

Преимущества архитектуры

Эта архитектура наследует преимущества Redux (и недостатки, конечно). Отличное резюме по выбору redux – это статья ” Вам может не понадобиться redux ” Дэна Абрамовым. Я думаю, что еще два интересных преимущества:

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

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

Следует с диаграммой с модулями архитектуры, где старый добрый 3-уровня архитектура все еще в хорошей форме, где главное отличие от Redux к MVC Архитектура (что также использует эту трехуровневую архитектуру) в ограничении. Давайте проанализируем каждый компонент сразу.

Компоненты архитектуры приложения клиента

Архитектура приложений

Модели

Модуль «Модели» объявляет модели данных и связанные с ними статическими функциями Micro/Helper. Каждая другая часть приложения может получить доступ или использовать модели, поэтому диаграмма не показывает, что зависимость для ясности.

Только сериализуемые модели могут быть сохранены на Redux и передаются в/с сервера, используя JSON. Чтобы это правило всегда присутствовать, рекомендуется отметить типы, которые действительно являются последовательными. Я решил добавить сериализуемые типы с суффиксом «SER». Таким образом, я всегда не помню не статичных функций в этих классах.

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

Эта архитектура также реализует абстракцию метаданных для прохождения по состоянию приема данных, называемую Asyncdataser:

  • Предоставляет заполнителю для доступа к асинхронно полученным данным. Он предоставляет данные (возможно) и статус об этом, как «загрузка» или «ошибка».
  • Обычно он генерируется на слое данных и используя его по приложению, каждому потребителю понимают, что устанавливает состояние данных и может соответственно реагировать. Это включает в себя шаблоны HTML, которые могут переключаться между различными презентациями данных (или отсутствием).
  • Также предоставляет свойство курсора для помощи на пагиновых данных.

Тематическое исследование

Для исследования случая я объявляю «въезд», «Andref» и «UserRef». Данные ввода будут доступны как Asyncdataser для записи.

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

class EntrySer
{
    constructor(
        public id: string = null,
        public title: string = '',
        public type: string = 'FLICKR',
        public data: string = '',
        public postBy: UserRef = null,
        public dateCreated: string = null) { }
 
    public static fields: string = `
            id
            title
            type
            data
            postBy { ${ UserRef.fields} }
            dateCreated
    `;
}
 
class EntryRef {
    constructor(
        public id: string = null) { }
 
    public static fields: string = `
            id
    `;
 
    public static resolveRef(ref: EntryRef, entries: Array) {
        return entries.find(e => e.id === ref.id);
    }
}
 
class UserRef {
    constructor(
        public id: string) { }
 
    public static fields: string = `
        id
    `;
 
    public static resolveRef(ref: UserRef, users: Array) {
        return users.find(u => u.id === ref.id);
    }
}
 
class AsyncDataSer {
    public error: boolean = false;
    public errorsData?: Array = null;
 
    constructor(
        public data: T,
        public loading: boolean = false,
        public cursor: any = null) { }
 
    public static hasData(adata: AsyncDataSer, orError: boolean = false): boolean {
        if (orError)
            return adata.error || (!adata.loading && adata.data != null);
             
        return !adata.error && !adata.loading && adata.data != null;
    }
 
    public static errored(errors?: Array, data: T = null): AsyncDataSer {
        const obs: AsyncDataSer = new AsyncDataSer(data);
        obs.error = true;
        if (errors && Array.isArray(errors))
            obs.errorsData = errors.filter((error) => (error.name && error.name === 'ServerError'));
        return obs;
    }
}

Слой данных

Служба данных концентрирует все конкретные запросы/мутации в базу данных, требуемой бизнес-уровнем. Также необходимо, – это менеджер по отношению к клиентскому сущному менеджеру, которое взаимодействует с удаленной базой данных, обеспечивая кэшированные результаты и навигацию на наливную связь. Я использовал клиент Apollo GraphQL.

Данные в результате/кэшированные данные хранятся в магазине Redux, что делает часть состояния приложения, которое может быть непосредственно потребляется на уровне презентации. Для этого менеджер ER должен предоставлять свои собственные редукторы и действия, объяснив двойную стрелку между «ER Manager» и «Store redux» на диаграмме выше.

Слой данных также генерирует объекты Asyncdataser в каждом запросе, как обсуждалось в разделе «Модель» выше.

Тематическое исследование

Endservice предоставляет функцию fetchentry_query (dataid, wrendid, usid) для извлечения данных записи. Этот запрос можно использовать различным клиентским кодом, возможно, в разных частях приложения, поэтому «Dataid» – это глобальный идентификатор, предоставляемый клиентским кодом, который будет позже, используемый для доступа к результатам запроса на уровне презентации.

Бизнес-слой

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

Один «EPIC» – это функция, которая в ответ на действия, обрабатываемое редукторами, производит цепочку других действий во время. Простой пример – выделять действие для сброса фильтров поиска, когда отправляется действие ввода на страницу. Более полезной ролью для EPIC является вызов конечной точки API в ответ на действие, создаваемое кнопкой «Сохранить», например. Затем он может ждать асинхронизм для ответа и цепочки действия с этим ответом. Эпопримена используют RXJS который надевает эту своевременную цепочку красиво. Epics взаимодействует только с моделями, службой данных и магазином Redux, где редукторы гораздо более ограничены.

Редукторы создают новое состояние из исключительно двух входов: текущее состояние и диспетчерское действие. Каждый редуктор должен быть чистая функция , реализация детерминированный алгоритм Учитывая эти два входа. Помимо домашнего сайта для Redux, Есть много учебных пособий, таких как Статья Алекс Бачук Для получения дополнительной информации по всем этим вопросам.

Тематическое исследование

Это тематическое исследование предназначено для начальной загрузки страницы детализации для редактирования «ввода». Страница может быть доступна как подобное URL « /Editrentry/EBBDDD170-6DEA-11E7-80D7-475D81AEC50B » и, введя на страницу, эта запись загружается для отображения и редактирования.

Необходимые данные состояния Redux:

  • Выбранный идентификатор записи
  • Состояние редактирования (готов, изменено, загрузка, экономия, ошибка)
  • Входные данные
  • Зарегистрированный пользователь

Есть два эпопада для выполнения загрузки данных на странице:

  • Epic для установки текущего выбранного идентификатора ввода

    • Реагируйте только на действие страницы, входящих в правильную идентификатор страницы
    • Проверьте параметры URL для получения текущего идентификатора ввода
    • Emit Action для установки текущего выбранного идентификатора ввода в данных состояния
  • Epic для загрузки данных записи:

    • Реагируйте только на любые действия типов:
      • Выбор записи. Запись была только что выбрана, поэтому мы должны попытаться загрузить свои данные.
      • Успех входа пользователя. Поскольку запись может быть выбрана, но не пользователь, только после того, как пользователь в порядке, мы можем попытаться загрузить запись.
      • Страница нагрузка. Похож на проверку входа пользователя. Только на правильной странице мы можем загрузить запись.
    • Реагируйте только на эти предварительные условия:
      • Правильная страница ID.
      • пользователь вошел в систему
    • Если текущий выбранный идентификатор ввода – это ноль:
      • Цепь статус редактирования действий для готов
      • Установите редактирование данных для пустого
      • Конец эпично
    • Если текущее состояние редактирования изменено:
      • Бездействие. Пользователь – середина изменения чего-то, поэтому не загружайте запись.
      • Конец эпично
    • Если текущий выбранный идентификатор ввода и идентификатор пользователя оба не ноль:
      • Попросите слой данных начать нагрузку соответствующей записи
      • Цепь Состояние редактирования действий для загрузки
      • При наличии результата базы данных:
        • Цепь статус редактирования действий для готов
        • Цепочка настроек действия редактирования данных к полученным данным
        • Конец эпично

Страницы

Страницы – это «контейнерные компоненты» (как определено ниже), которые содержат другие контейнеры и компоненты презентации (также определены ниже) в макете и не делают многое другое. Они отделены от контейнеров, потому что они являются верхним уровнем и являются только тем, что видит прикладной маршрутизатор (маршрутизатор приложений – это то, что управляет навигацией в приложении).

Тематическое исследование

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

Контейнерные компоненты

Разделение компонентов в «контейнер» и «презентационные» представлены на запоминающемся Статья Дэна Абрамовым. Вы можете прочитать больше там, но чтобы поехать, мне нужно только сказать, что контейнеры – это компоненты, которые координируют взаимодействие между компонентами презентационного дочернего действия и магазином Redux. У них только необходимые HTML/CSS для выкладывания дочерних компонентов. Кроме того, они подтверждают и получают события от дочерних компонентов и запускают соответствующие действия Redux. Поскольку контейнеры имеют прямую зависимость от состояния и действий redux, что, в свою очередь, полностью связано с бизнес-логикой, они, как правило, вряд ли можно многоразоваться. Наконец они могут иметь локальные входы: в основном для конфигурации, поскольку они могут прочитать состояние Redux самостоятельно.

Тематическое исследование

Контейнер Editressry использует два презентационных компонента: intryform и entrypreview. Это выбирает состояние (редактирование состояния, данные входа) и получает события (для измененной формы) для и из компонентов. Также включает кнопку «Сохранить/обновление», которая включена только при редактировании состояния «изменено». Он вызывает подходящее действие Redux для сохранения или обновления отредактированных данных ввода, собранных из компонента Approwform.

Презентационные компоненты

«Презентационная компонент» – это окончательный веб-компонент UI, полностью многоразовый и продуцирующий все необходимые HTML/CSS.

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

Тематическое исследование

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

Мой боковой проект: www.brickurator.com

Веб-приложение «Brickurator» – это система метки и рейтинга для внешних изображений. В этом случае для помечения конструкций Lego®, показанные на Flickr® (будут расширены другим в будущем). Он был реализован после архитектуры, изображенной на этой статье и с точки зрения разработки веб-приложений, упоминаются следующие функции:

  • Реализация Redux с полным проездом времени;
  • Автоматический отчет об ошибке: на ошибке JavaScript Отчет с последними 50 действиями отправляется на сервер для последующего воспроизведения и отладки с использованием Time-Travel;
  • тонкозернистая загрузка/ошибка состояния данных;
  • Оптимистичное интернет-интерфейс: изменения данных реализованы на стороне клиента перед ответом сервера;
  • Асинхронная операция: нет блокировки пользовательского интерфейса, нет кнопки «Сохранить» (за исключением создания объекта);
  • Интерфейс страницы тура с автоматией;
  • Авторизация и аутентификация пользователя с использованием auth0.com ;
  • Жидкая интернет-интерфейс: от мобильного до рабочего стола, используя Угловой и Ионный;
  • Graphql Сервер API с использованием APOLLO-SERVER и node.js;
  • Graphql Apollo-Client пользовательские завернутые для совместимости с временем;
  • Flickr® API интеграция;
  • Bighugelabs Интеграция API для английского тезауруса.

Если вы не знакомы с Redux, вы можете увидеть его в действии, установив Redux devtools расширение В Chrome и см. Действия и государство развиваются, когда вы взаимодействуете с приложением. Вы также можете использовать слайдер, чтобы сделать хорошее время путешествовать в приложении!

Повеселись!

Оригинальная статья In Мой блог Статья