Сегодня мы поговорим про заглушки в AngularJS-приложениях. Именно в приложениях, а не в тестах! Очень часто при разработке клиентской части приложения приходится реализовывать новую функциональность, не имея при этом рабочей функциональности на серверной стороне. А ещё иногда возникает потребность показать заказчику прототип приложения, не реализовывая при этом API для экономии времени. Когда-то я делал для этих целей на стороне HTTP-сервера (обычно на уровне nginx) заглушки — статические JSON-файлы, которые при подходящих location’ах отдавались наружу. Структура JSON’а в таком файле совпадает со спецификацией API, поэтому клиентское приложение можно разрабатывать со всеми HTTP-вызовами, не задумываясь особо о том, что сервер частично искусственный.
Но в этом подходе всё не так безоблачно! При разнообразии операций над REST-ресурсами (хотя не обязательно REST) в описании location’ов nginx’а могут появляться нетривиальные условия, вычисление статуса ответа (к примеру, при добавлении через POST-запрос REST API обычно отвечает HTTP-статусом 201, а при получении списка 200), HTTP-метода и т.д.. Реализация такой логики иногда занимает больше времени, чем хотелось бы. И тут нам на помощь приходит AngularJS-модуль ngMockE2E с сервисом $httpBackend, о котором многие разработчики несправедливо забывают или вовсе не знают.
Недавно я уже писал про нюансы при работе с $httpBackend в ngMock, но та заметка касалась unit-тестирования AngularJS-приложений. А вот $httpBackend в ngMockE2E позволяет нам настроить описания бэкенда («Backend Definitions») через when-методы и использовать их при работе с нашим приложением. Вполне логично, что в отличие от ngMock, у него отсутствуют методы по созданию ожиданий запросов («Request Expectations») через expect-методы, т.к. таких методов у сервиса $httpBackend в модуле ngMockE2E просто нет в связи с отсутствием необходимости верификации.
Так вот, для настройки ответов сервера при разработке или прототипировании (!!!) web-приложения, можно сделать такой трюк:
- Подключить к нашей странице файл angular-mocks.js, в котором определены модули ngMock и ngMockE2E;
- Определить модуль, который будем использовать только в среде разработки, в котором будут определяться заглушки ответов сервера. Он может выглядеть примерно так:
// Объявляем новым модуль с зависимостью ngMockE2E. При старте модуля делаем инъекцию зависимости $httpBackend. angular.module('development', ['ngMockE2E']).run(['$httpBackend', function ($httpBackend) { // Настраиваем заглушку на все GET-запросы получения списка пользователей с какими-нибудь критериями фильтрации. Определяем HTTP-код статуса и статический список в качестве ответа. Также тут можно использовать для проверки метод whenRoute. $httpBackend.whenGET(/^\/users\?.+$/i).respond(200, [{id: 1, name: 'Albert', lastName: 'Einstein'}]); // А все остальные запросы (тут надо перечислить все ваши возможные методы HTTP-запросов) мы будем спрашивать у настоящего бэкенда angular.forEach(['GET', 'POST', 'PUT', 'PATCH', 'DELETE'], function (method) { $httpBackend.when(method, /.*/i).passThrough(); }); }]);
- Подключаем файл с нашим AngularJS-модулем к странице;
- Добавляем модуль к зависимостям вашего основного модуля;
- Разрабатываем новую функциональность на мнимо-полноценном настроенном API;
- По окончании разработки не забываем отключить angular-mocks и наш модуль с заглушками, убрать зависимость в основном модуле.
Особо хотелось бы обратить ваше внимание на последний пункт. Если этого не сделать, думаю, вы представляете, как будет интересно пользователям работать с обновлённым приложением без реальных действий сервера по некоторым запросам
Ответы в заглушках можно сделать и динамическими. Для этого в метод respond() можно передать функцию. Подробнее об этом можно почитать в документации фрэймворка.
Подведение итогов
Теперь, в отличие от метода со статическими файлами на сервере, мы можем гораздо гибче настраивать заглушки запросов нашего сервера (вплоть до каждого адреса, заголовка и параметра), при этом даже не покидая пределы проекта в вашей любимой IDE.
Вот и всё! Я надеюсь, что приём, который я вам только что показал, будет вам полезен в разработке новых фич, которые в скором времени будут приятно удивлять всё новых и новых пользователей ваших приложений!
До новых статей!