All streams
Search
Write a publication
Pull to refresh
14
0
Валерий Четков @vchetkov

Backend разработчик

Send message

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

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

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

В общем, вашу идею я понял, еще раз спасибо за дискуссию. Этот разговор подкинул мне парочку интересных мыслей)

А если поставщиков 2, 3 ... 5? Это ведь все сторонние системы, с разными API. Имхо, идти по этому пути и под каждую систему писать новый proxy API - замахаешься.

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

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

2. Ускорение процесса тестирования.
Если каждый раз, когда нам нужно будет проверить какой-то редкий кейс, для этого нужно будет писать целый сервис, обеспечивающий подмену данных, реализующий даже небольшую часть API поставщика, то ИМХО, проще уже обойтись костылями о которых я писал в статье, это будет гораздо проще и быстрее.

3. Возможность интерактивной модификации данных.
На самом деле, я рассматривал варианты мока API, перед тем как делать этот инструмент. Поверхностно ковырял такие штуки как mock-servers в Postman и Hoverfly, но того чего хотел, я там не нашел.

Чтоб воспроизвести какой-то кейс - нужно сначала подменить подключения к API, сделать запрос, записать дамп ответа, потом отредактировать его нужным образом и настроить mock метод API. Много рутины, не удобно, не гибко, и сложность настройки возрастает кратно росту сложности самого воспроизводимого кейса.

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

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

С http-client-mitmproxy этих проблем не возникает.

А можешь чуть детальнее раскрыть свою идею?

Сейчас попробую описать более конкретный пример.

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

Цена у поставщика может измениться, это случай достаточно редкий, но возможный. Поэтому в момент бронирования, мы должны актуализировать данные о билете, чтоб не продать его себе в минус. Если цена в момент актуализации увеличилась, система должна уведомить об этом клиента, а процесс бронирования прерывается, возможно новая цена его не устроит. Если же цена уменьшилась, то система может заработать доп. прибыль, т.к. клиенту можно и не сообщать об изменении в меньшую сторону, а разницу забрать себе.

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

Мы написали логику, которая реализует все описанные выше требования. Задача уходит на тестирование в QA-отдел. Но т.к. подобная ситуация происходит крайне редко, задача зависает в тестировании на долго. Рано или поздно к разрабочику приходит QA-специалист и говорит: "Хоть убей, не могу воспроизвести случай, когда изменятся условия.. Помоги, а?".

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

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

Т.е. для того, что бы найти багу в уровне приложения

Не обязательно найти багу, скорее для воспроизведения ситуаций, которые могут приводить к этой баге (или чему-то еще), и для упрощения их тестирования

Мы видимо говорим о разных проблемах.

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

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

Так речь и не о проде)

Логи и сквозной requestId должны давать возможность понимания что пошло не так.

Давать возможность понимания, и давать возможность повторения крайне редко возникающей ситуации - разные вещи


Смысл в предоставлении возможности интерактивной модификации запросов/ответов, ходящих не от клиента к серверу, а между сервером и другими системами, на тех окружениях, на которых разработчик сочтет это нужным (stage, dev, test - решает уже разработчик, а статья описывает возможности инструмента)

Спасибо! Ошибку подправил)

Оговорюсь, я имел ввиду не совсем Entities, Services, Repositories, а Model (в которой будут entities, value objects и т.д.), Services (слой логики приложения) и Infrastructure (вспомогательные механизмы: конкретные реализации всяких репозиториев, нотификаторов и т.д.)
А также, не имел в виду сваливать все подряд классы в эти 3 папки, естественно можно сделать в каждой из них структуру и каким-то образом группировать логически близкие друг к другу элементы.


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

Хотя нет, реализуем, но это будет выглядеть как костыль…
Разместить фасад где-то в нашем коде, но в конфиге, директорию в которой мы его разместили указать как второй корневой каталог компонента B.
Работать будет, но тоже добавляет нюансы в конфигурацию. Т.к. без этого костыля, мы вообще могли-бы для стороннего пакета В секцию в modules не описывать, а просто включить vendor_based_modules. А так нужно будет его отдельно описывать в modules + исключать в vendor_based_modules. Не то, чтоб это очень сложно, но как-то вроде не очень :)
К примеру B это какой-то вендор… (ну т.е. пакет стороннего разработчика, мы его не поддерживаем). В таком случае этот вариант не реализуем.
Парни, в добавок к тому, что уже сделано и описано выше, есть еще пара идей, которые я хотел-бы обсудить и услышать ваши мнения.

Вот одна из них:
Допустим есть компоненты A и B. В целом мы не против, чтоб А использовал В, но по ряду причин хотим ограничить эту связь, т.е. сделать её допустимой ТОЛЬКО для конкретной группы классов (на пример, чтоб зависимость не разрасталась очень сильно, мы реализуем в компоненте A что-то типа ACL (anti-corruption layer), только в миниатюре :) и для него разрешаем зависимость от В, остальные элементы компонента A должны взаимодействовать с B ТОЛЬКО через него, т.е. не на прямую.

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

Идея: доработать в конфиге компонента секции allowed_dependencies/forbidden_dependencies, чтоб помимо разрешенных/запрещенных компонентов, в них можно было перечислить классы или директории, в которых располагаются классы, которым можно/нельзя знать про задаваемый в конфиге сторонний компонент.

Что думаете по этому поводу?
Спасибо, если честно, не знаком с этими инструментами. Постараюсь посмотреть на досуге, возможно получится почерпнуть какие-то идеи)

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

Спасибо, поковыряю его, на сколько я помню, его вроде Phan использует для анализа
А если явно тип возврата не определён, а есть аннотации?

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

А если и их нет, сможет вывести тип?

Нет, так пока не умеет

Если Fio где-то внесён в приватные, но там используется этот метод без явного упоминания Fio, вычислить его система?

Такого тоже не умеет, возможно со временем
Да, спасибо за замечание, сейчас исправлю

Information

Rating
Does not participate
Location
Севастополь, Республика Крым, Россия
Date of birth
Registered
Activity