коротко

Sequence-диаграмма (UML) — это способ показать, как участники сценария обмениваются сообщениями во времени: время идёт сверху вниз, у каждого участника своя вертикальная линия жизни (lifeline), а стрелки между ними — это вызовы и ответы. Синхронный вызов рисуют сплошной стрелкой (->>), ответ на него — пунктирной (-->>), асинхронное сообщение — открытой стрелкой без обязательного ответа. Ветвление, опции, циклы и параллельность заворачивают в рамки-фрагменты alt, opt, loop, par. Для аналитика sequence — главный инструмент описания интеграционного сценария: кто кого зовёт и в каком порядке. Правило выбора: BPMN — про бизнес-процесс и роли (кто что делает), sequence — про обмен сообщениями между системами во времени, диаграмма состояний — про жизненный цикл одной сущности.

Однажды я описал интеграцию с платёжным провайдером прозой: «бэкенд создаёт платёж, провайдер уводит клиента на свою страницу, клиент платит, провайдер дёргает нас вебхуком, мы проверяем подпись и обновляем заказ». На ревью разработчик и тестировщик хором спросили разное. Разработчик: «А кто первым ходит в банк — мы или провайдер?» Тестировщик: «А мы ждём ответа синхронно или он прилетает вебхуком потом?» Я понял, что в тексте порядок вызовов читается криво: фразы идут одна за другой, но кто кого зовёт и где ответ, а где новое событие — не видно. Перерисовал ту же интеграцию sequence-диаграммой за двадцать минут, и оба вопроса отпали сами. С тех пор любой сценарий «несколько систем общаются по шагам» я рисую, а не описываю абзацем.

Sequence-диаграмма ровно для этого и придумана: она навязывает вам ось времени. Вы физически не можете нарисовать стрелку, не ответив на вопрос «кто отправитель, кто получатель и что это — вызов или ответ». В прозе же легко написать «системы синхронизируются» и не заметить, что вы не сказали, в какую сторону идёт первый запрос.

Что такое sequence-диаграмма

Sequence-диаграмма — одна из диаграмм UML, и отвечает она на узкий, но частый вопрос: как участники сценария обмениваются сообщениями во времени. Не «какие у системы части» и не «какие у заказа статусы», а именно «кто кого зовёт, в каком порядке и что приходит в ответ».

Диаграмму читают сверху вниз вдоль каждой линии жизни. Положение событий на одной линии и связи отправки с получением задают порядок. Для независимых событий у разных участников общий порядок может быть не определён: одно только расположение ниже не доказывает «строго позже». Расстояние между стрелками обычно не задаёт длительность — ограничения времени нужно указывать явно.

Из чего состоит диаграмма

Участники и линии жизни (lifelines). Каждый участник сценария — клиент, наш бэкенд, внешний сервис, база — это столбец сверху, от которого вниз тянется вертикальная пунктирная линия. Эта линия и есть lifeline — «жизнь» участника на протяжении сценария. Участником может быть человек, система, сервис, компонент — всё, что отправляет или получает сообщения.

Сообщения. Это горизонтальные стрелки между линиями жизни. Важно различать их тип, потому что от этого зависит смысл:

  • Синхронный вызов — сплошная линия с закрашенной стрелкой (в mermaid это ->>). Означает «я зову тебя и жду, пока ты ответишь». В моделируемом поведении вызывающий ждёт завершения вызова. Это не утверждение о блокировке всего сервиса или конкретного потока исполнения.
  • Ответ (return) — пунктирная стрелка обратно (-->>). Это не новый вызов, а возврат результата на предыдущий синхронный запрос. Пунктир — визуальный маркер «это ответ, а не инициатива».
  • Асинхронное сообщение — стрелка с открытым (незакрашенным) наконечником. Означает «я отправил и пошёл дальше, ответа здесь не жду». Так рисуют отправку события без ожидания результата обработки — подробнее про асинхронную интеграцию.

В Mermaid ->> задаёт вид стрелки, а не поведение программы. В этих примерах мы используем её для вызова с ожиданием ответа, -->> — для возврата, -) — для асинхронной отправки. Вебхук асинхронен относительно исходной операции, но его доставка по HTTP — отдельный запрос, на который получатель отвечает, например, 200 OK. Не убирайте этот ответ из схемы только из-за слова «вебхук».

