Pull to refresh

[SDK и UI-библиотеки] Backend-Driven UI

Level of difficultyMedium
Reading time3 min
Views1.8K

Это глава 46 раздела «SDK и UI-библиотеки» моей книги «API». Второе издание книги будет содержать три новых раздела: «Паттерны API», «HTTP API и REST», «SDK и UI‑библиотеки». Если эта работа была для вас полезна, пожалуйста, оцените книгу на GitHub, Amazon или GoodReads. English version on Substack.

В предыдущей главе мы обсудили, каким образом можно упростить разработку сложных компонентов с использованием паттерна «модель». Другой способ обойти сложность «переброса мостов» между несколькими предметными областями, которые нам приходится сводить в рамках одного UI-компонента — это убрать одну из них. Как правило, речь идёт о бизнес-логике: мы можем разработать компоненты полностью абстрактными, и скрыть все трансляции UI-событий в полезные действия вне контроля разработчика.

В такой парадигме код поиска предложений выглядел бы так:

class SearchBox {
  …
  search(query) {
    const markup = await api.search(query);
    this.render(markup);
  }
  …
}

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

Этот подход можно обобщить ещё сильнее:

class SearchBox {
  constructor (…) {…}
  stateChange (patch) {
    // Получаем от сервера
    // список действий, которые
    // необходимо выполнить при
    // запрошенном изменении
    let actions = await api
      .getActions(
        this.model,
        patch
      );
    // Применяем действия
    …
  }
}

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

(Примером реализации этой идеи можно считать т.н. «Web 1.0» — сервер присылает готовый контент страницы, а вся интерактивность сводится к переходам по ссылкам.)

Хотя Backend-Driven UI обладает очевидным недостатком в виде требовательности к качеству соединения с сервером, у него есть два очень важных преимущества:

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

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

Тем не менее, мы не можем не отметить: при том, что любая крупная IT-компания проходит через эту фазу — разработки Backend-Driven UI (они же — «тонкие клиенты») для своих приложений или своих публичных SDK — мы не знаем ни одного заметного на рынке продукта, разработанного в этой парадигме (кроме, разве что, протоколов удалённых терминалов), хотя во многих случаях возникающими сетевыми задержками вполне можно было бы пренебречь. Рискнём сказать, что причины сложившегося положения вещей таковы:

  • разработать серверный код управления UI ничуть не проще, нежели клиентский;

  • современные клиентские устройства предоставляют широкий спектр функциональности, доступной только клиентскому разработчику, от кэшей до анимаций;

    • гибридный код, который частично получает состояние с сервера, частично обогащает его на клиенте, писать гораздо сложнее, чем чистый клиентский (в силу того, что в Backend-Driven UI содержимое ответа сервера для клиента представляет собой «чёрный ящик», для взаимодействия с которым приходится изобретать дополнительные протоколы);

    • отказ от гибридного кода, во-первых, сужает возможности приложения и, во-вторых, фактически переводит клиентское устройство в режим «облачного гейминга», что на сегодня очень дорого и не очень удобно для пользователя;

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

NB: следует различать Backend-Driven UI и технологию серверного рендеринга (SSR). Второе подразумевает, что одно и то же состояние UI (как правило, в виде HTML-разметки или аналогичного декларативного описания) может быть сгенерировано как сервером, так и клиентом. В SSR, однако, подразумевается, что клиент может интерпретировать ответ сервера и извлекать из него семантические данные.

С точки зрения предложения SDK сторонним разработчикам, Backend-Driven UI фактически вынуждает разрабатывать гибридный код (поскольку практика предоставления партнёрам возможности встроиться в функции серверного рендеринга на стороне провайдера API выглядит весьма далёкой от жизнеспособности идеей), и, таким образом, будет страдать от той же проблемы непрозрачности — разработчик не может со своей стороны определить, в каком сейчас состоянии находится визуальный компонент. Как ни странно, этот недостаток одновременно является и достоинством, поскольку вендор API сохраняет возможность на своей стороне производить любые манипуляции с контентом без нарушения обратной совместимости (мы обсудим этот вопрос в главе «Линейка сервисов API»). Таких клиентских API в мире существует довольно много (в первую очередь, разнообразные виджеты, рекламные API и т.д.), но их сложно назвать полноценными SDK.

Tags:
Hubs:
Total votes 3: ↑2 and ↓1+3
Comments8

Articles