Angular

Resource API и httpResource

Сигналы дали реактивное синхронное состояние, но данные обычно приходят асинхронно по сети. Раньше эти два мира сшивали вручную: подписаться на Observable, разложить результат по полям loading, error, value, не забыть отписаться. Resource API стирает шов. resource() и httpResource() сами выполняют асинхронную загрузку и выставляют результат как готовые сигналы value(), status(), error(). А когда меняется реактивный параметр запроса, ресурс сам перезапрашивает данные. Асинхронная загрузка наконец живёт в том же сигнальном мире, что и остальное состояние.

  • httpResource: один вызов превращает HTTP-запрос в сигналы данных, загрузки и ошибки, без ручной подписки
  • Реактивные параметры: ресурс с params на основе сигнала id сам перезапрашивает данные при смене id в URL
  • Состояния загрузки: status() и isLoading() напрямую управляют спиннером и сообщением об ошибке в шаблоне
  • Zoneless-приложения: ресурс - естественный источник асинхронных данных, который change detection видит через сигналы
  • Master-detail экраны: выбор записи в списке меняет сигнал, и detail-ресурс автоматически подтягивает её данные

Предварительные знания

  • Сигналы: signal(), computed(), чтение значения вызовом
  • HttpClient и типизированные запросы get/post
  • Понятие асинхронной загрузки и состояний loading/error/success

Зачем нужен Resource API

Сигналы реактивны и синхронны: значение всегда доступно сразу. Сетевые данные приходят асинхронно и несут с собой не одно значение, а целое состояние: идёт ли загрузка, есть ли ошибка, пришёл ли результат. Раньше это собирали руками: завести три сигнала, подписаться на Observable, в next записать value, в error записать ошибку, не забыть про отписку. Много шаблонного кода и легко ошибиться.

resource() сам управляет всем жизненным циклом загрузки. Функция params читает реактивные значения (здесь id()), а loader выполняет асинхронную работу и возвращает промис. Ресурс выставляет результат как сигналы value, status, error и обновляет их по ходу загрузки. Ручных подписок и отписок больше нет.

Ключевая особенность: при изменении любого сигнала, прочитанного в params, ресурс автоматически перезапускает loader с новыми параметрами. Смена id() с 1 на 2 сама инициирует новую загрузку, и value() обновится. Это и есть реактивная перезагрузка по параметрам.

Что произойдёт с ресурсом, если изменить сигнал, прочитанный внутри его функции params?

httpResource и его сигналы

httpResource() - специализация resource для самого частого случая: загрузки по HTTP. Вместо ручного loader он сам ходит через HttpClient. На вход - URL или объект запроса (метод, заголовки, тело), на выход - те же сигналы value/status/error. Дженерик задаёт тип данных, как в HttpClient.

Сигнал ресурсаЧто отдаётГде применяют
value()Данные или undefined, пока их нетОтображение результата в шаблоне
status()Состояние: idle, loading, resolved, errorЛогика по фазе загрузки
isLoading()Булев признак активной загрузкиПоказ спиннера
error()Ошибку загрузки или undefinedСообщение об ошибке, повтор запроса

URL в httpResource - реактивная функция, а не строка. Передав готовую строку вместо колбэка, ресурс не пересоберёт запрос при смене id. Чтобы перезагрузка по параметру работала, внутри функции должен читаться сигнал: () => `/api/users/${this.id()}`.

В чём преимущество httpResource перед общим resource для загрузки по HTTP?

Resource против subscribe и AsyncPipe

До сигналов асинхронные данные потребляли через Observable: либо ручной subscribe в коде, либо AsyncPipe в шаблоне. Resource API - не замена RxJS вообще, а другой способ доставки данных в шаблон: как сигналы, а не как поток. Выбор между ними зависит от того, в каком мире живёт остальное состояние компонента.

  • subscribe / AsyncPipe (Observable) — Данные как поток. Сильны в сложных асинхронных пайплайнах: debounce, switchMap, объединение потоков. AsyncPipe сам управляет подпиской, но состояние loading/error приходится собирать вручную.
  • resource / httpResource (сигналы) — Данные как сигналы рядом с остальным сигнальным состоянием. Готовые value/status/error, реактивная перезагрузка по параметрам, естественно для zoneless. Слабее для сложной оркестрации потоков.

Практический ориентир. Если данные напрямую кормят шаблон и компонент уже на сигналах, особенно в zoneless-приложении, resource даёт меньше шаблонного кода и встроенные состояния загрузки. Если нужна сложная композиция асинхронных событий (поиск с debounce, отмена предыдущего запроса, слияние нескольких потоков), сильнее остаётся RxJS с операторами.

Возврат undefined из функции запроса httpResource - штатный способ отложить загрузку. Пока параметр не готов (запись не выбрана, форма не заполнена), запрос не отправляется, ресурс остаётся в состоянии idle. Как только сигнал получит значение, загрузка стартует сама.

Когда resource/httpResource предпочтительнее связки subscribe и AsyncPipe?

Связь с другими темами

Урок сшивает асинхронные данные с сигналами. Опирается на HttpClient и change detection:

  • HttpClient — httpResource построен поверх HttpClient и наследует его типизацию
  • Change detection и zoneless — Ресурс отдаёт данные как сигналы, и zoneless CD реагирует на них без подписок

Итог

  • resource() оборачивает любую асинхронную загрузку (loader) и отдаёт результат как сигналы value(), status(), error()
  • httpResource() - специализация поверх HttpClient: принимает URL или объект запроса и наследует типизацию через дженерик
  • Реактивные параметры запроса: когда читаемый внутри сигнал меняется, ресурс автоматически перезапрашивает данные
  • status() даёт состояние загрузки (idle, loading, resolved, error), а isLoading() - удобный булев сигнал для шаблона
  • Resource заменяет связку ручной subscribe и AsyncPipe там, где данные должны жить как сигналы, особенно в zoneless

Связанные уроки

  • ng-26-httpclient — httpResource построен поверх HttpClient, поэтому базовые типизированные запросы идут первыми
  • ng-11-signals-intro — resource заводит асинхронные данные именно в сигналы, без понимания сигналов его поведение неясно
Resource API и httpResource

0

1

Войти