Кто работает с микросервисами - есть вопросы
Решил вот тоже попробовать, но вопросов больше чем ответов. В принципе интересует ASP.NET Core 3.1 C#, но общие соображения тоже не помешают.
Фронтенд пока не трогаем пусть останется монолитом, хотя хотелось бы всё закинуть в один сервис. Для блазора решение есть во всяком случае.
Первое - это данные.
Сделал я базу, создал объекты, сделал рестфул апи - микросервис с постманом работает.
Теперь надо его вызвать. Сделал вызовы допустим, но ведь данные должны быть теже самые. То бишь или копия или ссылка.
А как же независимость? Если сервис изменил данные то тоже менять надо на фронтенде.
А базы как разные делать? Пользователь то мне нужен везде один и тот же, и подобных общих объектов море.
Пока остановлюсь...
Если нет, лучше оставить монолит
проблема не в этом. Что когда использовать не сильно интересует.
Задача разобраться с микросервисами и сделать демо приложение.
Микросервисы это всё же о бекенде
ну может название другое, но в идеале хотелось бы иметь "лего блоки" и для блазора + НЕТ 5 такое уже есть.
https://devblogs.microsoft.com/premier-developer/microfron...
Можно мешать Разор с Ангуляром и прочим. По ссылке только идея.
Задача разобраться с микросервисами и сделать демо приложение.
Так это уже давно сделано: Первая попавшаяся ссылка на Гитхабе.
Первая попавшаяся ссылка на Гитхабе.
Для начала нужно сделать самому чтобы понять. Не нашел пока ни одного подходящего проекта
Что в ссылке не подходит:
10 microservices showcasing Kubernetes, Istio, gRPC and OpenCensus.
и
Нужно ASP.NET Core попроще и без зайцев желательно. Это все следующий этап.
Тут бы получить данные с Рестапи от доскер контейнера
Данные и вычисления нужно разделять, в этом суть.
Меня немного другое интересует. Данные на сервисе и фронтенде должны то быть одинаковыми. А как же "независимые сервисы"?
AKS в Azure я поднял за 10 минут.
Вообще то хотел дома в докере поиграться, а то за базу с приложением 5-ку драли ежемесячно. Сейчас поотключал всё, хотел глянуть выйдет ли на 0.
А Fabric Azure - это другое? Тоже вроде для микросервисов.
Данные на сервисе и фронтенде должны то быть одинаковыми. А как же "независимые сервисы"?
Какие данные? Что такое данные в этом контексте? Фронт делает запрос по определенному адресу. Определенному. Состоящему из хоста, порта и ендпойнта(ресурса). Нттп запрос . Получает нттп ответ. Что значит "независимый"? Бэкенд отвечает на любой запрос. Фронта, постмана, другого бэкэнда. Бэкенд занимается подготовкой данных к показу или изменению. Фронт запрашивает , бэк вытаскивает данные из одного или многих источников, подготавливает к отправке и предоставляет по запросу.
Пользователь то мне нужен везде один и тот же, и подобных общих объектов море.
Каждый сервис занимается чем то своим. Например сервис пользователей. То есть есть база данных пользователей и доступ к ней только через сервис пользователей. Если нужно что то другому сервису, он не имеет права лезть в чужую базу, а запрашивает данные через соответствующий сервис. Сервисы отдают данные по запросам не только фронту, но и другим сервисам.
Какие данные? Что такое данные в этом контексте?
У меня в есть в базе пользователь, сервис отдает мне например: имя, майл, роль. Для этого у меня есть POCO объект, создаваемый автоматом.
На фронтенде мне нужно получить тоже самое: имя, майл, роль. То бишь нужен идентичный POCO объект.
Теперь я в сервисе добавил телефон, значит нужна синхронизация с бекэндом и другими сервисами. Где же эта декларируемая независимость?
а запрашивает данные через соответствующий сервис
А как же дизайн базы? Удаляю я пользователя - значит автоматом со всех связанных таблиц должно удалится. Опять сервисам всё поручать и сообщения об удалении отслеживать? А если сервис слег и не получил сообщения?
Удаляю я пользователя - значит автоматом со всех связанных таблиц должно удалится.
Для этого есть нормализация данных, это вопрос дизайна БД, это не совсем про микросервисы.
Каждый пользователь и его атрибуты должен писаться один раз (в идеале, конечно).
А если сервис слег и не получил сообщения?
Для этого СУБД должна уметь транзакции
То есть вы атомарный объект описываете атрибутами из разных БД?
Почему атомарный?
Вот есть у меня пользователи на германке.
Теперь хочу сервис теннисные клубы сделать, что бы каждый пользователь мог туда записаться.
Для одной базы мы бы добавили таблицу клубов и затем еще одну клуб-пользователь. Как теперь правильно сделать две базы для сервиса?
А в итоге получается и фронтенд монолит и база можно сказать монолит.
------
Получается.
Ровно до тех пор, пока не сможешь разделить на изолированные части.
Какого тогда все просто помешаны на этих микросервисах?
-----
Как для меня - там, даже если пишут спагетти-код, кода будет меньше и взаимодействие с другими частями будет более расписанное.
Например сервис пользователей. То есть есть база данных пользователей и доступ к ней только через сервис пользователей. Если нужно что то другому сервису, он не имеет права лезть в чужую базу, а запрашивает данные через соответствующий сервис. Сервисы отдают данные по запросам не только фронту, но и другим сервисам
то есть скажем для сервиса загруженных пользователями котиков нужна отдельная БД?
а как там сохранять информацию об авторе картинки с котиком?
Где же эта декларируемая независимость?
Нигде и никогда. Проггеры используют какую нибудь систему типа sswagger или просто договариваются. Объект можно прислать в теле запроса или по частям как параметры запроса. Но принимающая сторона должна знать, что принимает. В принципе можно пропарсить ответ и вычленить все отдельные параметры по принципу ключ-значение. Без готового объекта. Но что потом делать с незнакомыми параметрами? Получатель должен знать , что он будет получать и быть готовым к получению. Ну и на этом базируются системы автоматической валидации полученного объекта - параметр xyz например не может быть короче 5 символов, иначе ошибка.
А тут все сложно. Вообще в бэкэнде есть слой управления данными. И именно он решает, как делать трансакции с многими источниками. Например откатить или не производить операцию, если один блок отказал. Или использовать очереди сообщений. Или асинхронно производить операции одну за другой. Но это плата за модульность.
Какого тогда все просто помешаны на этих микросервисах?
Во первых модно. Во вторых даже монолит можно написать модульно. Доступ к данным только через интерфейсы. Это позволяет выкинуть модуль полностью. Заткнуть интерфейсы и прога будет работать дальше. Когда нет сложных перекрестных ссылок и можно переписывать и выбрасывать модули не боясь поломать прогу.
Основная идея имхо - возможность беспроблемно заменить кусок проги не убив остальные части. Ибо только группа микросервисов образует прогу.
Во вторых даже монолит можно написать модульно
Именно это и смущает. В общем, плевать на помешательство. Делам модульно, а если приспичит можно и на микросервисы модули переделать.
Но вот копировать ли общие данные или передавать их по ссылке из одного источника? Скорее второе с версиями.
Вот тогда еще непонятка - сервисы можно размещать где угодно. Как же тогда с защитой, каждому сервису секурити токен еще добавлять?
Монолит можно написать модульно, но это все равно будет монолит. Большое нескалируемое нечто с бутылочными горлышками.
Данные по умолчанию копировать, но только те, что действительно нужны. Все как в жизни.
Если у вас поменялся почтовый адрес, то вы сообщаете об этом банку, врачу и прочим и они у себя меняют данные в базе, а не делают кажный раз
запрос в ратушу перед тем как послать вам по почте счет.
С защитой так же. Получаешь у специального сервиса (ратуша) токен (аусвайс) и таскаешь с собой пока он валидный (10 лет). Стал невалидный - обновляешь :-)
А каждый сервис как-нибудь сам решает что с этим токеном можно, а что нельзя.
Как же тогда с защитой, каждому сервису секурити токен еще добавлять
Есть Аутентификацион-сервер. Он управляет безопасностью. Первый запрос на любой сервис идёт без токена, поэтому перенаправляется на этот сервер, который даёт возможность аутентифицироваться. По результатам процедуры запрос получает токен и перенаправляется обратно. И обрабатывается. Выглядит для юзера это прозрачно - что бы он на бэке не запросил, неважно через клиент или другим хитрым способом, любой сервис выбросит его на регистрацию и потом любой примет с токеном.
Монолит можно написать модульно, но это все равно будет монолит
Ну есть у меня допустим 3 интерфейса, имплементация для которых лежит в 3 разных Длл-ках - тип модульный монолит
Теперь эти 3 интерфейса "имплементируются" через сервисы - тип микросервисы
Ну и где будет разница?
Данные по умолчанию копировать
То бишь, у меня сотня автогенерированных "таблиц" и все мне их ручками копировать/перебивать?
А потом все синхронизировать? Кто интересно будет мне план синхронизации писать, чтобы всё точно было?
пока он валидный (10 лет).
Токен валидный 10 лет - это где
Надо стащить и попользовать
Большое нескалируемое нечто с бутылочными горлышками.
На самом деле нет. Монолит это много сервисов вместе. Масштабировать можно так же, как и каждый сервис в отдельности - если ресурсы не имеют состояния. Просто это будет один проект. Возможно гигантский. Я знаю проект, где нужно загрузить пару тгигобайт всякой хрени, что бы работать над одним модулем.
С токенами как правило тоже все единообразно - общая политика безопасности. Даже если много отдельных сервисов.
В общем, каждому сервису еще и "логин часть".
Я не сильно понял, что это значит, но это стандартная защита вебресурса. Неважно, защит он в монолите или в отдельном сервисе. Каждый ендпойнт защищён. Каждый, кроме специально открытых. Каждый отвечает на запрос с правильным токеном или посылает за токеном. Если это защита на базе токенов.
То бишь, у меня сотня автогенерированных "таблиц" и все мне их ручками копировать/перебивать?
Я не понял проблему. У каждого сервиса свои таблицы. Каждый сервис хранит и управляет только своими данными. Сервис "пользователь-штаммдаты" имеет таблицу "адреса" и ее и данных по адресам нет больше нигде.
Каждый ендпойнт защищён.
По типу ентого?
[Authorize]
public class HomeController : Controller
Я имел в виду немного другое.
Если сервис обращается к сервису то там тоже ведь нужна защита. А токен я обычно получаю после отсылки "имя+пароль", получается каждый сервис должен иметь свою пару, которую тоже в принципе можно стыбрить.
У каждого сервиса свои таблицы
Ну так эти данные как-то должны попасть фронтэнду, пусть они и замапенны с дополнительными атрибутами для валидирования, но все равно это "копия" оригинальных таблиц сервиса. И эту копию должны синхронизировать разработчики сервиса, а не те кто пишет UI.
Вот еще, более практическая задачка.
Слепил я простенький сервис на Web API. Как делаю отладку в студии на докере - все работает.
Как запускаю прямо в докере - не откликается страница.
Это проект тип - строка 1
А если делаю проект тип - строка 2, то страница показывается как из под студии в докере, так и прямо с докера.
Что еще нужно добавить первому проекту чтобы в докере также работал? НЕТ Коре 3.1
....
Похоже, что то обновилось/испортилось второй тип проекта тоже перестал работать - "The connection to the server was reset while the page was loading. Это под виндой
...
Но если делаю Publish на Docker Hub, то получается как и было описано. Я раньше именно так проверял.
...
Получилось - как обычно, самдурак Или путь к сервису неправильно указывал или забывал строку соединения к базе указывать. Ошибок то особых никаких не показывает.
Под виндой для отладки так и не работает, ну и фиг с ним.
Я ж явист и работаю со спрингом. Перед тем, как нттп-запрос попадает ко мне, как к прикладному программисту для обработки он проходит ряд фильтров. Где и настраивается защита. Токен извлекается из заголовка запроса и проверяется. По результатам проверки запрос или пропускается дальше или формируется отказ в запросе с соответствующим кодом.
Если с сервисом общается другой сервис, то там свои способы защиты. Кроме того сервис, который запрашивает, может запросить сначала токен у сервера авторизации
Если у двух сервисов общие 100 таблиц, то, наверное, с ахритектурой что-то не так.
Синхронизировать обычно специально не надо. При появлении нового объекта он кидается в очередь сообщений на которую подписаны все сервисы.
При этом каждый сервис берет из нее себе то, что ему нужно.
Недостатков у такого подхода тоже немало и такая архитектура подходит отнюдь не для всех задач, но кострукция получатеся гибче, ее легче поддерживать и в нее легче вноситъ изменения.
Монолит может состоять хоть из 100 длл. Он выполняется в одном процессе/на одной машине, у него одна большая бд, а вечно увеличивать память и количество ядер мы не можем.
Тот кто удаляет пользователя посылает об этом сообщение. Все остальные на это реагируют. Кто-то может и удалит из базы, кто-то просто пометит пользователя как невалидного, кто-то из-за закона о защите личных данные поменяет ему имя на Джон Доу, а кто-то просто проигнорирует (Сервису который собирает статистику обычно без разницы валидный юзер или нет).
В монолите удалить пользоватея тоже не просто. На него обычно ссылаются тысячи сделаных им за годы работы изменений.
Если сервис недоступен, то, например, сообщение для него останется в очереди до тех пор пока он не поднимется. Или система через некий промежуток времени не получив подтверждения начнет все откатывать назад. Почитайте, например про SAGA pattern.
И да, распределенные трансакции подерживать тяжело и накладно, но как показывает
практика это нужно очень и очень редко. Обычно достаточно отложенной консистенции.
В монолите удалить пользоватея тоже не просто
Обычно это дело базы.
SAGA pattern
https://habr.com/ru/post/427705/
Интересно, спасибо
Если у двух сервисов общие 100 таблиц
Нет имелось в виду несколько другое.
Сервис берет данные их базы и отдает их по какому АПИ. Дальше данные переводятся в "UI формат" (типа те же данные только с атрибутами).
Вот как это все синхронизировать?
При этом каждый сервис берет из нее себе то, что ему нужно.
Это вроде еще сложнее, нужно знать ИД объекта и какие данные он имеет.
Он выполняется в одном процессе/на одной машине
Не обязательно. Можно иметь несколько отдельных машин, работающих через балансировщик загрузки. Точно так же как и отдельные сервисы. Да. Память загружается всем приложением. Но если имеется 20 сервисов, то не значит, что будет 20 отдельных машин под них. Если запустить несколько сервисов на одной машине, то придется делить память между этими процессами. Это может быть слижнее. Я не знаю, как запускаются веб-приложения с-шар, но обычно веб-приложения запускаются из под веб-сервера и распределением потоков и памяти все равно занимается этот самый веб-сервер(аппликатион-сервеr)
Обычно я запрашиваю токен авторизации по имени пользователя и паролю, а сервис как?
По разному. Например создается специальный пользователь, первый сервис сначала запрашивает от имени этого пользователя токен авторизации у сервера авторизации, а потом с этим токеном лазит где надо. Этого пользователя можно ограничить специально правами. Кроме того можно ставить защиту на заптос только с определенного домена только приложениями с определенным именем и с соответствующим кодовым словом.
Сервис берет данные их базы и отдает их по какому АПИ. Дальше данные переводятся в "УИ формат" (типа те же данные только с атрибутами).Вот как это все синхронизировать?
С чем синхронизировать? Сервис - это нечто, что по запросу предоставляет какой то ресурс в пользование. Итак веб-сервис(апи), который отвечает на веб-запрос, передает запрос внутреннему сервису (чертов термин 'сервис', который используется везде в разных контекстах), который в свою очередь вытаскивает ентети-обьект(как правило из базы данных) и передает апи. Апи серелизует полученные данные согласно транспортному протоколу и отправляет как хттп-ответ. Все. Что спросили, то и ответили. Ничего синхронизовать не надо.
>Но если имеется 20 сервисов, то не значит, что будет 20 отдельных машин под них
Можно и на одной. А можно и на разных. Две машины с 64гб памяти могут оказаться дешевле одной с 128гб.
А можно сегодя на одной, а на выходных, когда нагрузка больше, на трех. С монолитом такой трюк не пройдет.
И это мы еще не начали обсуждать как обновлять наше монолиное приложение когда клиент требует 7х24 доступности основного функционала.
То бишь делаем дополнительную защиту и называем ее SS7В принципе да. Есть стандартные решения. Но если мы выходим за рамки
контрекста приложение и еще используем каналы связи, то внезапно встает
задача защиты доступа к отдельным частям проги. Но это нормально. Кроме
того, что веб-сервисы между собой взаимодействуют, может потребоваться
доступ сторонним приложениям. Например приложения, которое занимается
изготовлением берихтов (например квик селс) потребует данные по
РЕСТ-протоколлу.
Ничего синхронизовать не надо
вытаскивает ентети-обьект(как правило из базы данных) и передает апи --> Апи сериализует полученные данные --> вытаскиваем объект "для UI"
Добавили в таблицу поле адрес, обновили апи, хотим показать адрес в UI. Как без "синхронизации"?
Ааа, имеется в виду синхронизировать транспортные объекты на фронте и на бэке. Да. Синхронизировать надо. Для этого есть или стандартные средства фреймворков(например валидация) или всегда договариваться. Но да. Надо. Ещё раз. Можно написать без синхронизации. Например просто приходят пары проверти ключ-значение. И другая сторона роется в этих ключах, ища что то свое или просто сохраняя все без разбора. Но обычно синхронизировать надо.
и какой будет наиболее удобный способ?
В небольшом проекте руками. Но я не особенно большой специалист в этой области, я работаю в бэке и мы не пользуемся тулами. Пока. Я видел проекты с подключенным сваггеро, есть такой тул, он при построении проверяет, но для управления такими вещами нужен выделенный архитект, у нас таких нет. Поэтому при изменении бэк и фронт-проггеры просто догавариваются. Или это вообще один человек.
Добавили в таблицу поле адрес, обновили апи, хотим показать адрес в UI. Как без "синхронизации"?
Тебепонятие "контракта" или "интерфейса" о чем-нибудь говорит?
Синхронизация - это вообще о другом. Если бы ты пользовался бы принятой в ИТ терминологией, то странных вопрособ было бы гораздо меньше. Синхронизация (информатика)
Ну может тогда расскажете какая ORM генерит интерфейсы.
Без понятия. Подозреваю, что никакая, т.к. эта задача не имеет смысла.
Ну расскажите тогда как называется то что я хочу принятой в ИТ терминологией
Это называется "контрактом" или "интерфейсом".
Подозреваю, что никакая, т.к. эта задача не имеет смысла.
Ну так о чём и говорю, с одной стороны у меня классы для базы, с другой классы для АПИ, с третьей для UI. и все их нужно ...
Это называется "контрактом"
Как то еще ни разу не слышал - а ну ка сделай мне одинаковые контракты данных.
Кроме как с WCF ничего больше и не попалось. И очень сомневаюсь что бы кто то меня понял с таким выражопиваем.
Ну так о чём и говорю, с одной стороны у меня классы для базы, с другой классы для АПИ, с третьей для UI. и все их нужно ...
И все их нужно... ничего :)
Есть классическая слоеная архитектура, в которой слои связаны между собой некими интерфейсами. Если в твоем случае это:
1) UI level
2) Application level
3) DAL
то UI level вообще ничего не должен знать о DAL. Ни о структуре таблиц, ни даже о существовании DAL.
Ты пытаешься сделать какую-то неподдерживаемую хренотень.
Как то еще ни разу не слышал - а ну ка сделай мне одинаковые контракты данных.
Что значит одинаковые контракты данных? И зачем это вообще надо?
Кроме как с WCF ничего больше и не попалось. И очень сомневаюсь что бы кто то меня понял с таким выражопиваем.
Добавили в таблицу поле адрес, обновили апи, хотим показать адрес в UI. Как без "синхронизации"?
Никак. Но Программист прав. Транспортные классы ДТО не обязаны соответствовать ни базым данных ни Ентити-классам, связанным с базами данных или другими иточниками данных. Мы храним одни данные в одном виде, передаем возможно в другоm. Передаем то, что или нужно клиенту или мы считаем, что ТАК нужно клиенту
Алекс, вы путаете теплое с мягким.
Ну добавили в апи вашего микросервиса еще одно поле/перешли на новую версию интерфейса.
Что вы собрались тут синхронизировать? Классы DTO? Так уй и бэкэнд на разных языках написаны.
Уй - это такой же консьюмер вашего апи, как и все остальные. Естественно разработчик уя добавит это поле в свой DTO класс, или что у него там заместо оного.
Возможно он сгенерирует новые DTO классы из описания автоматически. А может и ручками добавит.
Вы думаете о софте как об окошках с кнопочками и текстовыми полями, а надо как о потоках данных.
Знаете как в Германии информатику называют? EDV - электронная обработка данных :-)
Есть классическая слоеная архитектура, в которой слои связаны между собой некими интерфейсами.
Не для веба. На вебе клиент и сервер это 2 независимых приложения. Общение через ХТТП-запрос, фактически через текстовой файл. Ни одна из сторон не имеет ни малейшего представления о технологиях другой. Нет ни интерфейсов ни слоев.
Фактически сервер, принимая запрос и (если нужно) десериализуя обьект, инстанцирует готовый пустой обьект, такого класса, который он считает нужным. И начинает парсить запрос, пытаясь инициализировать и заполнить этот обьект. Разумеется в запросе никаких обьектов нет. Есть голый текст. И разумеется, если другая сторона внезапно прислала какую то хрень, то может произойти разное. Может быть сгенерирована ощибка на базе валидации готового обьекта. А может получится обьект с неицилизированными пропертями.
Что вы собрались тут синхронизировать? Классы DTO?
Да. Если сервер шлет на одно поле больше, то клиент начнет использовать это поле только после "синхронизации". Если сервер удалил поле из обьекта, то у клиента без "синхронизации" это поле останется просто пустым. С соответствующими последствиямi
Не для веба.
Возможно веб - это другой мир, но я почему-то сомневаюсь :D
На вебе клиент и сервер это 2 независимых приложения.
Ну так такое и не в вебе сплошь и рядом встречается. То, что это 2 независимых приложения не обязатетельно должно отменять слои ;)
Общение через ХТТП-запрос, фактически через текстовой файл. Ни одна из сторон не имеет ни малейшего представления о технологиях другой. Нет ни интерфейсов ни слоев.
А ты посмотри на это несколько иначе. Чем ХТТП запрос отличается от вызова какой-либо функции? Чем содержимое файла отличается от ДТО? Набор ХТТП запросов, а также входные и выходные данные - это и есть контракт/интерфейс между фронт- и бэкэндом.
Собственно говоря, браузер всего лишь занимается рендером UI. Какая разница, по какой технологии рендерить контролы web, WinForms, Qt, WPF итд?
То, что это 2 независимых приложения не обязатетельно должно отменять слои
Слои есть внутри самих приложений. Интерфейсы позволяют контрактами договорится внутри приложения о имплементации классов и принудить вторую сторону выполнить принятый договор. Но не между приложениями. Приложение получило какую то текстовую хрень и пытается по собственному разумению ее десериализировать. И ничего не знает о том, что другая сторона уже весь класс перестроила.
Чем ХТТП запрос отличается от вызова какой-либо функции?
Отсутствием синтаксической проверки во время программирования.
Набор ХТТП запросов, а также входные и выходные данные - это и есть контракт/интерфейс между фронт- и бэкэндом.
Интерфейс принуждает программиста править классы, имплементирующие измененные интерфейсы. А вот в вебе пришла какая то хрень и хорошо, если сервер выкинет ошибку о невозможности влепить текстовые данные в числовое поле.Фронденщики ДТО изменили втихаря. Упс. А может просто игнорировать отсутствующее поле, если на нем валидатия не висит.
Собственно говоря, браузер всего лишь занимается рендером UI. Какая разница, по какой технологии рендерить контролы web, WinForms, Qt, WPF итд?
Немного не так. До браузера все эти технологии не доходят. Только ява-скрипт и хтмл с цсс. Но дело не в этом. Дело в том, что обмен данными между бэком и фронтом осуществляется по устному договору, который не проверяется синтаксически. Типа фронтэндщик коворит "зуб даю" и этому приходится верить
Интерфейсы позволяют контрактами договорится внутри приложения о имплементации классов и принудить вторую сторону выполнить принятый договор. Но не между приложениями.
Есть несколько способов для Inter Process Communication. Собственно говоря, возьми любую коммуникацию по TCP - там все тоже самое. О контракте, которым должны соответствовать данные договариваются клиент и сервер. Иписание какого-либо протокола в PDF - это тоже контракт. Ну и в общем случае интерфейс не может принудить выполнять какой-либо договор. Интерфейс - это декларация, т.е. объявление всем контагентам, что какой-то объект соответствует какому-либо контракту, но ты не может а) заставить контрагента подчиняться этому контракту и б) нельзя гарантировать, что объект на 100% делает то, что декларируется.
Приложение получило какую то текстовую хрень и пытается по собственному разумению ее десериализировать. И ничего не знает о том, что другая сторона уже весь класс перестроила.
Если приложение ожидает данные по одному контракту, а получает другой, то оно просто сообщает об ошибке и все.
Просто разработчики должны договориться и использовать один контракт.
Отсутствием синтаксической проверки во время программирования.
Ну вот WCF дает такую проверку. И что? Это теперь не HTTP? :D Договоренности же не обязательно должны проверяться на стадии компилирования.
Интерфейс принуждает программиста править классы, имплементирующие измененные интерфейсы.
Интерфест - это просто форма документации, соответствие которой можно проверить на этапе компилорования.
А вот в вебе пришла какая то хрень и хорошо, если сервер выкинет ошибку о невозможности влепить текстовые данные в числовое поле.Фронденщики ДТО изменили втихаря. Упс. А может просто игнорировать отсутствующее поле, если на нем валидатия не висит.
Ну так в таком случае пронтэдщики встречаются в переговорке с бэкэндщиками и говорят "мы работаем по контрату от 1.1.2000", а другие им от вечают "а мы по контракту от 1.2.2020" и на этом разговор можно завершить и перейти к обсуждению того, какой контракт более правильный и, может быть, сделать новый контракт, который устроит всех.
Дело в том, что обмен данными между бэком и фронтом осуществляется по устному договору, который не проверяется синтаксически. Типа фронтэндщик коворит "зуб даю" и этому приходится верить
Ну это уже вопрос реализации :) Никто же не мешает запикнуть версию контракта в DTO ;)
то UI level вообще ничего не должен знать о DAL
А кто говорил что он должен знать?
Вот расскажите, какие будут шаги если мне нужно грубо говоря "показать" базу в приложении.
1. Генерируем классы данных из таблиц базы
2.
...
И теперь тоже самое, но через микросервис
И зачем это вообще надо?
Уже спрашивал - Ну расскажите тогда как называется то что я хочу принятой в ИТ терминологией
объект класса это участок памяти, занятый по определенным правилам. То, что передает нттп запрос это серилизация. Это не объект. Объект в определенной среде надо заново инстанцировать и инициализировать из информации, которую передает нттп запрос. А сам нттп запрос это просто текст. Этот текст можно после получения интерпретировать. И файлов там быть по определению не может. Потому что файл это юнит файловой системы. По получении запроса и на основании инфы в запросе он может быть создан на конкретном компе в конкретной файловой системе.
Ну добавили в апи вашего микросервиса еще одно поле/перешли на новую версию интерфейса.
Для начала, мне нужно об этом знать, а затем все равно как то изменить. Иначе говоря, UI зависит от API.
Возможно он сгенерирует новые DTO классы...
Ну так именно эти возможности и хочется обсудить
Вариант 1 - ручками, как бы уже давно известен.
>Интерфейс принуждает программиста править классы
Один раз руки оторвут за изменение втихаря пущеной в релиз версии и принуждать больше на надо :-)
А если серьезно, то умные дяди много чего придумали. Тесты там разные автоматические по ночам, например.
Все, конечно, не отловишь, но и раньше программист мог просто сделать class cast. И хорошо если это ява и все грохнется с ClassCastException.
В каком-нибудь си/паскале данные вполне могли бы из памяти без ошибок прочитаться. Вот тогда действительно веселуха.
а если бы мы вместо GET слали бы, например, 1 в псевдохедере, что-то кардинально изменилось бы? какая разница текст это или не текст?
Зависит от того, что ны обсуждаем. Я хотел сделать упор на то, что при передаче с запросом мы не посылаем готовые обьекты, например файлы файловой системы или обьекты классов конкретного языка. Мы посылаем строительный план. В текстовом виде. Принимающая сторона ЗНАЕТ, что должно прийти и готова к этому. Принимающая сторона например ожидает обьект определенного класса. Поэтому она сначала создает в памяти компa реально обьект, потом открывает строительный план и пытается в нем вычитать все, что к этому обьекту относится. Для его инициализации. И если план не соответствует реальному обьекту, то может произойти разное. Например обьект останется полупустым без сообщений о ошибках. Или переданная информация просто потеряертся, потому что у имеющегося класса просто нет соответствующих полей и вообще сохранение этих полей не предусмотрено.
Вот расскажите, какие будут шаги если мне нужно грубо говоря "показать" базу в приложении.
Ты же понимаешь, что это глупая задача? :)
Вот пример базы:
addresses: +---------------+-------------+ | name | type | +---------------+-------------+ | id | int | | country | varchar(255)| | zip | int | | city | varchar(255)| | street | varchar(255)| | house_nr | int | +---------------+-------------+ +-----+---------------+----------+---------------+---------------+----------+ | id | country | zip | city | street | house_nr | +-----+---------------+----------+---------------+---------------+----------+ | 1 | Germany | 55555 | Musterburg | Berliner Str. | 15 | | 2 | USA | 123456 | Example City | West ave. | 215 | | 3 | Russia | 965438 | Primersk | Lenina | 1 | +-----+---------------+----------+---------------+---------------+----------+ users: +---------------+-------------+ | name | type | +---------------+-------------+ | id | int | | address_id | int | | name | int | | last_name | varchar(255)| | birthday | datetime | +---------------+-------------+ +------+---------------+---------+-----------+------------+ | id | address_id | name | last_name | birthday | +------+---------------+---------+-----------+------------+ | 1 | 1 | Hans | Müller | 01.01.1950 | | 2 | 1 | Joachim | Schwarz | 02.01.1952 | | 3 | 2 | James | Tall | 01.03.1967 | | 4 | 2 | Nick | Smile | 02.04.1984 | | 5 | 3 | Mikhail | Petrov | 01.01.1999 | | 6 | 3 | Natasha | Ivanova | 02.01.1993 | +------+---------------+---------+-----------+------------+
Очевидно же, что показывать эту БД не имеет никакого смысла, а объекты БД и DTO, которые будут передаваться в UI, отличаются.
Так что где-то там будет шаг "Определить контракт взаимодействия бэк энда и фронт энда".
И теперь тоже самое, но через микросервис
Да хоть через что. Какая разница?
Ну расскажите тогда как называется то что я хочу принятой в ИТ терминологией
Ты хочешь нечто, что будет автоматически генерировать код на основе заданного контракта.
а если больше?
-----
На случай "а если больше" Я как раз и пытаюсь слепить сервис (ре)генерации.
Мягко говоря при каждом билде надо синхронизироваться.
Вопрос только в том сколько объектов надо синхронизировать.
Да, вопросик - у тебя ВЦФ-клиент&сервис в отдельных либах или в теле основного проекта?
Если вынесены - там можно автоматом синхронить.
Очевидно же, что показывать эту БД не имеет никакого смысла
Не следует понимать всё буквально, специально кавычки добавил
Можно взять для примера только таблицу адресов.
Определить контракт взаимодействия бэк энда и фронт энда
И как его интересно определять и чем?
Да хоть через что. Какая разница?
Ну зафигачь интерфейс в микросервис и UI - тут же получаем связь, которой быть не должно
что будет автоматически генерировать код на основе заданного контракта.
Подобные фразы я пропускаю не читая, слишком заумно
Не уверен что именно это мне нужно, хотя поменьше ручной работы.
А контракт откуда возъмется?
Можно взять для примера только таблицу адресов.
Нельзя, т.к. ее тоже можно разбить на несколько таблиц :) Мне просто лень :D
Суть в том, что сохраненные в ДБ объекты в 99,99% случаев не соответствуют отображаемым объектрам. Поэтому в общем случае такой мэппинг не возможен.
И как его интересно определять и чем?
Ну это кому как удобно :) У нас контракт с одной подсистемой определен текстом в wiki, а с другой подсистемой - xsd. Для REST можно воспользоваться привычными интерфейсами.
Ну зафигачь интерфейс в микросервис и UI - тут же получаем связь, которой быть не должно
Ничего дополнительного мы не получаем, т.к. любой сервис по определению имеет свой интервейс. Т.е. не зная как и с какими данными обращаться к сервису, а
также какие данные от него ожидать, ты никогда ничего не получишь ни от одного сервиса ;)
А контракт откуда возъмется?
Контракт ты сам создаешь. А как ты из него потом будешь генерировать JS-код - твое дело.
Мой шеф уже много лет мечтает о такой хренатени :) Хочет в автоматическом режиме парчить страницу в wiki и xsd и генерировать наши интерфейсы (в смысле C# код) :)
Т.е. не зная как и с какими данными обращаться к сервису, а также какие данные от него ожидать, ты никогда ничего не получишь ни от одного сервиса ;)
------
Глупости.
Все, что тебе надо знать об сервисе - это как получить с него ВСДЛ.
А это делается достаточно стандартизовано.
Если описывать интерфейсами - ИАнкновн - всегда, как в АктивХ, определен.
в автоматическом режиме парчить страницу в wiki и xsd и генерировать
-----
Несколько лет?
С ХСД там работы на несколько часов - вгет для довнлоада, хсд.ехе для генерации. Пакуется все в таргетс/проп и втыкается бефоре в проект...
По Вики - хрен его знает что вы там рисуете... сведете к ХСД - все будет как выше описано.
С ХСД там работы на несколько часов - вгет для довнлоада, хсд.ехе для генерации. Пакуется все в таргетс/проп и втыкается бефоре в проект...
Ну шеф хочет не только сгенерировать код ;) Это было бы слишком просто. Он хочет отслеживать всю историю изменений и включить комментарии для каждой переменной ;)
По Вики - хрен его знает что вы там рисуете... сведете к ХСД - все будет как выше описано.
В вики описано сообщение, которое передается в виде JSON ну и как и в случае с XSD, ему нужна вся история изменений и комментарии.
А что мешает добавить?
Хммм... технология :D
https://stackoverflow.com/questions/41329955/how-to-get-ws...
Он хочет отслеживать всю историю изменений и включить комментарии для каждой переменной ;)
-----
А кто мешает? Ну добавите еще пару вызовов гита...
описано сообщение, которое передается
-----
Так ведь вопрос не столько - что, а больше - как.
Если вы там лепите кто во что горазд - его хрен распарсишь, если все формализовано - так без проблем.
И ХСД не мешает себя документировать - в ней все необходимое есть.
Но вот писать всю эту лабуду обычно лениво.
Нее, не мешает.
Мешает :) По ссылке объяснено почему ;)
В кратце - все дело в EndPoint'ах. Технология REST не предполагает никаких EndPoint'ов (это не значит, что их нельзя сделать), в то время как использование WSDL требует дополнительного EndPoint'а, который будет отдавать WSDL.
Твой босс - даже хочет. Правда почему-то хочет брать со стороннего источника и бороться за актуальность...
Там речь о формате данных. Со стороннего источника он хочет брать, т.к. другой отдел контролирует этот формат. Ну и там никаких WSDL'ов в принципе нет, т.к. данные шлются через ActiveMQ.
А кто мешает? Ну добавите еще пару вызовов гита...
Ну с одной командой получилось договориться и они положили свои XSD в гит. Я даже сделал скрипт, который проверяет было ли обновление и шлет е-мылы, если было :) Но шеф решил, что этого недостаточно и запущено это не было :D
И ХСД не мешает себя документировать - в ней все необходимое есть.
Но вот писать всю эту лабуду обычно лениво.
Воооот. Я шефу нуэны комментарии. При этом комментарии должны быть не в XSD, а в коде :) Какая проперти что именно означает и в связи с чем она появилась. Короче говоря, это очень странная история :D
При этом комментарии должны быть не в XSD, а в коде :)
------
Как Я его понимаю!!!
Причем - в деталях - ему хочется поменять генератор кода в хсд.ехе.
Мне - тоже. Вот только там мелкомягкий - что вижу то пою - код и втиснуться в него никак...
И, кстати, Я искал у кого есть вариант, где можно воткнуть свой генератор - не нашел.
Т.е. компиляторы схем - есть. А вот написанных так чтобы сменить генератор - нету...
Сервис берет данные их базы и отдает их по какому АПИ. Дальше данные переводятся в "UI формат" (типа те же данные только с атрибутами). Вот как это все синхронизировать?
никак, есть одна версия API, накатываешь изменения и сообщаешь - новый API доступен по урлу 2.0, если там не критично, то какое то время можно две версии API поддерживать, чтобы старые клиенты не отвалились в одночасье, а перешли постепенно на новый API
А когда изменений сотни?
Представь, что вы пишете с коллегой одну прогу. Ты первый переименовал все классы и изменил имена всех полей. И первый загнал свой код в репозиторий. И у коллеги конфликты. Сотни. Тысячи. Что делать? На самом деле так случается редко. Сотни изменений это новая прога.
А когда изменений сотни?
делать сотни изменений во фронтэнде... чудес не бывает
ну можно конечно наворотить кучу абстракций, параметров, сложной логики, тогда будет некоторый запас изменений которые заработают на лету