Для проекта документация — это не «формальность на потом», а рабочий инструмент. Она нужна, чтобы быстрее согласовывать решения между командами, проще вводить новых участников в контекст и заметно сокращать время разборов, когда что-то идет не так в проде.
В мире разработки программного обеспечения, особенно в условиях многокомандных проектов, эффективное межкомандное взаимодействие играет ключевую роль в успехе проекта. Одним из инструментов, который может значительно облегчить этот процесс, являются Sequence диаграммы.
В русской википедии они именуются как диаграммы последовательности.
Зачем вообще нужны Sequence диаграммы?
Sequence диаграммы являются графическими представлениями взаимодействия различных компонентов или участников в системе во времени. Они помогают разработчикам визуализировать последовательность вызовов методов или функций в процессе выполнения определенной функциональности. Это не только облегчает понимание работы системы, но и помогает выявить потенциальные проблемы или неоптимальные пути выполнения.
Почему удобнее их писать как код?
Поначалу я рисовал такие диаграммы в draw.io. Это было в целом достаточно утомительно.
Скачать файл диаграммы выше: sso-diagram.drawio.
Потом для меня открыли существование PlantUML. Написать первую диаграмму, используя текст, было тоже весьма утомительно, как и рисовать в draw.io. Но вот когда дело дошло до внесения изменений и когда потребовалось делать другие подобные диаграммы, тут в полной мере и раскрылись преимущества диаграмм в виде кода, а не рисунков.
- Ясность и точность
- Использование PlantUML для написания Sequence диаграмм в виде кода обеспечивает высокую ясность и точность в описании взаимодействия между компонентами. Код на PlantUML является формализованным и строгим, что исключает возможные неоднозначности или недопонимания при интерпретации диаграмм.
- Интеграция с документацией
- Sequence диаграммы, созданные на PlantUML, легко встраиваются в документацию проекта, такую как Confluence. Это обеспечивает удобный доступ к визуальным представлениям архитектуры и взаимодействия компонентов системы для всех участников проекта.
- Версионность изменений
- PlantUML дает возможность отслеживать изменения в диаграммах и контролировать их версионность. Это полезно при работе с Confluence, так как позволяет сохранять историю изменений и быстро восстанавливать предыдущие версии диаграмм при необходимости.
- Легкость внесения правок и создание последующих диаграмм
- Благодаря тому, что Sequence диаграммы на PlantUML представлены в виде кода, внесение правок становится простым и быстрым процессом. Кроме того, на основе существующего кода легко создавать последующие диаграммы, что способствует экономии времени и повышает эффективность работы команды.
К минусам кодирования диаграмм я отнёс бы разве что недостаточную гибкость в стилях отображения.
PlantUML
Диаграмму можно начать кодировать/рисовать в браузере:
https://www.plantuml.com/plantuml/uml/SyfFKj...
Если содержимое диаграммы является уязвимым с точки зрения конфиденциальности, можно запустить PlantUML через Docker локально, и тот же интерфейс в браузере будет доступен локально и без доступа в интернет.
https://hub.docker.com/r/plantuml/plantuml-server
Нумерация запросов
Диаграммы нужны для того, чтобы, с одной стороны, спроектировать и согласовать техническое решение между командами, а с другой стороны, в процессе эксплуатации реализованного решения в случае неполадок быстрее разобраться в причинах и адресовать проблему нужной команде.
Для обоих сценариев сильно помогает нумерация запросов на диаграмме. Если запросы пронумерованы, в коммуникации часто используется формат: «запрос 11 отправляет такие-то данные сервису вашей команды, а в ответе 12 приходят неожиданные данные». Это позволяет избегать запутанных и длинных конструкций.
Пример диаграммы для Single Sign-On
@startuml
<style>
group {
LineThickness 1
LineColor #4d4d4d
LineStyle 1
}
groupHeader {
LineThickness 1
LineStyle 1
}
</style>
skinparam sequence {
ArrowColor #000000
ActorBorderColor #000000
LifeLineBorderColor #000000
LifeLineBackgroundColor #FFFFFF
ParticipantBorderColor #000000
ParticipantBackgroundColor #FFFFFF
ParticipantFontColor #000000
BoxBorderColor #000000
BoxBackgroundColor #FFFFFF
BoxFontColor #000000 }
participant Customer order 10
participant Browser order 20 #fff2cc
participant App1 order 30 #dcebf7
participant App2 order 40 #e2efda
participant App3 order 50 #d9d2e9
participant App4 order 60 #F5F5F5
participant App5 order 70 #FCE4D6
group App1 Group Authentication
Customer -> Browser : A1. Go to App1
activate Browser
Browser -> App1 : A2. GET index
activate App1
App1 -> Browser : A3. index
deactivate App1
Customer -> Browser : A4. Click Login
Browser -> App2 : A5. GET authorization.oauth2, CustID: App1
activate App2
App2 -> Browser : A6. Login form
Customer -> Browser : A7. Login information
Browser -> App2 : A8. POST Login information
App2 --> Browser : A9. 302 Redirect + auth code
Browser -> App1 : A10. GET redirect uri_endpoint + auth hash
activate App1
App1 -> App2 : A11. Request access token by auth hash
App2 -> App1 : A12. Access Token + User_Info
App1 -> Browser : A13. Logged in content
deactivate App1
Browser -> Customer : A14. Logged in content
end
group App1 User Authentication
Customer -> Browser : B1. Click User Login
Browser -> App1 : B2. GET
activate App1
App1 -> Browser : B3. Login form
Customer -> Browser : B4. User Login information
Browser -> App1 : B5. POST User Login information
App1 -> Browser : B6. User Logged in content + Cookie with User Id
deactivate App1
Browser -> Customer : B7. User Logged in content
end
Customer -> Browser : C1. Go to App
Browser -> App3 : C2. GET initial URI (with ID, pass and language parameters)
activate App3
App3 --> Browser : C3. 302 Redirect to App2, set state parameter to 'initial URI'
Browser -> App2 : C4. GET authorization.oauth2, CustID: App1
App2 --> Browser : C5. 302 Redirect + auth hash
Browser -> App3 : C6. GET redirect uri_endpoint + auth hash
App3 -> App2 : C7. Request tokens by auth hash
App2 -> App3 : C8. Access, Refresh, Id Tokens
App3 --> Browser : C9. 302 Redirect to certain Data Center depending on User from Id Token, GET initial URI
deactivate App3
Browser -> App4 : C10. GET initial URI
activate App4
App4 --> Browser : C11. 302 Redirect to App2, set state parameter to 'initial URI'
Browser -> App2 : C12. GET authorization.oauth2, ClientID: App1
App2 --> Browser : C13. 302 Redirect + auth hash
Browser -> App4 : C14. GET redirect uri_endpoint + auth hash
App4 -> App2 : C15. Request tokens by auth hash
App2 -> App4 : C16. Access, Refresh, Id Tokens
deactivate App2
App4 -> App5 : C17. Socket: Id Token + User
activate App5
rnote over App5
App5 gets Id token,
extracts user information,
creates internal context
for this user
+ Login to User, if defined
endrnote
App5 -> App4 : 18. Success status
deactivate App5
App4 -> Browser : C19. App4 Logged in content, depending on parameters from App2 'state' about 'initial URI'
deactivate App4
Browser -> Customer : C20. App4 Logged in content
deactivate Browser
@enduml
Ссылка на полную версию этой диаграммы на PlantUML сервере: http://www.plantuml.com/plantuml/uml/fLLjRz....