Активация (execution specification). Узкий прямоугольник показывает выполнение поведения участника. Часто его рисуют от получения вызова до возврата, но это не единственный допустимый случай: выполнение может начаться и закончиться по другим событиям. Его длина сама по себе не измеряет загрузку процессора или время работы.

Фрагменты: alt, opt, loop, par

Простой сценарий — это прямая последовательность сообщений сверху вниз. Но в жизни почти всегда есть условия: «если оплата прошла — одно, если отказ — другое». Для этого в sequence есть фрагменты — рамки, которые оборачивают группу сообщений и помечены в левом верхнем углу типом.

  • alt (alternative) — ветвление «или-или». Рамка делится на части горизонтальной чертой, в каждой части — условие в квадратных скобках (например, «оплата успешна» / «отказ»). Выбирается не более одной ветки с истинным условием. Если подходящих условий нет и нет else, ветки не выполняются. Для понятного примера задавайте взаимоисключающие условия; порядок веток не следует автоматически считать приоритетом.
  • opt (optional) — опциональный блок: выполнится, только если условие истинно, иначе пропускается. Аналог if без else.
  • loop — цикл: блок повторяется, пока выполняется условие (например, «для каждой позиции заказа» или «пока статус = pending»).
  • par (parallel) — параллельность: события веток могут перемежаться, при этом порядок внутри каждой ветки сохраняется. Это не обещание физического выполнения в одну секунду; зависимости между ветками нужно показать отдельно.

Не злоупотребляйте фрагментами

Самая частая болезнь sequence-диаграмм — вложенные alt внутри loop внутри opt, после чего схему невозможно читать. Если сценарий распадается на три независимые ветки — нарисуйте три простые диаграммы вместо одной с тройным alt. Диаграмма должна экономить чтение, а не превращаться в ребус.

Когда брать sequence, а когда BPMN или состояния

Это вопрос, на котором путаются чаще всего, поэтому разберём по сути, а не по списку. Три нотации отвечают на три разных вопроса, и выбор идёт от вопроса, а не от привычки.

BPMN — про процесс и роли. Если вы описываете, как заявка проходит через отделы, где менеджер принимает решение, где процесс ждёт оплаты, кто за какой шаг отвечает, — это бизнес-процесс, и его место в BPMN с дорожками под роли. BPMN отвечает на «кто что делает в каком порядке». Подробнее — в записи какую нотацию когда использовать.

Sequence — про взаимодействие участников в сценарии. Она полезна при согласовании API, интеграций и взаимодействия внутренних компонентов: кто отправляет сообщение, кто получает, что ожидается в ответ. Участниками могут быть и люди. Выбор между sequence и BPMN определяется вопросом к модели, а не правилом «системы против людей».

Диаграмма состояний — про жизненный цикл одной сущности. Если вопрос звучит как «в каких статусах бывает заказ и какие переходы между ними разрешены» — это конечный автомат, а не sequence. Sequence описывает взаимодействие и может содержать несколько альтернативных путей; диаграмма состояний описывает состояния сущности и разрешённые переходы в выбранных границах модели. Подробнее — в записи про диаграммы состояний.

Пример: результат оплаты приходит вебхуком

Заказ уже создан и ожидает оплаты. Рассмотрим фрагмент интеграции после создания платежа: провайдер отдельно уведомляет бэкенд об окончательном результате. Здесь «оплачен» означает подтверждённое списание по договорённости с провайдером, а не только авторизацию или резервирование средств.

sequenceDiagram
  participant U as Браузер покупателя
  participant B as Бэкенд магазина
  participant P as Платёжный провайдер
  Note over B,P: Платёж создан ранее, связь платежа с заказом сохранена
  P->>B: POST вебхука (ID события, платёж, результат)
  B->>B: Проверить подлинность и связь с заказом
  alt Проверки пройдены
    B->>B: Идемпотентно сохранить событие и допустимый статус
    B-->>P: 200 OK
  else Запрос не прошёл проверку
    B-->>P: Ответ об отказе по контракту
  end
  U->>B: Получить текущий статус заказа
  B-->>U: Оплачен, отказ или ожидает подтверждения

