Разработка мобильного приложения без сервера

Разработка мобильного приложения без сервера

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

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

Такая ситуация может происходить по разным причинам. Однако, чаще всего на старте разработки, бэкэнд просто не написан и клиент начинает без него. В таком случае начало разработки затягивается на 2-4 месяца

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

Как правило, любое клиент-серверное приложение выглядит примерно вот так:

На каждый экран приходится как минимум 1 запрос (а часто больше). Переходя по экранам вглубь, нам нужно сделать все больше и больше запросов. Иногда мы даже не можем сделать переход, до тех пор пока сервер не скажет нам «Покажи кнопку». То есть мобильное приложение очень сильно завязано на сервер, не только во время своей непосредственной работы, но и на этапе разработки. Рассмотрим абстрактный цикл разработки продукта:

  1. Сначала мы проектируем. Декомпозируем, описываем и обсуждаем.
  2. Получив задачи и требования, начинаем разработку. Пишем код, верстаем и т.п.
  3. После того, как мы что-то реализовали, готовится сборка, которая уходит на ручное тестирование, где работа приложения проверяется по разным кейсам.
  4. Если у нас все нормально, и тестеры апрувят сборку, она уходит заказчику, который выполняет приемку.


Каждый из этих процессов очень важен. Особенно последний, так как заказчик должен понимать на каком этапе мы действительно находимся, а иногда ему нужно отчитываться о результатах перед руководством или инвесторами. Как правило, подобные отчеты происходят, в том числе, в формате демонстрации мобильного приложения. На моей практике был случай, когда заказчик демонстрировал буквально половину MVP, которая работала только на моках. Приложение на моках выглядит как настоящее и крякает как настоящее. Значит оно настоящее (:
Однако это розовая мечта. Давайте рассмотрим, что произойдет на самом деле, если у нас не будет сервера.

  1. Процесс разработки будет проходить медленнее и болезненнее, так как сервисы мы написать нормально не можем, проверить все кейсы тоже не можем, приходится писать заглушки, которые потом нужно будет удалить.
  2. После того, как мы с горем пополам сделали сборку, она попадает тестерам, которые смотрят на нее и не понимают что с ней делать. Проверить ничего нельзя, половина вообще не работает, потому что сервера нет. Как следствие — пропускают много багов: как логических, так и визуальных.
  3. Ну а после «как смогли посмотрели», надо отдать сборку заказчику и тут начинается самое неприятное. Заказчик не может толком оценить работу, он видит 1-2 кейса из всех возможных и уж точно не может показать это своим инвесторам.


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

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

Таким образом, есть следующие проблемы:
 

  1. Сервер отсутствует полностью. Из-за этого невозможно разрабатывать, проверять и презентовать.
  2. Сервер не успевает, что мешает разрабатывать и может мешать тестировать.
  3. Мы хотим тестировать граничные кейсы, а сервер не может этого позволить без долгих телодвижений.
  4. Аффектит тестирование и угрожает презентации.
  5. Сервер падает (однажды мы уже во время стабильной разработки лишились сервера на 3.5 дня).


Чтобы бороться с этими проблемами и был создан Mocker.
 

Принцип работы


Mocker — небольшой веб-сервис, который где-то хостится, слушает трафик на каком-то определенном порту и умеет отвечать заранее заготовленными данными на конкретные сетевые запросы.

Последовательность следующая:

1. Клиент отправляет запрос.
2. Mocker получает запрос.
3. Mocker находит нужный мок.
4. Mocker возвращает нужный мок.

url


Этот параметр используется для того, чтобы указать URL запроса, по которому обращается клиент.

Например, если мобильное приложение делает запрос на url host.dom/path/to/endpoint, то в поле url нам нужно написать /path/to/endpoint.
То есть это поле хранит относительный путь до эндпоинта.

Это поле должно быть отформатировано в формате url-template, то есть допускается использовать следующие форматы:
 

  1. /path/to/endpoint — обычный url адрес. Во время получения запроса сервис будет сравнивать строки посимвольно.
  2. /path/to/endpoint/{number} — url с path-паттерном. Мок с таким URL будет реагировать на любой запрос, который удовлетворяет этому шаблону.
  3. /path/to/endpoint/data?param={value} — url c parameter-паттерном. Мок с таким url сработает на запрос, содержащий заданные параметры. При этом, если одного из параметров не будет в запросе, то он не будет соответствовать шаблону.


Таким образом, управляя URL параметрами можно явно определить, что на какой-то определенный url вернется какой-то определенный мок.
 

method


Это ожидаемый http method. Например POST или GET.
Строка обязательно должна содержать только заглавные буквы.
 

statusCode


Это код http статуса для ответа. То есть запросив этот мок, клиент получит ответ со статусом записанным в поле statusCode.
 

response


Это поле содержит JSON объект, который будет отправлен клиенту в теле ответа на его запрос.
 

request


Здесь записывается тело запроса, которые ожидается получить от клиента.Это будет использоваться для того, чтобы отдать нужный response в зависимости от тела запроса request. Например, если мы хотим менять ответы в зависимости от параметров запроса.

Кэширующий прокси


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

Получив ответ с 200-м кодом Mocker сохраняет ответ в моковый файл (да, вы потом можете его скопировать или поменять) и возвращает клиенту то, что он получил от реального сервера. Причем, он не просто сохраняет файл в случайное место, а организует файлы так, чтобы с ними можно было затем работать вручную Например, Mocker отправляет запрос по следующему URL: hostname.dom/main/products/loans/info. Тогда он создаст папку hostname.dom, затем внутри нее он создаст папку main, внутри нее папку products

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

Интерфейс


Сначала мы работали с моками напрямую по по ssh, но с ростом числа моков и пользователей перешли на более удобный вариант. Сейчас мы используем CloudCommander.
В примере docker-compose, он связывается с контейнером Mocker-а.

Развертывание


Для того, чтобы развернуть Mocker проще всего использовать Docker. К тому же, развернув сервис из докера, автоматически развернется web-интерфейс через который удобнее работать с моками. Файлы необходимые для развертывания через Docker лежат в репозитории.

Однако, если вас не устраивает этот вариант, можете самостоятельно собрать сервис из исходников.

Известные проблемы

 

  • После каждого нового файла надо делать curl mockerhost.dom/update_models для того, чтобы сервис прочел файлы заново. Я не нашел быстрый и элегантный способ обновлять его иначе
  • Иногда CloudCommander багует (или я что-то не так сделал) и он не дает редактировать моки, которые были созданы через web-интерфейс. Лечится чисткой кэша у браузера.
  • Сервис работает только с application/json. В планах поддержка form-url-encoding.

 

Итог


Mocker— это web-сервис, который решает проблемы разработки клиент-серверных приложений в том случае, когда сервер по каким-то причинам не готов.

Сервис позволяет создавать множество разных моков на один URL, позволяет связать между собой Request и Response с помощью явного указания параметров в url, либо прямо с помощью задания ожидаемого тела запроса. У сервиса есть web-интерфейс, который сильно упрощает жизнь пользователям.

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