Системный сервант @breakfront Channel on Telegram

Системный сервант

@breakfront


Заметки про IT, системный анализ и интеграции.

Личный блог: https://t.me/howToBeTanya

Системный сервант (Russian)

Системный сервант - канал, который обязательно понравится всем, кто интересуется IT, системным анализом и интеграциями. Здесь вы найдете множество полезных заметок, статей и обсуждений на эти темы. Если вы хотите быть в курсе последних технологических новинок, узнать о лучших практиках в сфере IT и поделиться своим опытом с другими специалистами, то этот канал идеально подойдет для вас. Не упустите возможность присоединиться к сообществу Системный сервант и узнать много нового и интересного в области информационных технологий!

Системный сервант

08 Oct, 13:22


Как познакомиться с GraphQL:

1. Посмотреть вебинар.
2. Почитать официальную документацию(она короткая, но на английском).
3. Потренироваться на тестовых и открытых API:
▫️ Тестовый API выдуманной горнолыжной базы - https://snowtooth.moonhighway.com/,
▫️ SWAPI на GraphQL - https://graphql.org/swapi-graphql/,
▫️ API GitHub - https://docs.github.com/ru/graphql/overview/explorer,
▫️ Еще много открытых API: https://github.com/graphql-kit/graphql-apis (не все сейчас работают, но какие-то можно посмотреть).

Тестовые и открытые API взяты из книги “GraphQL” Алекс Бэнкс, Ева Порселло - ее можно почитать, если хочется углубить знания технологии.

Системный сервант

19 Sep, 03:37


Чем опасен PATCH?

На собеседованиях часто спрашивают, чем отличается PUT от PATCH.

Самый простой ответ - что PATCH предназначен для частичного изменения ресурса, в то время как PUT всегда меняет ресурс полностью.

Рассмотрим пример ресурса с пользователем:

{
"id": 1,
"name": "John Doe",
"email": "[email protected]",
"phone": "12345678"
}


Метод PATCH может позволять менять параметры ресурса по отдельности.


PATCH /users/1

{
"email": "[email protected]"
}


PUT же требует отправки всех полей ресурса, даже если меняется только одно из них.

На этом уровне кажется, что PATCH - хороший способ оптимизировать размер запросов и увеличить гибкость API.

Но если копнуть немного глубже, то появляется идемпотентность. Операция считается идемпотентной, если её повторное выполнение не изменяет результат после первого применения.

PUT должен быть всегда идемпотентным. В то время как идемпотеность PATCH зависит от реализации. Эта вариативность тоже добавляет гибкости, но несет больше рисков и требует больше внимания команды к разработке и поддержке таких методов.

Также, даже если мы сделали PATCH идемпотентным, его применение может привести к нарушению целостности данных. Допустим, мы делаем вызов с удалением email:


PATCH /users/1

{
"email": null
}


Примерно в это же время кто-то сделал другой вызов, с удалением номера телефона:


PATCH /users/1

{
"phone": null
}


Однако, по бизнес-правилам у пользователя должен быть заполнен либо email, либо телефон.

Значит, надо это заранее продумать и добавить дополнительную проверку в момент транзакции в БД. В то время как в методе PUT мы бы могли ограничиться валидацией на поля запроса.

Более того, какой-то из клиентов получит в ответе ошибку, хотя с его точки зрения он делал все правильно и конфликта быть не должно. PUT же делает для клиента очевидным результат запроса в разрезе всего ресурса и минимизирует шанс получить противоречия в значениях параметров.

Таким образом, PATCH - гибкий и мощный инструмент HTTP, но использовать его стоит с осторожностью. И точно не стоит его применять по умолчанию везде, где нужно обновление ресурса.

Системный сервант

20 Aug, 16:19


Открываю портал в дискуссию на тему “Надо ли читать “Проектирование требований к ПО” К. Вигерса и Дж. Битти в 2024 году?”

Напишу свое мнение по этому поводу.

Это фундаментальная книга с подробным описанием базовых паттернов проектирования ПО. Пять лет назад я была уверена, что эта книга должна быть обязательной для всех IT-специалистов, а не только для аналитиков. В ней описано, как подходить к разработке так, чтобы не переделывать или закрывать продукты сразу после релиза. Книга предлагает системный подход к проектированию и помогает оптимально выстроить процесс работы: сначала разобраться, что и зачем нужно сделать, и только потом приступать к работе. Об этом я даже писала статью.

