Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

CodeFest
January 31, 2018

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

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

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

CodeFest

January 31, 2018
Tweet

More Decks by CodeFest

Other Decks in Technology

Transcript

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

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

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

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

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

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

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

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

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

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

    чтобы API был про продукт, а не про стандарт Нужна идеология, план расширения
  11. Badoo — MAPI Выкатили в 2010 Постоянно вносим изменения Поддерживаем

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

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

    в модель на выбранном языке Предоставляет де/сериализацию в бинарь и JSON 22
  14. message Message { uint32 message_id = 1; uint32 connection_id =

    2; repeated MessageBody bodies = 3; } 24
  15. MessageBody Состоит из типа и тела Все типы — значения

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

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

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

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

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

    serverAppStartup: ServerAppStartup? var clientAppStartup: ClientAppStartup? var genericError: GenericError? […] } 31
  21. struct ServerAppStartup { var appVersion: String? var platformType: PlatformType? var

    deviceInfo: DeviceInfo? var sessionId: String? var capabilities: [CapabilityType]? var features: [FeatureType]? } 35
  22. struct ClientAppStartup { var features: [AppFeature]? […] } struct AppFeature

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

    данном подходе предполагается обратное Бинарный формат Protobuf! 38
  24. Подвох Чтение траффика сложнее — это не Charles Нет открытых

    библиотек а-ля Alamofire Вряд ли подойдёт для публичных API 43
  25. API — в репозиторий Атомарные изменения нескольких документов Каждому изменению

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

    серебряная пуля Протокол под себя — дороже, зато удобнее Документация — максимально подробно, с примерами Всё — в репозиторий 49
  27. 51 Дополнительные материалы Swift Protobuf Badoo Crazy Agile API Versioning

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