Вебхук не является ответом на ранее созданный платёж: это новый HTTP-запрос. Подлинность проверяется для любого результата, а повтор одного события не должен повторно менять заказ. В этой схеме подтверждение провайдеру отправляется после сохранения результата; вариант с надёжным приёмом в очередь потребует другого обозначения момента подтверждения.

Браузер узнаёт статус отдельным запросом — бэкенд не может просто «отправить ответ» в уже завершённый HTTP-запрос. На рисунке проверка статуса стоит после вебхука. Если пользователь проверит раньше, он получит «ожидает подтверждения» и сможет повторить чтение. Редирект со страницы оплаты сам по себе не подтверждает списание.

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

Проверяйте смысл каждой стрелки

Кто отправляет сообщение, по какому каналу и в ответ на что? Название «Сообщить пользователю» не объясняет, будет это ответ на запрос, WebSocket или уведомление. Если важен обмен сообщениями — sequence поможет. Если важнее порядок работ и ветвления одного процесса, удобнее может оказаться BPMN или диаграмма деятельности. Самовызовы на sequence допустимы.

Пример с alt, opt и loop: календарь не ответил

Это отдельный учебный вариант интеграции MeetRoom. В сквозной статье рассматривается исходящий вебхук booking.created. Здесь мы намеренно разбираем другой контракт: обработчик вызывает API календаря и может запросить результат по ключу синхронизации.

Бронь уже сохранена, задание синхронизации надёжно зарегистрировано. Как согласовать эти записи, например через outbox, — отдельная задача. Календарь хранит внешнее представление брони; ошибка синхронизации её не отменяет. Условимся, что API различает подтверждённый результат и «пока неизвестно». Обычный ответ «не найдено» не считаем доказательством, что создание точно не состоялось.

На узком экране схему можно прокрутить по горизонтали; исходник доступен ниже.

%% Отдельный учебный вариант MeetRoom: прямой API календаря, не исходящий вебхук.
%% Бронь уже создана; календарь хранит её внешнее представление.
%% API поддерживает ключ операции и достоверный поиск результата по нему.
sequenceDiagram
  participant W as Обработчик синхронизации
  participant C as API календаря
  Note over W,C: Бронь сохранена, задание синхронизации надёжно зарегистрировано
  W->>C: Создать событие (ключ синхронизации)
  alt Получен успешный ответ
    C-->>W: ID созданного события
    W->>W: Сохранить ID, статус synced
  else Получен явный отказ без создания события
    C-->>W: Ошибка валидации
    W->>W: Сохранить причину, статус failed
  else До срока ожидания ответ не получен
    Note over W,C: Это отсутствие ответа, а не сообщение от календаря
    W->>W: Статус unknown
  end
  opt Статус unknown
    loop Пока unknown, не более 3 попыток сверки
      W->>W: Выдержать паузу перед попыткой
      W->>C: Найти результат по ключу синхронизации
      alt Получен окончательный результат
        C-->>W: ID события или подтверждённый отказ
        W->>W: Сохранить synced или failed
      else API пока не знает результата
        C-->>W: Пока неизвестен
        W->>W: Оставить unknown
      else Ответ на сверку не получен
        Note over W,C: Истёк срок ожидания ответа
        W->>W: Оставить unknown
      end
    end
    opt После сверки остался unknown
      W->>W: Зарегистрировать необходимость дальнейшего разбора
    end
  end

В первом alt разделены три наблюдения: успех, явный отказ без побочного эффекта и отсутствие ответа до срока ожидания. Последнее оставляет статус unknown. Рядом с тайм-аутом нет стрелки «ошибка от календаря»: сообщение могло вообще не прийти.

opt запускает сверку только для unknown. loop ограничивает её тремя попытками с паузами — число выбрано для упражнения. Окончательный результат завершает сверку, отсутствие результата сохраняет unknown. После исчерпания попыток нужен дальнейший разбор; автоматически объявлять failed нельзя. Политика повторов и способ такого разбора определяются реальным контрактом и требованиями к эксплуатации.