Однако, мир изменился: сейчас везде гибкие методологии и быстрые запуски (по крайней мере в планах). Как правило, при планировании продукта времени на обследование и разработку требований закладывается мало или не закладывается совсем. Также не очень понятно, как этот процесс по выявлению бизнес-, пользовательских, функциональных и нефункциональных требований запихнуть в двухнедельные спринты. От продуктовых команд ожидается очень быстрый результат, который достигается в основном за счет качества.

Также сильно изменились требования к аналитикам. Сейчас от нас больше ожидают умение описать контракты API, структуры БД и интеграционные схемы. А разобрался ли аналитик, нужен этот функционал бизнесу или нет - беспокоит далеко не всех нанимающих менеджеров. Во время последних поисков работы в 2021 году про процесс разработки требований меня спросили где-то в 5 компаниях из 10.

На мой взгляд это не очень хороший тренд. На практике, какие бы амбициозные цели менеджеры не ставили - что-то серьезное меньше чем за полгода-год запустить не получается. В этот срок вполне можно поместить вдумчивое проектирование. Но вместо этого разработка идет по рваному скачкообразному процессу, где за день до релиза выясняется, что не сделан большой и важный кусок, без которого вообще никак. Релиз откладывается на 2 месяца, а в конце этого срока история повторяется.

При этом я считаю agile хорошим подходом, который помогает поставлять больше полезных и нужных фичей. Очень важно находиться в постоянном контакте с заказчиком и сверяться с реальностью. Но не всегда следует начинать кодить сразу после того, как заказчику пришла в голову какая-то идея. Иногда лучше остановиться, подумать, применить к задаче какие-то инструменты анализа.

Сейчас я стараюсь использовать паттерны из книги выборочно, в зависимости от контекста и ситуации. Редко получается пройти полный цикл разработки требований, но знания об идеальном процессе помогают выбрать оптимальные техники для каждой конкретной ситуации. Поэтому я за то, чтобы читать и перечитывать Вигерса, но относиться к книге скорее как к набору инструментов, а не как к непреложному алгоритму работы.

А вы как считаете, нужна ли сегодня эта книга и описанные в ней приемы? И часто ли вы сталкиваетесь с неприятностями, которых можно было бы избежать, выдели команда больше времени на проработку требований?

Системный сервант

01 Aug, 17:31


За 5 лет, что я проектирую API, вывела для себя шесть базовых принципов, которым полезно придерживаться. Собрала эти принципы в чек-лист.

Системный сервант

12 Jul, 11:04


Написала про интересный интеграционный кейс: проблему зависимых сообщений. А также про такие способы ее решения, как Dead Letter и Inbox.

Cтатья на medium и тоже самое, но без VPN.

Если вы встречались с подобной проблемой - напишите в комментариях, как ее решили? Как в итоге проявило себя решение в процессе эксплуатации?

На моем проекте мы выбрали Inbox, причем сначала сохраняли туда только зависимые и проблемные сообщения. После начала эксплуатации пришли к выводу, что лучше все-таки сохранять в inbox все сообщения, чтобы использовать его возможности по полной.
Спустя какое-то время потребовалась оптимизация логики обработки. Но в итоге решением довольны - у нас есть гарантия обработки сообщения хотя бы 1 раз, сообщения не теряются и обрабатываются корректно.

Системный сервант

02 Jul, 20:41


Пока я планирую следующие посты и вообще чаще писать в этот канал, поделюсь еще одной хорошей инфографикой от ByteByteGo.

UPD: @and_burakov правильно заметил, что протоколами это все называть не совсем корректно, API technologies - более точное словосочетание.

Системный сервант

07 Dec, 07:09


А вот и сама инфографика

Системный сервант

07 Dec, 07:08


В одной из рассылок от ByteByteGo пришла прекрасная инфографика с 12 способами сделать API безопаснее. Буду по мере сил публиковать более подробное описание каждого из пунктов.

Итак, первый способ - это HTTPS

HTTPS  -  это HTTP с обеспечением безопасности (HTTP over TLS/SSL).

В рамках взаимодействия по HTTPS происходит шифрование данных и проверка сертификатов. 

При установке соединения сервер отправляет клиенту свой сертификат и открытый ключ (public key). На основе открытого ключа генерируются сессионные ключи (session key), которые живут только одну сессию.

Далее с помощью session key клиент сверяет данные из сертификата с данными сервера, от которого приходят запросы. Если данные (например, имя) сервера не совпадают с указанными в сертификате - клиент может прервать соединение, либо сообщить о проблеме пользователю.

Аналогичным образом сервер может проверять сертификат клиента. Так HTTPS-соединение помогает избежать перехвата данных. 

