Igor Kashkuta (Badoo), Клиент-серверный API глазами iOS разработчика, CodeFest 2017

16b6c87229eaf58768d25ed7b2bbbf52?s=47 CodeFest
January 31, 2018

Igor Kashkuta (Badoo), Клиент-серверный API глазами iOS разработчика, CodeFest 2017

https://2017.codefest.ru/lecture/1167

В мобильной разработке есть ряд особенностей, которые стоит учесть при проектировании протокола: наличие разных версий клиентов на бою, невозможность моментально пропатчить клиент, проблемы с доступом в Сеть и другие. На протяжении более чем пяти лет мы в Badoo занимаемся разработкой и поддержкой протокола клиент-серверного взаимодействия, рассчитанного на решение этих проблем. В докладе я расскажу о том, как он устроен с точки зрения iOS разработчика.
● Схема: protobuf и про что это вообще.
● Транспорт: почему (не) HTTP.
● Версионность или как быть со старыми клиентами.
● Клиентская часть.
● Документация.
● Практические примеры.

16b6c87229eaf58768d25ed7b2bbbf52?s=128

CodeFest

January 31, 2018
Tweet

Transcript

  1. Клиент-серверный API глазами iOS разработчика Игорь Кашкута

  2. Кратко о себе 2010 2011 2015 ! " !

  3. Client Backend API

  4. Client Backend API

  5. “ СОЗДАНИЕ И ПОДДЕРЖКА API — ОБЩЕЕ ДЕЛО

  6. 6 План Что может пойти не так с HTTP Что

    в таком случае делать Что делать в любом случае
  7. Как бывает HTTP

  8. 8 HTTP Стандарт Повсеместно распространен Библиотек, примеров, статей — множество

  9. 9 “Магазин”. День 0 Выбрали HTTP, почему нет GET запрос

    на список товаров, json в ответ GET запрос на детальное описание товара, json в ответ Остальное по аналогии Выпустили на iOS и Android
  10. 10 День 1 А давай добавим немного HTML в описание

    товара? Ну совсем чуть-чуть Да на самом деле хватит одного <b>
  11. 11 День 1. Мысли Нужна обратная совместимость для клиентов на

    бою Добавить параметр в запрос? Сделать новую версию api? Отдавать в ответе всё — и старое и c <b>? А что если в дальше понадобится <i>?
  12. 12 День 2 А давай сделаем чат? Пользователи будут в

    восторге! Причём давай наш собственный, с уникальными фичами
  13. 13 День 2. Мысли HTTP — однонаправленный. Клиент спросил —

    сервер ответил А тут надо в обе стороны… хм… Ок, быть может long polling сойдёт…
  14. 14 День 3 А давай раскатим чат только на часть

    аудитории? И сделаем A/B-тест!
  15. 15 День 3. Мысли Ок, добавим запрос на конфигурацию фичи

    В ответе также будет вариант A/B теста
  16. 16 День 4 А давай добавим ссылки в сообщения в

    чате? И чтобы они вели на другие экраны приложения И не забудь, теперь мы всегда выкатываем постепенно!
  17. 17 HTTP С развитием продукта просто HTTP не хватает Хочется

    чтобы API был про продукт, а не про стандарт Нужна идеология, план расширения
  18. Свой протокол Когда понятно, что не HTTP единым

  19. Свой протокол Заточен под продукт Больше возможностей Меньше неопределённостей Удобнее,

    потому что самим для себя Но имеет свою цену 19
  20. Badoo — MAPI Выкатили в 2010 Постоянно вносим изменения Поддерживаем

    пять платформ Прошли несколько мажорных редизайнов продукта Ни разу не хотели всё переделать 20
  21. Protobuf Типизированный формат описания данных Есть примитивные типы, перечисления и

    структуры Все поля структур опциональны Поля структур могут быть массивами 21
  22. Protobuf Набор генераторов кода для всех основных ЯП Превращает спеку

    в модель на выбранном языке Предоставляет де/сериализацию в бинарь и JSON 22
  23. Базовое сообщение Атом коммуникации От клиента к серверу и наоборот

    23
  24. message Message { uint32 message_id = 1; uint32 connection_id =

    2; repeated MessageBody bodies = 3; } 24
  25. struct Message { var messageId: UInt32? var connectionId: UInt32? var

    bodies: [MessageBody]? } 25
  26. MessageBody Состоит из типа и тела Все типы — значения

    перечисления Все тела — поля одной структуры. Это дёшево! Строгое соответствие тип → тело У сообщения тела может не быть 26
  27. struct MessageBody { var type: MessageType? var serverAppStartup: ServerAppStartup? var

    clientAppStartup: ClientAppStartup? var genericError: GenericError? […] } 27
  28. enum MessageType { case acknowledge // body: null case serverAppStartup

    // body: serverAppStartup case clientAppStartup // body: clientAppStartup case genericError // body: genericError […] } 28
  29. struct MessageBody { var type: MessageType? // = .serverAppStartup var

    serverAppStartup: ServerAppStartup? var clientAppStartup: ClientAppStartup? var genericError: GenericError? […] } 29
  30. struct MessageBody { var type: MessageType? // = .clientAppStartup var

    serverAppStartup: ServerAppStartup? var clientAppStartup: ClientAppStartup? var genericError: GenericError? […] } 30
  31. struct MessageBody { var type: MessageType? // = .genericError var

    serverAppStartup: ServerAppStartup? var clientAppStartup: ClientAppStartup? var genericError: GenericError? […] } 31
  32. MessageType Каждому сообщению соответствует набор ответов Ответ не нужен —

    тогда Acknowledge без тела 32
  33. enum MessageType { // response: clientAppStartup // response: genericError case

    serverAppStartup […] } 33
  34. Handshake 34 Client Server .serverAppStartup .clientAppStartup

  35. struct ServerAppStartup { var appVersion: String? var platformType: PlatformType? var

    deviceInfo: DeviceInfo? var sessionId: String? var capabilities: [CapabilityType]? var features: [FeatureType]? } 35
  36. enum CapabilityType { case supportsBoldTagInDescriptions case supportsItalicTagInDescriptions […] } enum

    FeatureType { case chat case nativeLinksInChat […] } 36
  37. struct ClientAppStartup { var features: [AppFeature]? […] } struct AppFeature

    { var type: FeatureType? var isEnabled: Bool? var abTestVariationId: String? } 37
  38. Транспортировка сообщений В HTTP каждый запрос независим от предыдущих В

    данном подходе предполагается обратное Бинарный формат Protobuf! 38
  39. HTTP/1.0 API 39 Client Server TCP HTTP json bytes TCP

    HTTP TCP
  40. HTTP/1.1 API 40 Client Server TCP HTTP json bytes HTTP

    HTTP HTTP
  41. Badoo MAPI 41 Client Server TCP CUSTOM binary protobuf bytes

  42. 2017 — WebSocket! 42 Client Server TCP WebSocket binary protobuf

    bytes
  43. Подвох Чтение траффика сложнее — это не Charles Нет открытых

    библиотек а-ля Alamofire Вряд ли подойдёт для публичных API 43
  44. Полезные советы Общие рекомендации

  45. Подробная документация — тоже API Описание Скриншоты Примеры запросов/ответов с

    данными Все граничные случаи 45
  46. Согласованность Весь набор документов — цельный продукт Изменения — атомарны

    Единый источник правды 46
  47. Изменения Только с одобрения всех действующих сторон В едином техническом

    стиле 47
  48. API — в репозиторий Атомарные изменения нескольких документов Каждому изменению

    — тикет с причиной Привычный процесс ревью, как с кодом Генерация вебсайта билд-системой Удобно подключается к кодобазам проектов 48
  49. Закрепим Участвуйте в создании и развитии API HTTP — не

    серебряная пуля Протокол под себя — дороже, зато удобнее Документация — максимально подробно, с примерами Всё — в репозиторий 49
  50. https://twitter.com/BadooTech Спасибо! @ikashkuta gmail, twitter, telegram, etc.

  51. 51 Дополнительные материалы Swift Protobuf Badoo Crazy Agile API Versioning

    strategy for a complex internal API Sphinx Google API Design Guide Logux Swarm.js