Как сделать API удобным для клиентов, особенно мобильных клиентов:)
Вынесенный в название вопрос кажется парадоксальным — ведь обычно API проектируется как контракт между поставщиками и потребителями программных интерфейсов, а контракт обычно должен быть удобным для всех участников. Но на самом деле вопрос не праздный. В этой статье мы попробуем ответить на него:)
И начнем мы с обсуждения того, как API обычно выглядит глазами поставщиков API (рис. 1). Кажется, что все удобно и на своем месте:
- есть ряд endpoint’ ов
- есть ряд клиентов, которые обращаются в эти endpoint’ы за данными

Но если взглянуть на ту же ситуацию глазами клиента, то можно увидеть, что он обычно вынужден интегрироваться с кучей разных разномастных API и зачастую заниматься объединением данных на своей стороне. А если это мобильный клиент, то это не комильфо по нескольким причинам:
- реализация логики объединения данных на стороне клиента приводит к tight coupling между мобильным приложением и API, а с учетом того, что мобильные приложения живут долго, то это связь тянется тоже дооооолго — дальнейшая эволюция мобильных приложений и API затруднена
- если приложения пишутся нативные, то часто требуется эту логику реализовывать несколько раз — а именно под Android и под iOS
- реализация сложного объединения данных фактически на фронте — это не профильная задача мобильных разработчиков, т.е. мы не оптимально используем разделение труда
- при необходимости изменения логики объединения данных нужен релиз мобильного приложения — а это гораздо дольше и заметнее изменения бекенд сервисов

Возникает вопрос, а как же это можно изменить эту ситуацию к лучшему? И к счастью ответ на этот вопрос дан уже до нас:)
Нам просто нужны удобные фасады, которые позволят получать ответы нужные клиенту сразу в агрегированном виде. Среди стандартных вариантов есть 2 особо популярных:
- использование архитектурного паттерны Backend For Fronted или для краткости BFF
- предоставление API в виде GraphQL — open-source языка для выборок и манипуляции данными при обращениях через API
По-факту, оба этих варианта позволяют создать некую абстракцию, когда сложность скрыта за фасадом и клиент наслаждается удобным API.

Давайте сравним эти варианты. Сводные таблички представлены на рисунке 4.

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

Если бы мне пришлось выбирать как сделать API удобным, то я бы выбрал вариант с BFF, опираясь на свой текущий опыт. Мне кажется, что формат с query language оставляет слишком много свободы клиентской стороне и требует более аккуратного обращения, чтобы не выстрелить себе в ногу.
Источники
- Pattern: Backends For Frontends — определение от Сэма Ньюмана
- GraphQL — страничка с Wikipedia
- Backends For Frontends — в радаре от ThoughtWorks
- Pattern: API Gateway / Backends for Frontends — Крис Ричардсон смешивает паттерны BFF и API Gateway
- Backends for Frontends pattern — описание паттерна BFF от Microsoft
- Create a backend for frontend application architecture — описание от IBM
- GraphQL — официальная страничка языка