Но даже если данные будут перехвачены - их нельзя будет просто так прочитать. Так как HTTPS обеспечивает шифрование данных. Расшифровать сообщения можно только с помощью закрытого ключа (private key).

Часто, при взаимодействиях внутри контура компании, HTTPS-ресурс используют именно при аутентификации/получении токена. А дальнейшее взаимодействие идет по обычному HTTP.
То есть создается отдельный API для авторизации - туда по HTTPS передается логин и пароль. В ответ сервис авторизации присылает токены.
Далее клиент с этими токенами идет в API сервисов, содержащих нужные ему данные. Особенно это удобно при микросервисной архитектуре - клиенту не нужно проходить аутентификацию в каждом из сотни микросервисов.

Если взаимодействие между сервисами происходит под VPN, то часто в HTTPS нет необходимости.
Но все же так шанс перехватить токен становится выше, поэтому важно, чтобы время жизни токена было небольшое.

Источники:
- https://www.cloudflare.com/learning/ssl/what-is-a-session-key/
- https://ru.wikipedia.org/wiki/HTTPS
- https://en.wikipedia.org/wiki/HTTPS
- Вот тут можно почитать, зачем сайтам использовать HTTPS и как это влияет на SEO

Системный сервант

02 Dec, 18:37


Написала, почему так важно при разработке смотреть на реальные данные.

Системный сервант

21 Jul, 00:15


Что можно почитать и послушать, чтобы познакомиться с обменом сообщениями/брокерами сообщений/Kafka/Event Driven Architecture (EDA):

1. Базовая книга “Шаблоны интеграций корпоративных приложений” Г. Хоп и Б. Вульф - в плане практических примеров может быть где-то устарела, но основные паттерны и понятия интеграции через обмен сообщениями там есть и довольно хорошо описаны.
2. “Микросервисы. Паттерны разработки и рефакторинга” К. Ричардсон - хорошая книга, чтобы познакомиться со всеми современными способами интеграций. В главах 5 и 6 дается базовое разъяснение EDA, Event Streaming и Event Sourcing и зачем они вообще нужны.
3. Выпуск подскаста Podlodka про менеджеры очередей
4. Выпуск подскаста Podlodka про EDA (на самом деле больше про Kafka)
5. Отдельная статья про Event Streaming and Event Sourcing
6. И про outbox pattern - хороший способ реализации отправки сообщений из БД

Системный сервант

29 May, 17:04


У systems.education тут стартовал новый воркшоп по очередям и кафкам: https://systems.education/kafka-workshop.

Будет интересно тем, кто хочет все потрогать руками, я вот записалась)

Системный сервант

04 Feb, 21:14


#breakfront_tooltips #breakfront_analysis_fails

ДОСТУП К ДАННЫМ В API

Чтобы подобраться к данным из API клиент, как правило, проходит два этапа: аутентификация и авторизация.

Аутентификация - это проверка подлинности пользователя (правильный логин и пароль, например). Очень часто клиент проходит аутентификацию и получает JWT-токен, с которым делает запросы к API разных сервисов. Сервисы проверяют подлинность и актуальность этого токена при каждом запросе. У токена задается время жизни, по прошествии которого токен надо обновить. Если токен неверный или “протух”, API ответит на вызов ошибкой.

Примечательно, что даже сервис, который сам не генерировал JWT-токен, имея соответсвующий ключ, может проверить подлинность и актуальность токена. Что делает эту технологию очень удобной в случае сервисно-ориентированной и микросервисной архитектуры: достаточно сделать один сервис аутентификации, который будет хранить данные клиентов, выдавать токены и заботиться о безопасности, а остальные сервисы будут иметь дело только с токенами.

Также в JWT-токене может быть какой-то payload, то есть “полезная нагрузка”: данные, которые можно передавать прямо в токене, сообщая что-то сервису. Например, там может быть id пользователя, его роль и доступы и пр. В интересах безопасности payload можно зашифровать. Но, например, в системах, работающих в контуре компании под VPN какие-то данные можно передавать открыто и тогда их легко получить сразу из токена.

Тема аутентификации очень обширна и технически нетривиальна. Но часто в компаниях принят единый стандарт аутентификации, разработкой этого сервиса занимается отдельная команда с активным участием отдела безопасности. Остальным остается только получать и проверять токены:)

Вот с авторизацией проектировщики API работают гораздо чаще.

Авторизация - это проверка, есть ли у пользователя права на выполнение действия.

На поверхности авторизации лежит ролевая модель и доступ к ресурсам по ролям. Пользователи с ролью “сотрудник” не имеют доступа к ресурсу с зарплатами, в отличие от пользователей с ролью “руководитель”. Может быть более сложная логика: пользователи с ролью “продавец” видят только товары со статусом “готово к продаже”.

