API: общее

Korrekted
Korrekted
Last updated 

Общее

API приложения доступен по базовому пути https://app.buddo.io/api/. Тестовый контур находится по URL http://app.test.buddo.io/api/
 
Все вызовы осуществляются по протоколу POST (даже вызовы для получения информации), чтобы передаваемые параметры (в первую очередь API-ключ) были зашифрованы с помощью протокола HTTPS. Production-окружение работает по протоколу HTTPS, тестовое — по HTTP.
 
Реализация API предусматривает в первую очередь использование мобильными приложениями. Ниже будут описаны методы реализации безопасности, формат передачи данных, а также принципы корректного использования API.
 
Все маршруты в рамках каждого API делятся на два вида — те, которым требуется авторизация пользователя (для изменения, к примеру, личных данных, а также получения платного контента), и не требуется (для сохранения промежуточные данных до, к примеру, активации подписки). Теперь подробнее.
 

Формат запросов и ответов

При работе с API для ответов бекенда используется формат JSON. Все «системные» поля протокола содержат в названии префикс "_" (подчёркивание). В случае передачи данных на сервер существуют следующие системные поля:
-               _api_key — ключ для удалённого доступа из мобильного приложения (отличается для production- и тестового окружений)
-               _user_token — аутентификационный жетон пользователя, который можно получить при успешном логине. С помощью этого токена пользователь «представляется» методам API, которые касаются запроса или изменения личных данных/состояния.
 
В случае ответа системных полей будет как минимум три:
-               _code — код ответа (см. ниже)
-               _msg — ответ ("OK" или «человеческое» описание ошибки, которое следует при необходимости транслировать пользователю в интерфейс приложения)
-               _need_payment — флаг необходимости подтверждения оплаты для успешного выполнения запроса (true или false). Если флаг указан false, пользователя следует направить на пейгейт (т.е. экран активации подписки)
 
Эти три системных поля присутствуют в ответе от API всегда. Дополнительные поля при составлении запроса не должны содержать префикс «_». Точно также его не содержат и дополнительные поля ответов.
 

Коды ответов

На данный момент предусмотрены три группы ответов 2xx, 4xx и 5xx. Коды группы 4xx можно получить только на этапе аутентификации и авторизации. Коды группы 5xx можно получить при некорректной обработке данных (например, при ошибке валидации). Подробнее:
  • 200 — запрос выполнен успешно
  • 400 — критическая ошибка выполнения запроса, запрос никогда не сможет быть выполнен
  • 401 — предоставленный пользовательский токен или сессия устарела, требуется перелогин (или в случае этого конкретного приложения повторная валидация чека — об этом ниже)
  • 500 — ошибка обработки данных. Отправляется в случае некорректных данных
 

Использование API

При использовании API следует помнить два ключевых правила:
1. при каждом запросе требуется передавать API-ключ
2. для работы с данными конкретного пользователя нужно каждый каждый раз передавать полученный ранее пользовательский токен и автоматически «перелогинивать» пользователя при истечении срока действия токена
 
То есть каждый запрос к API должен сопровождаться передачей среди JSON-параметров ключа (параметр _api_key):
_api_key: "n2SgK3uHsQFd9g"
 
Запросы на просмотр и изменение личных данных должен сопровождаться передачей полученного ранее токена (системный параметр _user_token)
_user_token: "7QQBIsisvusxEGGXkYDdoTialGfTqXLxNB9w4rYAWr8B7OyrNcEb5XlrEBk4z5CnHLTMdSn9jvLrjjT6vyiBvE29fnePsQcaB5XOYkYiQJJa2Chyaz9FdcPtz3i2Uvcv"
 

Учётные записи в приложении

После исследования способов идентификации пользователей без явной процедуры создания учётной записи (с целью повышения конверсии), было принято решение выполнять логин пользователя по имеющемуся чеку от приложения.

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

Но original_transaction_id предоставляется исключительно в момент валидации существующего чека, который доступен только при наличии хотя бы одной активации подписки. Это означает, что все новые пользователи, скачавшие и запустившие приложение, будут неаутентифицированы и для них учётные записи заведены не будут. Такие пользователи будут проходить онбординг, данные о котором будут сохраняться локально в кеше и далее доступ к бесплатному контенту, эти пользователи будут получать анонимно. При попытке доступа к платному контенту (что контролируется бекендом) потребуется оплата, будет отображён пейгейт, и в случае активации подписки приложению будет выдан пользовательский токен, по которому далее будет получен доступ к платному контенту.

