Этот пост был впервые опубликован в блоге TK.

В Front-End Development принято использовать данные API для визуализации пользовательских интерфейсов. Но иногда данные API не совсем то, с чем мы хотим работать. Таким образом, нам удается сопоставить данные API с состоянием приложения.

Но это не должно быть сложно. Это может быть простая функция сопоставления, контракт данных API и контракт состояния приложения.

Я покажу пример в контексте приложения Redux и покажу, как мы можем сделать состояние согласованным.

Начнем с первоначального госконтракта.

И используйте тип контракта в определении начального состояния:

После определения состояния приложения мы можем думать о контракте API. Мы можем просто реализовать тип PersonAPI со всеми типами, необходимыми для данных.

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

Это очень просто! И как нам это использовать?

Данные входят. Данные выходят. Все чисто.

Здесь у нас очень простое отображение, без задействованной логики. Но что, если данные API, которые мы получаем, содержат не name, а firstName и lastName? Мы хотим преобразовать firstName и lastName в атрибут name в Person контракте.

Тип PersonAPI:

Тип Person:

В нашем name нам нужно соединить строки. В основном выполняется строковая интерполяция:

Итак, наша функция отображения будет примерно такой:

Здорово! Преобразование данных для рендеринга пользовательского интерфейса.

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

Мы можем использовать Typescript Optional Property. Он сообщает нам: «Это необязательное свойство, оно имеет этот тип, но данные могут быть здесь ... или нет!»

Итак, мы используем его в нашем контракте API:

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

  • У него есть свойство lastName: concat firstName и lastName
  • В нем нет lastName: просто верните значение firstName

Но мы также можем преобразовать этот let оператор в const, выполнив тернарную операцию:

Или лучше: разделите его ответственность на функцию, которая создает имя!

Мы разделяем ответственность каждой функции. Здорово! Теперь протестировать наши функции стало проще.

Следующий этап: использование данных API для создания нового состояния приложения. Представьте, что мы хотим знать, активен ли человек. Бизнес-правило: статус человека должен быть active, а последнее посещение должно быть в пределах этой недели (за последние 7 дней).

Сначала наш контракт API:

Мы будем использовать эти свойства: status и lastVisit.

Второй госконтракт нашего приложения:

Бизнес-правило сейчас:

  • Статус человека должен быть active.
  • Последний визит должен быть в течение последних 7 дней.

Теперь наша функция отображения:

Давайте проведем рефакторинг! Начнем с status. 'active' - строка. Чтобы определить его в структуре данных и обеспечить возможность повторного использования, мы можем использовать Enum в Typescript.

Мы используем это как:

Логика статуса человека упрощается с помощью этой функции:

Теперь последний визит. Как насчет того, чтобы сделать его более наглядным вместо случайных чисел? Это 1 день в миллисекундах:

Это 7 дней в миллисекундах:

А это неделю назад:

Теперь наша логика проста:

Теперь мы можем объединить все вместе в функции с именем isActive, которая возвращает логическое значение?

Я действительно хочу выделить weekAgo «логику» в новую функцию. И еще хочу назвать заявления.

Называя наши утверждения, это выглядит так:

Итак, наша последняя функция isActive выглядит красиво:

И наша функция отображения остается простой:

Всего несколько настроек: Сокращение значения свойства объекта для id и email.

Обучение

Итак, что мы узнали здесь?

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

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

Примечание из JavaScript на простом английском:

Мы запустили три новых издания! Проявите любовь к нашим новым публикациям, подписавшись на них: AI на простом английском, UX на простом английском, Python на простом английском - спасибо и продолжайте учиться!