Есть и менее очевидные правила доступа, которые, бывает, упускают, особенно если API не имеет пользовательского интерфейса и предназначено для других систем.

Например, если вы служба доставки, которая предоставляет API для магазинов. Делать разный API под каждый магазин довольно накладно, тем более что процесс у вас со всеми примерно одинаковый.

Вы предоставляете один интерфейс для всех. Причем магазины и сети магазинов делают на своей стороне интерфейс для продавцов. То есть на каждого вашего партнера-организации приходится какое-то количество пользователей.

Скорее всего, у вас будет метод получения заказа по UUID/GUID. И критически важно не давать пользователю из одного магазина получать заказы другого магазина. Просто представьте, что будет, если через ваш API ВкусВилл сможет получать заказы для X5.

То есть нам нужно не только понимать подлинность токена пользователя, но и то, что пользователь работает именно в той организации, которой принадлежит заказ. Для этого нужно произвести ряд логических операций и, возможно, вызовов к другим сервисам: получить организацию заказа, получить организацию, в которой зарегистрирован пользователь, сравнить их, обработать ошибку.

Кто-то вам может сказать: зачем заморачиваться, у нас же заказы не инкрементом пронумерованы, а UUID/GUID - их очень сложно подобрать. Но их же можно и не перебором вычислять, а, например, перехватить какие-то вызовы и разжиться нужным списком идентификаторов. Конечно, случайно это сделать не получится, но компании могут на многое пойти, чтобы узнать о продажах своих конкурентов.

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

Системный сервант

01 Nov, 14:26


Подготовила совместно с systems.education воркшоп по проектированию интеграций c REST-like API.

Очень рада, что получилось реализовать эту задумку. Лично мне не хватало материалов, где бы рассказывали про процесс интеграции целиком, а не только про методы, способы и прочие «кусочки пазла». Училась этому на своих и чужих ошибках, по частям выхватывала информацию из разных источников. Поэтому особенно приятно сформулировать свой подход в цельный процесс.

В итоге на воркшопе проектируем интеграцию по шагам - от общего к частному. От бизнес-задачи до контракта API.

Мы уже провели несколько пилотов, так что 12-13 ноября будет обкатанная и “зрелая” программа.
Особенно подойдет тем, кто еще не работал с интеграциями или работал, но чуть-чуть. Но также поможет структурировать знания и, возможно, познакомиться с новым подходом более опытным коллегам.

Записаться можно тут: https://systems.education/rest-workshop

Системный сервант

18 Sep, 09:22


Ооо, возвращение легенды! Если где и учиться сбору требований, то здесь: https://t.me/systems_education/245

Системный сервант

11 Aug, 20:23


#breakfront_tooltips

Идентификаторы

В информационных системах, и особенно в их базах данных, необходимо использовать уникальные идентификаторы для объектов. Как правило, это числовые или текстовые поля.

Например, заказ в интернет-магазине мы все привыкли идентифицировать по номеру. Обычно это человекочитаемый код, вроде 34538.

Можно предположить, что всего у интернет-магазина на момент нашего заказа было 34537 заказов в базе. То есть в качестве идентификатора заказа система интернет-магазина генерирует десятичные целые числа путем автоинкремента. То есть при создании заказа БД прибавляет к Id последнего объекта 1.

Это довольно распространенная практика, простая в реализации и понятная всем людям. То есть директор интернет-магазина посмотрит на номер последнего заказа сразу поймет, сколько у него всего было заказов.

Но если директор поймет, то и конкурент поймет. Более того, конкурент может вычислить разницу номеров и понять, сколько заказов приходит в день, неделю, месяц. Так он поймет примерное количество клиентов, пики и спады продаж. И даже какие из наших маркетинговые активностей работают, а какие - нет.

Еще, если я на странице своего заказа вижу ссылку http://store.ru/order/3 - ничего не мешает мне заменить 3 на 2 и потенциально увидеть заказ другого пользователя. Если доступ к нему не закрыли, конечно. Однако часто этот доступ не закрыт:)

В общем, порядковый номер заказа в БД - чувствительная информация, часто закрытая договорами о неразглашении.

Что же делать? Можно путать следы: начинать отсчет с 10000, например. Но в целом от перечисленных опасностей это не спасает.

Часто используют какой-то составной код, сформированный по внутренней логике приложения. Например, “номер заказа в регионе”-”номер заказа у пользователя”. Кажется, примерно такой способ сейчас используют все крупные e-commerce игроки, когда показывают номер заказа покупателям. Потому что им важно, чтобы человек увидел свой заказ и не впал в ступор. Чтобы он мог где-то внести номер этого заказа или сказать его сотруднику магазина.

