habrahabr

Как написать максимально хреновый бэкенд для мобильного приложения

  • среда, 28 июня 2017 г. в 03:19:47
https://habrahabr.ru/post/331120/
  • Разработка под iOS
  • Разработка под Android
  • Разработка мобильных приложений
  • API



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


Если вы мобильный разработчик, то наверняка сталкивались с такими бородатыми дядями, которые меланхолично тянут логику на перле и вечно что-то пишут в консоли. Или может это был сутулый анимешник с длинными волосами, всосавший php с молоком матери.
Так или иначе, большинство из них ни разу не сталкивалось с мобильной разработкой, а кое-кто считает себя при этом гуру.


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


Приятного чтения.
Итак, если вы серверный разработчик:


  • Не обращайте внимания на строение приложения, вам абсолютно не должно быть дело до того, как будет выглядеть продукт для пользователя. Ведь вы не хипстер, чтобы задумываться о таких вещах. Если данные для одного экрана надо получать через 10 разных запросов, это проблемы дизайнера, который рисовал интерфейс, не согласовывая его с вашим API. В следующий раз пусть не думает об удобстве пользователя, все-таки в проекте есть вещи поважнее.
  • Ни в коем случае не пишите документацию. Простого вордовского файла на дропбоксе будет достаточно. В конце концов ваша работа — это струящиеся потоки данных, элегантные и высокопроизводительные. Пусть беспомощные мобильные разработчики почаще обращаются к вам за разъяснениями. Простого списка запросов без малейших примеров и описания им будет вполне достаточно. Ведь всегда можно заглянуть в ваш код и посмотреть все параметры и аргументы.
  • Не заморачивайтесь с названиями полей. Это нормально, что одна и та же сущность в разных местах называется по-разному, пусть поле, обозначающее количество объектов, в одном месте будет count, а в другом koli4estvo_kek. И так понятно, неужели не распарсят?
    И в смысле приходит разный тип данных? Ну да, в одном случае число, а в другом строка. Что не так?
  • Меняйте логику без предупреждения. Если вас озарило, то не медлите — срочно внедряйте. Не задумывайтесь о совместимости, не торопитесь обсуждать, просто делайте. И обязательно выкатывайте в релиз, дальше сами разберутся. Документацию тоже обновлять не обязательно, это все суррогат.



  • Ни в коем случае не пишите тесты и не проверяйте собственное API. Помните, вы не допускаете ошибок, это в приложениях вечно едут экранчики и что-то вылетает. Да и потом, понять, что найденная проблема находится все-таки на бэкенде — дело пары минут.
  • Не присылайте пояснения к ошибкам. Во-первых, они случаются крайне редко. Все должно идти идеально. Во-вторых, всем и так понятно почему что-то пошло не так. Простого http 400 или 500 (вишенка на торте) должно быть достаточно.
  • Отдавайте ответы в разных форматах. Пусть где-то будет json, а в другом месте xml. В конце концов, природа любит разнообразие.
    Цитата замечательных людей: 'А тут тоже в json ответ нужен что ли?'
  • Для авторизации используйте только cookie. Вас так вас в институте учили, когда вы делали свой первый интернет магазин. Ведь Android и iOS — это просто еще один браузер, не нужно преувеличивать их сложность.
  • Запомните: никаких тестовых данных, пусть разработчики руками генерируют весь контент. И не забывайте при этом каждый день очищать базу, это только добавляет азарта в работу.
  • Будьте бунтарем: принимайте параметры в POST через URL, ведь это тот же GET, только другой. Дайте волю воображению. И игнорируйте любые мольбы коллег привести все к стандартному виду, они просто не могут мыслить нестандартно.
  • Выносите максимальное количество логики на клиент. Сервер должен быть настолько легковесным, насколько возможно. Надо сделать рассылку по расписанию? На клиент, пусть крутит у себя таймер. Агрегация данных из трех разных источников? Туда же. У вас тут вообще-то нет фонового потока, который можно безнаказанно нагружать.

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


  • Не читайте документацию, всегда проще и быстрее спросить у коллеги. Даже если вас пятнадцать человек, он будет рад каждому объяснить еще раз.


    (Может быть, им просто одиноко и не с кем поговорить?)

  • Прося коллегу что-то переделать в API, не объясняйте причину. Если для него это не очевидно, то и объяснять бессмысленно, все равно не поймет.

Полезные рекомендации


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


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


Документация


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


Самый простой и удобный вариант — это использовать Swagger. Хоть его изначальный внешний вид и оставляет желать лучшего:



Но его можно без проблем облагородить с помощью форматтера:


Получается симпатично и удобно. В качестве альтернатив можно использовать Apiary, но придется разделять код и документацию, что нежелательно, либо заморачиваться с рендерингом.


Единообразие


В мобильной разработке есть сложность — многие решения и фреймворки крайне неповоротливы. Нельзя просто взять и поменять формат для какого-то одного конкретного запроса, либо это предельно сложно. Как и нельзя изменить название определенного поля только для определенного случая: бедный девелопер будет орать в голосину, пытаясь воткнуть под это костыль.


Все должно быть целостно: везде одинаковые названия, один формат взаимодействия (предпочтительно JSON), и тп.


Особенно хорошо, если названия параметров в запросе и ответе идеально совпадают с полями соответствующих классов в мобильном приложении. Звучит странно, но это настолько упрощает жизнь разработчикам, что они будут вам за это шоколадки таскать из магазина.


В некоторых местах упрощение доходит до абсурда: например, сохранение в Realm (мобильная база данных) может быть произведено практически сразу из json. Если будет интересно, то отдельно расскажу о том, как мы избавлялись от middleware в мобильном приложении.


Пример кода по сохранению любых пришедших объектов на iOS:

Один generic метод на любую запись в базу с сервера. Классно, правда?


Тоже самое касается и изображений. Лучше всего, когда на картинку сразу приходит ссылка, которую не нужно 'доделывать'. И по тому же правилу — название ссылки должно быть везде одинаковым.


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


Достаточность


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


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


Теперь понимаете, почему мобильные девелоперы стараются, чтобы все приходило в едином запросе? От этого зависит, уйдут они сегодня домой или нет)


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


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


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


Стабильность


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


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


В качестве бонуса хочется добавить, что здорово, когда есть pretty print, хотя бы на время разработки. Бывает, что надо разобраться с тем, что пришло от сервера, не заглядывая в документацию.


А что приятнее читать, такое:



Или такое:



Разница, мне кажется, на лицо.
Главное, не забудьте отключить Pretty Print на боевом сервере, поскольку ресурсов он жрет как не в себя.


Заключение


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


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