Клиент выбирает первый элемент ответа, но сервис не обещает порядок элементов. Какой дефект интеграционного контракта это выявляет?
Дефект заключается в том, что клиент использует незафиксированное свойство ответа: порядок элементов не является частью контракта. Контракт должен либо явно гарантировать порядок, включая правила разрешения одинаковых значений, либо клиент должен сам упорядочивать данные по переданному бизнес-полю.
В распределённых системах порядок записей часто является случайным побочным эффектом реализации: плана выполнения запроса, структуры индекса, репликации или текущего состояния хранилища. Пока данных мало и система не меняется, такое поведение может выглядеть стабильным, хотя гарантии у него нет.
Интеграционные контракты появились не только для описания формата данных, но и для фиксации их семантики. Для коллекций это включает порядок, уникальность, полноту выборки, правила пагинации и смысл отсутствующих элементов.
Если клиент считает первый элемент особым, а сервис порядок не гарантирует, результат может измениться после оптимизации запроса, переноса данных, переключения реплики или добавления нового элемента. Ошибка особенно опасна тем, что формально оба сервиса продолжают соблюдать свои неявные ожидания и сбой проявляется только на отдельных данных.
Если порядок влияет на бизнес-решение, например определяет приоритетный тариф или следующий шаг обработки, это уже не проблема отображения, а нарушение бизнес-логики. При пагинации ситуация усугубляется: нестабильный порядок может привести к пропускам или повторной выдаче элементов между страницами.
Нужно определить, что именно означает порядок. Возможны два корректных варианта:
Для воспроизводимого результата сортировка должна быть детерминированной. Если основное поле может совпадать, добавляют уникальный вторичный ключ как правило разрешения ничьих. Нельзя описывать контракт фразой «обычно возвращается сначала самый новый элемент»: это наблюдаемое поведение, а не гарантия.
При постраничной выдаче одного поля сортировки может быть недостаточно. Нужны стабильная комбинация полей и согласованный способ продолжения выборки, иначе изменения между запросами способны переместить элементы между страницами. Для бизнес-критичного выбора предпочтительно передавать явный признак приоритета, а не заставлять клиента выводить его из позиции элемента.
Гарантия порядка увеличивает ответственность сервиса: её нужно поддерживать при изменении хранилища и проверять контрактными тестами. Сортировка на стороне клиента уменьшает требования к сервису, но требует, чтобы все данные, необходимые для сортировки, входили в контракт, и может быть невозможна для больших коллекций без серверной пагинации.
Сервис рекомендаций возвращал список предложений. Мобильное приложение выбирало первый вариант как рекомендуемый, однако сервис документировал только состав списка. После перехода на реплику с другим индексом первым стал менее выгодный вариант, хотя данные и бизнес-правила не изменились.
Рассматривались три решения. Можно было сохранить текущую реализацию и полагаться на порядок хранения, но это не давало гарантии. Можно было сортировать весь список в приложении, однако клиенту не хватало части бизнес-признаков, а разные версии приложения могли сортировать по-разному. Выбранным решением стало добавление в контракт явного поля приоритета и серверной сортировки по приоритету с уникальным идентификатором как вторичным ключом.
После этого поведение стало одинаковым для клиентов и реплик. Отдельно добавили проверку контракта, которая фиксировала порядок при равных значениях приоритета; это предотвратило скрытую зависимость от порядка хранения.
Нет, если несколько элементов могут иметь одинаковое время с недостаточной точностью или одинаковый timestamp из разных источников. Нужен детерминированный tie-breaker, например уникальный идентификатор, а его направление и формат должны быть частью правил контракта.
Не всегда. Сортировка по неуникальному полю оставляет порядок равных элементов неопределённым. Кроме того, между страницами данные могут измениться, поэтому для стабильной пагинации требуется согласованный механизм продолжения выборки и ясное определение того, относительно какого состояния формируется результат.
Это определяется смыслом порядка. Если порядок выражает бизнес-правило или нужен для корректной пагинации, его обычно гарантирует сервис-владелец данных. Если это исключительно представление, например сортировка по имени на экране, её может выполнять клиент, но все необходимые поля и правила сравнения должны быть доступны ему явно.