Этот способ не очень удобен тем, что нужно поддерживать внутреннюю логику генерации этих кодов. Особенно проблематично, если заказы создаются в разных экземплярах сервиса. Так что, возможно, внутри БД магазина скрыты другие кода - GUID или UUID.

GUID - Globally Unique Identifier, статистически уникальный 128-битный идентификатор. GUID выглядит так: b118c6e2-e0a5-4e83-81d3-8320a24eb8bf.

UUID - это аналогичный код, только формирующийся по другим правилам.

Самостоятельно guid’ы можно генерировать, например, здесь. Большинство программ для разработки включают в себя функции для генерации GUID/UUID.

GUID/UUID делают несколько сложнее взаимодействие человека с системой, а также имеют бОльший объем и могут несколько замедлить работу с БД.

Тем не менее, сейчас такие кода очень часто используют в качестве идентификаторов. И вот почему:

1) Уникальность - вероятность, что вы сгенерируете guid, который уже является где-то идентификатором настолько мала, что ей пренебрегают.
2) Сложно подобрать - простым перебором явно не получится.
3) Используется стандартный алгоритм генерации, не требующий закладывания специальной логики в приложение.
4) Не надо следить за уникальностью идентификаторов и актуальностью логики в разных частях системы.

В итоге, можно сделать вывод, что клиентам лучше показывать код, который никак нельзя “расшифровать”, чтобы получить информацию о заказе. А для внутренних процессов и разработки удобно использовать GUID или UUID.

Про техническую сторону сравнения GUID и автоинкремента можно почитать здесь.

Системный сервант

05 Aug, 17:55


#breakfront_tooltips

Что почитать/посмотреть про интеграции c REST-like API

В порядке возрастания сложности:

- Наталья Косинова. Мастер-класс: Интеграция информационных систем (вебинар)
- Мой вебинар про введение в интеграции
- Андрей Бураков. REST, что же ты такое? (вебинар или статья)
- Brian Cooksey, An Introduction to APIs (короткий бесплатный курс на английском)
- А. Лоре, Проектирование веб-API (книга)
- Бесплатный курс по документированию API
- Спецификация OpenAPI
- Сергей Константинов, API (короткая бесплатная книга)
- Крис Ричардсон: Микросервисы. Паттерны разработки и рефакторинга (книга)
- Хоп, Вульф: Шаблоны интеграции корпоративных приложений (книга)

Системный сервант

19 Apr, 15:12


#breakfront_tooltips

Выложу и тут свою памятку для погружения в новый проект.

Системный сервант

04 Apr, 18:22


#breakfront_analysis_fails
Продолжаю рубрику с ошибками анализа.

ПАГИНАЦИЯ

Пагинация - это выдача данных по частям, разбитыми на страницы или блоки. Например, товары интернет-магазина можно выдавать, сортируя по дате создания, разными способами:
-с 1го по 50й,
- 15 товаров, следующих за товаром с артикулом 1111-111,
- товары страницы 4 при размещении 100 записей на странице,
- и т. д.

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

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

Но вдруг кто-то захотел показывать на главной странице общий каталог товаров. И так как вы уже умеете выгружать список товаров - просто сделали запрос без фильтра. И система пытается выгрузить сразу весь миллион товаров. В результате что-то сломается. Может сломаться вообще все. То есть ваш интернет-магазин может перестать работать у всех пользователей, так как все ресурсы будут уходить на попытку выгрузить все товары.

Поэтому нельзя давать возможность посмотреть сразу ВСЕ. Даже если сейчас в вашем интернет-магазине 500 товаров - через 3 года их может стать 500 тысяч.

И даже если сейчас вы не хотите или не можете делать пагинацию, надо хотя бы сделать ограничение. Например, чтобы можно было получить только первые 1000 записей. Также необходимо делать ограничение, если хотите дать возможность потребителю выбирать количество товаров на одной странице. Например, сделать максимум 100 - тогда пользователь может посмотреть по 10, 15, 50, 100 записей на странице, но не по 1000.

Пагинация делается при разработке и ее необходимо описывать в требованиях. https://twirl.github.io/The-API-Book/index.ru.html (глава 11 п. 16), тут и тут есть про виды пагинации и какие с ней могут возникнуть трудности.

Системный сервант

17 Mar, 18:40


Провела тут для группы Systems.Education вебинар про основы интеграции. Мне лично было интересно😄.
https://www.youtube.com/watch?v=MfpFK17huBE