Следовательно, «под капотом» приложение может находиться в анонимном или авторизованном состоянии. Как следствие, общая схема работы в общем случае с учётными записями выглядит следующим образом:
  1. При холодном запуске приложения первым делом должно проверить наличие пользовательского токена (_user_token) в локальном хранилище и при его наличии проверить его валидность (по URL /api/check/user_token).
  2. Если токена для проверки нет или проверка показала, что он невалидный, следует получить и отправить имеющийся Apple-чек пользователя по URL /api/payments/validate — если у пользователя есть активированные ранее подписки, в ответ вернётся пользовательской токен (фактически, будет произведён логин). Если чека нет, на /api/payments/validate следует отправлять строчку "null" вместо чека.
Далее возможны три сценария ответа.

Сценарий №1: _user_token имеется, флаг active_subscription == true
Это благоприятный и самый простой сценарий. Пользователя мы знаем, у него точно есть доступ к контенту. В таком случае:
  1. Выполнять остальные запросы навигации пользователя
  2. Не рисовать замочки на карточках с контентом, так как у пользователя есть к нему доступ

Сценарий №2: нет ни _user_token, ни флага active_subscription
Это означает, что бекенд не может опознать пользователя, который к нему стучится. Это означает, что пользователя ни разу не оформлял подписку в приложении. В таком случае:
  1. Cледует показать онбординг. Факт прохождения онбординга сохраняется. По успешному завершению онбординга и перезапуску приложения онбординг более не показывается. В случае прерывания онбординга в середине и перезапуске приложения потребуется заново показать онбординг.
  2. Так как после окончания онбординга у приложения всё ещё нет _user_token, следует отображать экраны приложения с карточками контента, помеченные «замочками» (так как мы точно знаем, что у пользователя нет подписки)
  3. В случае обращения к контенту и получению вместо контента ошибки доступа и флаг _need_payment == true, следует показать пейгейт.
  4. После успешной активации подписки следует:
    • отправить чек на /api/payments/validate, что автоматически далее приведёт к сценарию №1
    • после получения пользовательского токена записать полученные во время онбординга данные в созданную учётную запись пользователя

Сценарий №3: есть _user_token, но флаг active_subscription == false
Данный сценарий означает, что перед нами пользователь, который ранее пробовал приложение. Здесь сценарий следующий:
  1. Следует отображать экраны приложения с карточками контента, помеченные «замочками» (так как мы точно знаем, что у пользователя нет подписки)
  2. В случае обращения к контенту и получению вместо контента ошибки доступа и флаг _need_payment == true, следует показать пейгейт
  3. В случае успешной активации подписки следует запросить /api/payments/validate, передав туда чек пользователя и его уже имеющийся _user_token (это особенно важно)
  4. Если активации подписки действительно прошла успешно, ответ от /api/payments/validate автоматически далее приведёт к сценарию №1

О пользовательских токенах

Каждый токен выдаётся сроком на 1 год. К примеру, при логине пользователя 17 марта 2019 года будет получен токен, действующий до 17 марта 2020 года. С полученным токеном можно выполнять действия от имени связанного пользователя вплоть до 17 марта 2020 года — затем потребуется заново получить токен.

Ключи для API

На тестовом контуре test.buddo.io — 1yyl1WBNrlD2MVK
На production-контуре buddo.io — xPh20WC5EYuboYQ

Методы API

Группа методов /api/check: https://public.3.basecamp.com/p/kSuQHU7aQ8umvy2qEHUfkrLf
Группа методов /api/users: hhttps://public.3.basecamp.com/p/rv9vzM77DFBrtPM4DmxYv5Qg
Группа методов /api/activation_codes:
https://public.3.basecamp.com/p/isotKCwQQzcenUS8qoReYHy5
Группа методов /api/payments: hhttps://public.3.basecamp.com/p/irDMw6zjNRNjiTTCAFHtS1gw
Группа методов /api/courses:
https://public.3.basecamp.com/p/YJC2rCRyCjBjuaxfKzCpkjHp
Группа методов /api/reviews:
https://public.3.basecamp.com/p/WmbYiyUdM8aJSXFWXHMikZhT
Группа методов /api/singles:
https://public.3.basecamp.com/p/UKb4SrKx1TT1XZZr6obTn8Fa
Группа методов /api/sleep:
https://public.3.basecamp.com/p/wUkbRmeoNiRepHNmkGyCkwm7
Группа методов /api/theory:
https://public.3.basecamp.com/p/F7fEpL9dtToe54ad1TUV9ZV6