Исходник Mermaid — скопировать и изменить
%% Отдельный учебный вариант MeetRoom: прямой API календаря, не исходящий вебхук.
%% Бронь уже создана; календарь хранит её внешнее представление.
%% API поддерживает ключ операции и достоверный поиск результата по нему.
sequenceDiagram
  participant W as Обработчик синхронизации
  participant C as API календаря
  Note over W,C: Бронь сохранена, задание синхронизации надёжно зарегистрировано
  W->>C: Создать событие (ключ синхронизации)
  alt Получен успешный ответ
    C-->>W: ID созданного события
    W->>W: Сохранить ID, статус synced
  else Получен явный отказ без создания события
    C-->>W: Ошибка валидации
    W->>W: Сохранить причину, статус failed
  else До срока ожидания ответ не получен
    Note over W,C: Это отсутствие ответа, а не сообщение от календаря
    W->>W: Статус unknown
  end
  opt Статус unknown
    loop Пока unknown, не более 3 попыток сверки
      W->>W: Выдержать паузу перед попыткой
      W->>C: Найти результат по ключу синхронизации
      alt Получен окончательный результат
        C-->>W: ID события или подтверждённый отказ
        W->>W: Сохранить synced или failed
      else API пока не знает результата
        C-->>W: Пока неизвестен
        W->>W: Оставить unknown
      else Ответ на сверку не получен
        Note over W,C: Истёк срок ожидания ответа
        W->>W: Оставить unknown
      end
    end
    opt После сверки остался unknown
      W->>W: Зарегистрировать необходимость дальнейшего разбора
    end
  end

Открыть исходник диаграммы (.mmd). Если API не поддерживает надёжную сверку по ключу, этот пример нельзя переносить без изменения контракта.

Проверьте решение

После тайм-аута коллега предлагает создать событие с новым ключом. При каких условиях появится дубль? Почему повтор со старым ключом безопасен только при согласованных гарантиях идемпотентности и сроке хранения ключей? Разберите идемпотентность, затем проверьте контракт API в тренажёре.

Когда что брать

Вопрос, на который отвечаетеНотацияЧто в центре
Как системы обмениваются сообщениями во времени (интеграционный сценарий)UML sequenceСообщения между участниками, порядок, ответы
Кто что делает в бизнес-процессе, в каком порядке, кто за что отвечаетBPMNШаги, роли (дорожки), развилки процесса
В каких состояниях бывает одна сущность и какие переходы разрешеныДиаграмма состоянийСостояния и переходы одной сущности

UML и Mermaid — разные уровни

UML определяет смысл участников, сообщений и фрагментов; Mermaid — способ записать и отрисовать схему. Не вся семантика UML автоматически проверяется Mermaid. Успешная отрисовка подтверждает синтаксис, но не полноту сценария и не правильность контракта.

Как проверить свой разбор

Попросите коллегу восстановить сценарий по схеме: кто инициирует взаимодействие, откуда берётся окончательный результат, что происходит при явном отказе и отсутствии ответа. Количество фрагментов alt не определяет качество ответа. Важнее согласованные границы, условия веток и то, что схема не обещает поведение, которого нет в контракте.

Частые вопросы

Чем sequence-диаграмма отличается от BPMN?

Sequence показывает взаимодействие участников через сообщения. BPMN моделирует ход процесса, события, работы и управление потоками. Обе нотации могут описывать людей и системы; выбирайте по вопросу, который нужно согласовать.

Что значат сплошная и пунктирная стрелки?

В UML учитываются линия и наконечник: синхронный вызов, асинхронное сообщение и возврат имеют разное обозначение. В примерах Mermaid здесь ->> используется для вызова с ожиданием, -->> — для ответа, -) — для асинхронной отправки. Смысл закрепляйте легендой: вид линии без контекста не описывает весь контракт интеграции.

Что означают alt, opt, loop и par?

alt выбирает не более одной подходящей альтернативы; opt включает необязательный фрагмент по условию; loop задаёт повторение с условием и ограничениями; par допускает перемежение веток с сохранением порядка внутри каждой. Ветки par не обязаны начинаться физически одновременно.

Семантика взаимодействий: OMG UML 2.5.1, раздел Interactions. Синтаксис примеров: документация Mermaid.